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!
Solved! Go to Solution.
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.
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.
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:
Hope it helps,
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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?
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 .
Have a great day,
TIC