AnsweredAssumed Answered

LPC845 Jumping to secondary Application

Question asked by Otavio Borges on Jan 29, 2019
Latest reply on Feb 13, 2019 by Alice_Yang

I'm trying to jump from the bootloader to the user application on a LPC845M301JBD48. So far I manage to use IAP and UART to load the application on flash with the offset 0x3000. But when I try to switch context I receive the following error from LinkServer:

Target error from Register access: Nn(05). Wire ACK Wait in DAP access   

I try boot the application without the debugger connected with no success.

I've tried debugging just the application (compiled with offset 0x3000). and forcing the jump on GDB initialization. I've reached the Reset handler and System Init, but the same error from DAP occurs on the mentioned line below:

void SystemInit (void) {

#if defined(__MCUXPRESSO)
    extern void(*const g_pfnVectors[]) (void);
    SCB->VTOR = (uint32_t) &g_pfnVectors;
#else
    extern void *__Vectors;
    SCB->VTOR = (uint32_t) &__Vectors;
#endif

    // Initial configuration of PLL using FRO
    SYSCON->SYSPLLCLKSEL = 0;
    SYSCON->SYSPLLCLKUEN = 1;
    SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK; // Debugger disconnects here
    SYSCON->SYSPLLCTRL = SYSCON_SYSPLLCTRL_MSEL(0x01) |
            SYSCON_SYSPLLCTRL_PSEL(0);                        // PLL = ((4+1) * CLK_OSC_IN) / (2 * (2^0)) = 30MHz
    SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_SYSPLL_PD_MASK);
    while(SYSCON->SYSPLLSTAT == 0)                            // wait for the PLL to lock
        __asm("nop");

    // config clock to 30MHz
    // setup XTALIN and XTALOUT
    SYSCON->SYSAHBCLKCTRL0 |= (SYSCON_SYSAHBCLKCTRL0_IOCON_MASK | SYSCON_SYSAHBCLKCTRL0_SWM_MASK);
    IOCON->PIO[IOCON_INDEX_PIO0_9] = 0;
    IOCON->PIO[IOCON_INDEX_PIO0_8] = 0;
    SWM0->PINENABLE0 &= ~(SWM_PINENABLE0_XTALIN_MASK | SWM_PINENABLE0_XTALOUT_MASK);

    SYSCON->SYSOSCCTRL = 0;                                    // disable BYPASS and OSC range 1-20MHz
    SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_SYSOSC_PD_MASK);    // enable OSC output
    for(uint16_t delay = 0; delay < 6500; delay++)
        __asm("nop");                                        // wait around 5us

    // setup the PLL
    SYSCON->EXTCLKSEL = 0;                                    // Use Sytem Osc
    SYSCON->SYSPLLCLKSEL = SYSCON_SYSPLLCLKSEL_SEL(0x01);    // use external XTAL as PLL source
    SYSCON->SYSPLLCLKUEN = 0x01;                            // update CLK source for PLL
    SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK;        // turn off PLL
    SYSCON->SYSPLLCTRL = SYSCON_SYSPLLCTRL_MSEL(0x01) |
            SYSCON_SYSPLLCTRL_PSEL(0);                        // PLL = ((1+1) * CLK_OSC_IN) / (1) = 24MHz
    SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_SYSPLL_PD_MASK);    // Turn on the PLL
    while(SYSCON->SYSPLLSTAT == 0)                            // wait for the PLL to lock
        __asm("nop");

    // update System clock etc
    SYSCON->MAINCLKSEL = SYSCON_MAINCLKSEL_SEL(0x00);        // Use external CLock as Pre-PLL source
    SYSCON->MAINCLKUEN = 0x01;                                // update MAINCLKSRC
    SYSCON->MAINCLKPLLSEL = SYSCON_MAINCLKPLLSEL_SEL(0x01);    // Use PLL as Main clk source
    SYSCON->MAINCLKPLLUEN = 0x01;                            // update MAINCLKSRC
    SYSCON->SYSAHBCLKDIV = SYSCON_SYSAHBCLKDIV_DIV(1);        // Main clk divider 1 = 30MHz

    SystemCoreClockUpdate();
    SystemInitHook();
}

If I compile the user application without the offset (FLASH starting at 0x0) it works perfectly.

To switch from the bootloader to the application I use the following code:

static void BootApplication(uint32_t startAddr){
    app entryPoint;


    __DSB();
    __ISB();
    __set_MSP(*((uint32_t *)startAddr));
    SCB->VTOR = (startAddr & SCB_VTOR_TBLOFF_Msk);
    __DSB();
    __ISB();

    entryPoint = (app) *((uint32_t *)(startAddr + 4));

    entryPoint();
}

I'm using MCUXpresso v10.3.0 and LPC845 BRK board.

 

Thanks for all the help!

Outcomes