This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2129 - IAP failed, now UART not working in user code but ISP works?

Hi all,

I have been developing an SD bootloader for the LPC2129. In testing, I have had a flash fail (this was while developing the CRC check for my SD driver). After that, the board no longer sends text on UART0_putc or UART0_puts. I have tried to reprogram the board using ISP and while it programs and verifies successfully, I can no longer use the UART peripherals.

What did I overwrite, can I recover it (if so, how?), and what can I do to prevent this in the future?

Thanks!

Parents
  • Everything is configured the same as it was before, when it was working. My other 8 boards (that I didn't screw up) are working fine still, using the following init:

    void UART0_init(void) { uint8_t temp;

    /* Set up pin select block for tx and rx (pg. 103 in datasheet) */ /* xxxx xxxx xxxx xxxx xxxx xxxx xxxx 0101 or 0x05 */ PINSEL0 &= ~((1<<1)|(1<<3)); PINSEL0 |= (1<<0)|(1<<2);

    /* Enable UART FIFOs, Reset TX and RX FIFOs (pg. 139-140 in datasheet) */ /* xxxx x111 = 0x7 */ U0FCR = 0x7;

    /* Clear Interrupt Enables */ U0IER = 0x0;

    /* Setup Line Control Register, including: word length, stop bits, parity, and enable break transmission (pg. 140-141 in datasheet) */ /* WWSE PP11 */ /* set parity enable */ temp = (UART0_PARITYENABLE << 3); /* set parity */ temp |= (UART0_PARITY << 4); /* set stop bits */ temp |= ((UART0_STOPBITS-1) << 2); /* set word length in temp */ temp |= (UART0_WORDLENGTH-5);

    U0LCR = temp;

    /* Enable DLAB: */ U0LCR |= 0x80;

    /* Set lower bits of divisor latch */ U0DLL = (uint8_t)UART_BAUDCALC(UART0_BAUDRATE); /* Set higher bits of divisor latch */ U0DLM = (uint8_t)(UART_BAUDCALC(UART0_BAUDRATE) >> 8);

    /* Disable DLAB now that we are done with it */ /* U0LCR AND ~(1xxx xxxx) */ U0LCR &= ~(0x80);
    }

    As I said before, the ISP mode works fine and the data verifies properly. All I can figure is that the UART register is somehow screwed up, or it's no longer entering the application at all (I don't have any output LEDs onboard, but my startup file is the same as it ever was).

    /* 32-bit ARM assembly */
    .text
    .arm

    /* The stack sizes of each mode in bytes */
    .set UND_STACK_SIZE, 0x00000004 /* Undefined Mode */
    .set ABT_STACK_SIZE, 0x00000004 /* Abort Mode */
    .set FIQ_STACK_SIZE, 0x00000004 /* Fast Interrupt Mode */
    .set IRQ_STACK_SIZE, 0X00000250 /* Normal Interrupt Mode */
    .set SVC_STACK_SIZE, 0x00000250 /* Supervisor Mode */

    /* The operation mode bits and interrupt flags locations of the CPSR register */
    .set MODE_USR, 0x10 /* User */
    .set MODE_FIQ, 0x11 /* FIQ */
    .set MODE_IRQ, 0x12 /* IRQ */
    .set MODE_SVC, 0x13 /* Supervisor */
    .set MODE_ABT, 0x17 /* Abort */
    .set MODE_UND, 0x1B /* Undefined */
    .set MODE_SYS, 0x1F /* System */

    /* CPSR Register: [... I F T M M M M M] * 7 6 5 4 3 2 1 0 * Bits 0-4 are the current operating mode (see above). * Bit 5 is Thumb instruction set status. * Bit 6 is FIQ enable/disable. * Bit 7 is IRQ enable/disable. */
    .set I_BIT, 0x80 /* If I is set in CPSR, IRQ is disabled */
    .set F_BIT, 0x40 /* If F is set in CPSR, FIQ is disabled */

    .set BL_ENTRY, 0x36000

    .global Reset_Handler
    .global _startup
    .func _startup

    _startup: /* We are using BL_ENTRY instead of Reset_Handler so that the secondary bootloader starts * upon reset. The bootloader will then pass control to the apps Reset_Handler. */ ldr PC, =BL_ENTRY ldr PC, Undef_Addr ldr PC, SWI_Addr ldr PC, PAbt_Addr ldr PC, DAbt_Addr nop /* Reserved Interrupt Vector that holds the NXP/Philips ISP Checksum */ /* See NXP AN10404: " The below instruction is the IRQ vector and it will load the PC with the ISR of the highest priorty interrupt from the VIC Vector Address Register (VICVectAddr at address 0xFFFFF030). " */ ldr PC, [PC, #-0xFF0] ldr PC, FIQ_Addr

    Reset_Addr: .word Reset_Handler
    Undef_Addr: .word Undef_Handler
    SWI_Addr: .word vPortYieldProcessor
    PAbt_Addr: .word PAbt_Handler
    DAbt_Addr: .word DAbt_Handler
    Reserved_Addr: .word 0 /* Reserved Vector, no handler */
    IRQ_Addr: .word IRQ_Handler /* Actually not used, since we loaded [PC, #-0xFF0] into this vector */
    FIQ_Addr: .word FIQ_Handler

    /* For now, cascade all unused exception handlers into the Reset Handler */
    Undef_Handler:
    SWI_Handler:
    PAbt_Handler:
    DAbt_Handler:
    IRQ_Handler:
    FIQ_Handler:
    Reset_Handler: /* Setup the stack in each one of the modes, the order is irrelevant: */ ldr r0, = _end_stack /* r0 contains the address of the end of the stack */

    msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Enter Undefined Mode, disable FIQ/IRQ interrupts */ mov sp, r0 /* Set the stack pointer of this mode to the value of r0 (end of the stack) */ sub r0, r0, #UND_STACK_SIZE /* Subtract the size of the undefined stack from r0, this * leaves the address of the start of the next mode's stack in r0 */

    msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Enter Abort Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #ABT_STACK_SIZE

    msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* Enter FIQ Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #FIQ_STACK_SIZE

    msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* Enter IRQ Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #IRQ_STACK_SIZE

    msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Enter Supervisor Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #SVC_STACK_SIZE

    msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* Enter System Mode, disable FIQ/IRQ interrupts */
    /* add r0, r0, #1 */ mov sp, r0

    /* Clear the .bss section (unitialized variables) to start clean */ mov R0, #0 /* Set R0 to 0, this is the value we clear .bss with */ ldr R1, =_start_bss /* Start of the bss section */ ldr R2, =_end_bss /* End of the bss section */

    2: cmp R1, R2 /* Compare our location in the bss section to the end of the bss section, * when this comparison is true, this loop will * break upon the blo intruction. */ strlo R0, [R1], #4 /* Write the 0 to the current bss address (R1), * writes back R1+4 to R1 (increments our bss iterator) * only if the above cmp is false */ blo 2b /* Loop back to 2 while the cmp is false */

    /* Switch to Supervisor Mode with interrupts disabled for Task Initialization and Scheduler Start */ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT

    /* Enter main() for project C code */ b main

    .endfunc
    .end

Reply
  • Everything is configured the same as it was before, when it was working. My other 8 boards (that I didn't screw up) are working fine still, using the following init:

    void UART0_init(void) { uint8_t temp;

    /* Set up pin select block for tx and rx (pg. 103 in datasheet) */ /* xxxx xxxx xxxx xxxx xxxx xxxx xxxx 0101 or 0x05 */ PINSEL0 &= ~((1<<1)|(1<<3)); PINSEL0 |= (1<<0)|(1<<2);

    /* Enable UART FIFOs, Reset TX and RX FIFOs (pg. 139-140 in datasheet) */ /* xxxx x111 = 0x7 */ U0FCR = 0x7;

    /* Clear Interrupt Enables */ U0IER = 0x0;

    /* Setup Line Control Register, including: word length, stop bits, parity, and enable break transmission (pg. 140-141 in datasheet) */ /* WWSE PP11 */ /* set parity enable */ temp = (UART0_PARITYENABLE << 3); /* set parity */ temp |= (UART0_PARITY << 4); /* set stop bits */ temp |= ((UART0_STOPBITS-1) << 2); /* set word length in temp */ temp |= (UART0_WORDLENGTH-5);

    U0LCR = temp;

    /* Enable DLAB: */ U0LCR |= 0x80;

    /* Set lower bits of divisor latch */ U0DLL = (uint8_t)UART_BAUDCALC(UART0_BAUDRATE); /* Set higher bits of divisor latch */ U0DLM = (uint8_t)(UART_BAUDCALC(UART0_BAUDRATE) >> 8);

    /* Disable DLAB now that we are done with it */ /* U0LCR AND ~(1xxx xxxx) */ U0LCR &= ~(0x80);
    }

    As I said before, the ISP mode works fine and the data verifies properly. All I can figure is that the UART register is somehow screwed up, or it's no longer entering the application at all (I don't have any output LEDs onboard, but my startup file is the same as it ever was).

    /* 32-bit ARM assembly */
    .text
    .arm

    /* The stack sizes of each mode in bytes */
    .set UND_STACK_SIZE, 0x00000004 /* Undefined Mode */
    .set ABT_STACK_SIZE, 0x00000004 /* Abort Mode */
    .set FIQ_STACK_SIZE, 0x00000004 /* Fast Interrupt Mode */
    .set IRQ_STACK_SIZE, 0X00000250 /* Normal Interrupt Mode */
    .set SVC_STACK_SIZE, 0x00000250 /* Supervisor Mode */

    /* The operation mode bits and interrupt flags locations of the CPSR register */
    .set MODE_USR, 0x10 /* User */
    .set MODE_FIQ, 0x11 /* FIQ */
    .set MODE_IRQ, 0x12 /* IRQ */
    .set MODE_SVC, 0x13 /* Supervisor */
    .set MODE_ABT, 0x17 /* Abort */
    .set MODE_UND, 0x1B /* Undefined */
    .set MODE_SYS, 0x1F /* System */

    /* CPSR Register: [... I F T M M M M M] * 7 6 5 4 3 2 1 0 * Bits 0-4 are the current operating mode (see above). * Bit 5 is Thumb instruction set status. * Bit 6 is FIQ enable/disable. * Bit 7 is IRQ enable/disable. */
    .set I_BIT, 0x80 /* If I is set in CPSR, IRQ is disabled */
    .set F_BIT, 0x40 /* If F is set in CPSR, FIQ is disabled */

    .set BL_ENTRY, 0x36000

    .global Reset_Handler
    .global _startup
    .func _startup

    _startup: /* We are using BL_ENTRY instead of Reset_Handler so that the secondary bootloader starts * upon reset. The bootloader will then pass control to the apps Reset_Handler. */ ldr PC, =BL_ENTRY ldr PC, Undef_Addr ldr PC, SWI_Addr ldr PC, PAbt_Addr ldr PC, DAbt_Addr nop /* Reserved Interrupt Vector that holds the NXP/Philips ISP Checksum */ /* See NXP AN10404: " The below instruction is the IRQ vector and it will load the PC with the ISR of the highest priorty interrupt from the VIC Vector Address Register (VICVectAddr at address 0xFFFFF030). " */ ldr PC, [PC, #-0xFF0] ldr PC, FIQ_Addr

    Reset_Addr: .word Reset_Handler
    Undef_Addr: .word Undef_Handler
    SWI_Addr: .word vPortYieldProcessor
    PAbt_Addr: .word PAbt_Handler
    DAbt_Addr: .word DAbt_Handler
    Reserved_Addr: .word 0 /* Reserved Vector, no handler */
    IRQ_Addr: .word IRQ_Handler /* Actually not used, since we loaded [PC, #-0xFF0] into this vector */
    FIQ_Addr: .word FIQ_Handler

    /* For now, cascade all unused exception handlers into the Reset Handler */
    Undef_Handler:
    SWI_Handler:
    PAbt_Handler:
    DAbt_Handler:
    IRQ_Handler:
    FIQ_Handler:
    Reset_Handler: /* Setup the stack in each one of the modes, the order is irrelevant: */ ldr r0, = _end_stack /* r0 contains the address of the end of the stack */

    msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Enter Undefined Mode, disable FIQ/IRQ interrupts */ mov sp, r0 /* Set the stack pointer of this mode to the value of r0 (end of the stack) */ sub r0, r0, #UND_STACK_SIZE /* Subtract the size of the undefined stack from r0, this * leaves the address of the start of the next mode's stack in r0 */

    msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Enter Abort Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #ABT_STACK_SIZE

    msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* Enter FIQ Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #FIQ_STACK_SIZE

    msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* Enter IRQ Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #IRQ_STACK_SIZE

    msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Enter Supervisor Mode, disable FIQ/IRQ interrupts */ mov sp, r0 sub r0, r0, #SVC_STACK_SIZE

    msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* Enter System Mode, disable FIQ/IRQ interrupts */
    /* add r0, r0, #1 */ mov sp, r0

    /* Clear the .bss section (unitialized variables) to start clean */ mov R0, #0 /* Set R0 to 0, this is the value we clear .bss with */ ldr R1, =_start_bss /* Start of the bss section */ ldr R2, =_end_bss /* End of the bss section */

    2: cmp R1, R2 /* Compare our location in the bss section to the end of the bss section, * when this comparison is true, this loop will * break upon the blo intruction. */ strlo R0, [R1], #4 /* Write the 0 to the current bss address (R1), * writes back R1+4 to R1 (increments our bss iterator) * only if the above cmp is false */ blo 2b /* Loop back to 2 while the cmp is false */

    /* Switch to Supervisor Mode with interrupts disabled for Task Initialization and Scheduler Start */ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT

    /* Enter main() for project C code */ b main

    .endfunc
    .end

Children
  • I can't see any code in your post. Just lots of unreadable noise - that is the reason there is information directly above the message box how to post source code.

    Haven't you started by verifying that your application really starts?

    A working UART requiers more than just UART initialization - your program must start, and the oscillator used for baudrate must have the correct speed. And the UART needs to be powered up. Probably other things too.

    You obviously have to do some debugging all the way through the boot sequence.