LPC845 Jumping to secondary Application

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC845 Jumping to secondary Application

Jump to solution
2,495 Views
otavioborges
Contributor III

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!

Labels (1)
0 Kudos
Reply
1 Solution
1,964 Views
otavioborges
Contributor III

Figured out the issue. I was turning off the PLL but not correctly updating the main clk source. Forgot to write 0 on MAINCLKUEN. The following code loads the user application and boot it:

typedef void (*app)(void);

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));

    DisablePLL();
    entryPoint();
}

static void DisablePLL(void){

    __disable_irq();
    SYSCON->MAINCLKSEL = SYSCON_MAINCLKSEL_SEL(0x00);        // using FRO
    SYSCON->MAINCLKUEN = 0;
    SYSCON->MAINCLKUEN = 1;                                    // update main CLK

    SYSCON->MAINCLKPLLSEL = SYSCON_MAINCLKPLLSEL_SEL(0x00);    // using main_clk_pre_pll
    SYSCON->MAINCLKPLLUEN = 0;
    SYSCON->MAINCLKPLLUEN = 1;                                // update PLL clock source
    __enable_irq();

    SYSCON->SYSPLLCLKSEL = SYSCON_SYSPLLCLKSEL_SEL(0x00);    // use FRO as PLL clock input
    SYSCON->SYSPLLCLKUEN = 0;
    SYSCON->SYSPLLCLKUEN = 1;                                // update PLL

    SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK;        // disable PLL

    SystemCoreClockUpdate();

}

PS.: using add-symbol-file to the bootloader debug configuration with the .axf of the application enabled me to debug both applications together. Leaving as reference.

View solution in original post

0 Kudos
Reply
4 Replies
1,965 Views
otavioborges
Contributor III

Figured out the issue. I was turning off the PLL but not correctly updating the main clk source. Forgot to write 0 on MAINCLKUEN. The following code loads the user application and boot it:

typedef void (*app)(void);

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));

    DisablePLL();
    entryPoint();
}

static void DisablePLL(void){

    __disable_irq();
    SYSCON->MAINCLKSEL = SYSCON_MAINCLKSEL_SEL(0x00);        // using FRO
    SYSCON->MAINCLKUEN = 0;
    SYSCON->MAINCLKUEN = 1;                                    // update main CLK

    SYSCON->MAINCLKPLLSEL = SYSCON_MAINCLKPLLSEL_SEL(0x00);    // using main_clk_pre_pll
    SYSCON->MAINCLKPLLUEN = 0;
    SYSCON->MAINCLKPLLUEN = 1;                                // update PLL clock source
    __enable_irq();

    SYSCON->SYSPLLCLKSEL = SYSCON_SYSPLLCLKSEL_SEL(0x00);    // use FRO as PLL clock input
    SYSCON->SYSPLLCLKUEN = 0;
    SYSCON->SYSPLLCLKUEN = 1;                                // update PLL

    SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK;        // disable PLL

    SystemCoreClockUpdate();

}

PS.: using add-symbol-file to the bootloader debug configuration with the .axf of the application enabled me to debug both applications together. Leaving as reference.

0 Kudos
Reply
1,964 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Otavio Borges,

1)In default,  the MCUXpresso IDE can't debug application with start address from 0x3000( only can start from 0x0000).

2) About the bootloader,  does application file have been flashed into chip before jump.  There is some secondary bootloader demo , you can have a look:

LPC82X|NXP 

Hope it helps,


Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply
1,964 Views
otavioborges
Contributor III

1) Is there a way I can debug the application. For example using gdb's add-symbol-file;

2) I've tried the approach on the mentioned demo. But with no luck. But raised some questions. Why does the demo uses SYSMEMREMAP instead of VTOR to change the IRQ interruption vector? Would both approaches work on LPC845?

0 Kudos
Reply
1,964 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Otavio,

I should add something after my last reply,

" 1)In default,  the MCUXpresso IDE can't debug application with start address from 0x3000( only can start from 0x0000)."

when using  CMSIS-DAP or linker server debug probe, 

we can re-configure the "Reset  Handing" to SOFT as below, then can debug your application .

pastedImage_1.png


Have a great day,
TIC

0 Kudos
Reply