Dave,
Thank you for the advice. I should have read the section in the manual about the bootloader, because it spells that p0.14 bit pretty plainly. I’ve tied that pin HIGH, so that shouldn’t be the issue anymore. calulate_checksum was specified by my config file, so I don’t suppose that’s the problem either.
What I’ve done is set up a simple LPC2103 circuit, and want to run the blinking LED example from the lynch tutorial. I’ve taken the C file, with some excess code culled out of it, and compiled it with the following startup code:
/* ***************************************************************************************************************
crt.s STARTUP ASSEMBLY CODE
-----------------------
Module includes the interrupt vectors and start-up code.
*************************************************************************************************************** */
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000004 /* stack for "undefined instruction" interrupts is 4 bytes */
.set ABT_STACK_SIZE, 0x00000004 /* stack for "abort" interrupts is 4 bytes */
.set FIQ_STACK_SIZE, 0x00000004 /* stack for "FIQ" interrupts is 4 bytes */
.set IRQ_STACK_SIZE, 0X00000004 /* stack for "IRQ" normal interrupts is 4 bytes */
.set SVC_STACK_SIZE, 0x00000004 /* stack for "SVC" supervisor mode is 4 bytes */
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set MODE_USR, 0x10 /* Normal User Mode */
.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
.text
.arm
.global Reset_Handler
.global _startup
.func _startup
_startup:
# Exception Vectors
_vectors: ldr PC, Reset_Addr
ldr PC, Undef_Addr
ldr PC, SWI_Addr
ldr PC, PAbt_Addr
ldr PC, DAbt_Addr
nop /* Reserved Vector (holds Philips ISP checksum) */
ldr PC, [PC,#-0xFF0] /* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin */
ldr PC, FIQ_Addr
Reset_Addr: .word Reset_Handler /* defined in this module below */
Undef_Addr: .word UNDEF_Routine /* defined in main.c */
SWI_Addr: .word SWI_Routine /* defined in main.c */
PAbt_Addr: .word UNDEF_Routine /* defined in main.c */
DAbt_Addr: .word UNDEF_Routine /* defined in main.c */
IRQ_Addr: .word IRQ_Routine /* defined in main.c */
FIQ_Addr: .word FIQ_Routine /* defined in main.c */
.word 0 /* rounds the vectors and ISR addresses to 64 bytes total */
# Reset Handler
Reset_Handler:
/* Setup a stack for each mode - note that this only sets up a usable stack
for User mode. Also each mode is setup with interrupts initially disabled. */
ldr r0, =_stack_end
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */
mov sp, r0
/* copy .data section (Copy from ROM to RAM) */
ldr R1, =_etext
ldr R2, =_data
ldr R3, =_edata
1: cmp R2, R3
ldrlo R0, [R1], #4
strlo R0, [R2], #4
blo 1b
/* Clear .bss section (Zero init) */
mov R0, #0
ldr R1, =_bss_start
ldr R2, =_bss_end
2: cmp R1, R2
strlo R0, [R1], #4
blo 2b
/* Enter the C code */
b main
.endfunc
.end
and linker script:
/* identify the Entry Point */
ENTRY(_startup)
/* specify the LPC2106 memory areas */
MEMORY
{
flash : ORIGIN = 0, LENGTH = 128K /* FLASH ROM */
ram_isp_low(A) : ORIGIN = 0x40000120, LENGTH = 223 /* variables used by Philips ISP bootloader */
ram : ORIGIN = 0x40000200, LENGTH = 64992 /* free RAM area */
ram_isp_high(A) : ORIGIN = 0x4000FFE0, LENGTH = 32 /* variables used by Philips ISP bootloader */
}
/* define a global symbol _stack_end */
_stack_end = 0x4000FEDC;
/* now define the output sections */
SECTIONS
{
. = 0; /* set location counter to address zero */
startup : { *(.startup)} >flash /* the startup code goes into FLASH */
.text : /* collect all sections that should go into FLASH after startup */
{
*(.text) /* all .text sections (code) */
*(.rodata) /* all .rodata sections (constants, strings, etc.) */
*(.rodata*) /* all .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* all .glue_7 sections (no idea what these are) */
*(.glue_7t) /* all .glue_7t sections (no idea what these are) */
_etext = .; /* define a global symbol _etext just after the last code byte */
} >flash /* put all the above into FLASH */
.data : /* collect all initialized .data sections that go into RAM */
{
_data = .; /* create a global symbol marking the start of the .data section */
*(.data) /* all .data sections */
_edata = .; /* define a global symbol marking the end of the .data section */
} >ram AT >flash /* put all the above into RAM (but load the LMA copy into FLASH) */
.bss : /* collect all uninitialized .bss sections that go into RAM */
{
_bss_start = .; /* define a global symbol marking the start of the .bss section */
*(.bss) /* all .bss sections */
} >ram /* put all the above in RAM (it will be cleared in the startup code */
. = ALIGN(4); /* advance location counter to the next 32-bit boundary */
_bss_end = . ; /* define a global symbol marking the end of the .bss section */
}
_end = .; /* define a global symbol marking the end of application RAM */
The comments say 2106, because it’s the tutorial example, but checking most of the addresses against the 2101/2/3 user manual, the relevant ones seem to be the same. (Perhaps there’s an omission here on my part)
I make everything, and produce a hex file, which I then load into the target. Here’s my openOCD session:
ryansturmer@creampuffstarship:~/src/openocd/trunk$ openocd --file lpc2xxx_armusbocd.cfg
Info: openocd.c:93 main(): Open On-Chip Debugger 1.0 (2008-01-05-01:03) svn:247
Info: openocd.c:94 main(): $URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
Info: jtag.c:1291 jtag_examine_chain(): JTAG device found: 0x4f1f0f0f (Manufacturer: 0x787, Part: 0xf1f0, Version: 0x4)
Warning: arm7_9_common.c:742 arm7_9_assert_reset(): srst resets test logic, too
Info: server.c:67 add_connection(): accepted 'telnet' connection from 0
And here’s what it looks like from the telnet client when I flash the system.
Open On-Chip Debugger
> poll
target state: halted
target halted in Thumb state due to debug request, current mode: Supervisor
cpsr: 0x400000f3 pc: 0x7fffe27e
> flash write_image /home/ryansturmer/projects/repos/lpc2000/examples/demo2106_blink_flash/main.hex 0 ihex
wrote 560 byte from file /home/ryansturmer/projects/repos/lpc2000/examples/demo2106_blink_flash/main.hex in 1s 183467us (0.462096 kb/s)
> reset run
> poll
target state: running
> halt
requesting target halt...
> Target 0 halted
target halted in Thumb state due to debug request, current mode: Supervisor
cpsr: 0x400000f3 pc: 0x7fffe27e
Again, I’m almost certain this is an obvious mistake due to my n00bery. Does anything jump out of the screen at anyone? I can post the C file and the header as well, but it’s pretty vanilla, and I don’t suspect it to be the problem.
Thanks for the help everyone, you guys have all been fantastic!