There is a problem with using the LEDs when the PCMCIA is disabled. When PCMCIACON == 0 then you cannot program the LEDs via the CPLD. This is true of a standalone program or from a program running under LOLO. Here is a working example showing the problem, there are four files:
demo.h#define BOOTABLE 1
#define USEPCMCIA 0
demo.lds.S#include "demo.h"
ENTRY(StartUp)
SECTIONS
{
#if BOOTABLE
. = 0x00000000;
#else
. = 0x000C0000;
#endif
.boot : { *(.boot) }
.text : { *(.text) }
.data : { *(.data) }
.rodata : { *(.rodata*)
. = ALIGN(4);}
_text = ADDR(.text);
_etext = ADDR(.rodata) + SIZEOF(.rodata);
. = ALIGN(4);
.bss : { *(.bss) }
_bss = ADDR(.bss);
_ebss = ADDR(.bss) + SIZEOF(.bss);
. = ALIGN(4);
}
demo.S#include "demo.h"
;
.global StartUp
;
#if BOOTABLE==1
.section .boot
.word StartUp
#endif
;
#define rADDR r1
#define rDATA r2
;
#define rPGADDR r1
#define rPGDATA r2
#define rLEDADDR r3
#define rLEDDATA r4
;
.text
.code 32 /* We are _not_ compiling thumb instructions. */
;
StartUp:
nop
bl SetupPCMCIA
bl SetupGPIO
ldr rPGADDR, GPIO_DATA_G //init the Port G bit0 high.
mov rPGDATA, #1
str rPGDATA, [rPGADDR]
ldr rLEDADDR, LED_ADDR //turn one LED on.
mov rLEDDATA, #6
strh rLEDDATA, [rLEDADDR] //set new LED pattern.
;
Shifter:
ldrh rLEDDATA, [rLEDADDR]
eor rLEDDATA, rLEDDATA, #0xff
mov rLEDDATA, rLEDDATA, lsl #1
ands rLEDDATA, rLEDDATA, #7
moveq rLEDDATA, #1
NoReload:
eor rLEDDATA, rLEDDATA, #0xff
strh rLEDDATA, [rLEDADDR] //set new LED pattern.
eor rPGDATA, rPGDATA, #1
str rPGDATA, [rPGADDR] //toggle PG0.
bl Delay //wait a while.
b Shifter //keep wiggling the bits.
;
SetupPCMCIA:
ldr rADDR, PCMCIACON //setup PCMCIA.
#if USEPCMCIA==1
mov rDATA, #3 //allow for two PCMCIA cards.
#else
mov rDATA, #0 //allow Port G & H to funcion as GPIO.
#endif
str rDATA, [rADDR]
mov pc, lr
;
SetupGPIO:
ldr rADDR, BCR7_REG //Point to BCR7.
ldr rDATA, BCR7_DATA //get value to put in BCR7.
str rDATA, [rADDR] //now set CS7 parms via BCR7.
ldr rPGADDR, GPIO_DATA_DIR_G //set PortG as outputs.
mov rPGDATA, #0
str rPGDATA, [rPGADDR]
mov pc, lr
;
Delay:
#if BOOTABLE==1
mov r6, #0x8000
#else
mov r6, #0x80000
#endif
Delay_More:
subs r6, r6, #1
bne Delay_More
mov pc, lr
;
LED_ADDR:
.word 0x71600000
GPIO_DATA_DIR_G:
.word 0x80000e38
GPIO_DATA_G:
.word 0x80000e3c
BCR7_REG:
.word 0x8000201c
BCR7_DATA:
.word 0x1000b2c2 //16bit, WST2=WST1=22, Idle=2.
PCMCIACON:
.word 0x80002040
PINMUX_REG:
.word 0x80000e2c
MakefilePROG_PREFIX=arm-linux-
ASFLAGS += -mcpu=arm9
CFLAGS += -mcpu=arm9 -mlittle-endian -Werror -O2 -Wall -fno-builtin
CC=$(PROG_PREFIX)gcc
AS=$(PROG_PREFIX)as
CPP=cpp
OBJCOPY=$(PROG_PREFIX)objcopy
INCLUDES=demo.h
OBJS=demo.o
default: demo
all: clean demo
demo.o: demo.S $(INCLUDES)
$(CC) $(ASFLAGS) -c -o $@ $<
demo: $(OBJS) $(INCLUDES) demo.lds demo.S
$(CC) -nostdlib -o demo -T demo.lds $(OBJS)
$(OBJCOPY) -O binary --strip-all demo demo.bin
demo.lds: $(INCLUDES) demo.lds.S
$(CPP) -P -Ush demo.lds.S | grep -v ^$$ > demo.lds
clean:
-rm -f *~ $(OBJS) demo demo.bin demo.lds
I happened to stumble onto this while working with the LH7A400 in learning the assembler. The object is to have the three LEDs strobing sequentially while toggling PortG_bit0.
To build & run:
A. By setting BOOTABLE to 0 (zero), you can make a program to exec under lolo. Build it with 'make', burn 'demo' into flash, then 'exec 0xc0000 -'. By alternately setting USE_PCMCIA to 0/1 (zero / one), you will alternate between toggling PG0 or the LEDs, however you cannot do both.
B.By setting BOOTABLE to a 1 (one), you will now make a binary image that can be place into Flash, replacing bolo. The file you need to burn would be 'demo.bin'. Place it in Flash starting from location 0x0000:0000.
Note: You may have to change PROG_PREFIX and / or the "-mcpu=arm9", in Makefile, to match your compiler.
---
tom@openhardware.net