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!