LPC11C14 IAP 57 command bug CAN

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by Opticalworm on Tue Jan 31 13:12:55 MST 2012
Hello Everyone, 
for the last few days now, I've been trying to figure out why my LPC11C14 kept crashing everytime I try to re-invoke the CAN bootloader (ISP) via IAP57. (bare in mind that my code were compiled at the time in uVision)
Eventually I decide to try my hand at compiling the same code in LPCXpresso and to my supprise, it worked worked fine. (Also bare in mind that I used virtually the same code.)

Test Code (in LPCXpresso):

So after a few days of of testing, hours of reading datasheets, and comparing the RAM on output from both IDEs; I belive that I've found where the bug comes is at and why it has a better chance in working LPCXpresso over uVision.

[B][SIZE=3]In short[/SIZE][/B]
The bug is due to the fact that the IAP57 command doesn't reset the stack during its initialization phase and instead it uses the user current stack pointer (which could be any where in RAM at the point). Flash magic (Via CAN) assumes the ISP bootloader wont use the RAM rigion bellow 0x1000_1E60 [= (0x1000_2000 -(256 +128 +32))] while it writes to the rest of the, supposedly free, RAM. as you can see Flash magic could write to the part of the RAM ISP is using and cause the device to fail.

this was the bug that cause by LPC11C14 to crash.

[B][SIZE=4][COLOR=black]The bit I needs help on[/COLOR][/SIZE][/B]
Now that I know that the stack need resetting, I'm having trouble in actually doing it.

for example I've tried adding the following command into InvokeBootloader() just before calling the IAP57 (the stack pointer I select should place the stack 32 byte bellow the top of the stack.)
but when I call iap_entry() the LPC11C14 brings up a hard fault.
Any Idea clue what I'm doing wrong?

void InvokeBootloader(void) {    
uint32_t command[5];   
uint32_t result[4];    

__disable_irq();      /* make sure 32-bit Timer 1 is turned on before calling ISP */  

LPC_SYSCON->SYSAHBCLKCTRL |= 0x00400;     /* make sure GPIO clock is turned on before calling ISP */    
LPC_SYSCON->SYSAHBCLKCTRL |= 0x00040;     /* make sure IO configuration clock is turned on before calling ISP */ 
LPC_SYSCON->SYSAHBCLKCTRL |= 0x10000;     /* make sure AHB clock divider is 1:1 */    
LPC_SYSCON->SYSAHBCLKDIV = 1;     // Disable the PLL     LPC_SYSCON->MAINCLKSEL = 0; // Enable the IRC oscillator     LPC_SYSCON->MAINCLKUEN    = 0x01;               /* Update MCLK Clock Source */    
LPC_SYSCON->MAINCLKUEN    = 0x00;               /* Toggle Update Register   */    
LPC_SYSCON->MAINCLKUEN    = 0x01;     while (!(LPC_SYSCON->MAINCLKUEN & 0x01));       /* Wait Until Updated       */
command[0] = IAP_REINVOKE_ISP;    // Reset the stack pointer before calling IAP-57   

__set_MSP(0x10001FE0);          //reset stack pointer

iap_entry(command, result);

[SIZE=3][COLOR=black]Oh yeah this is the quick outline of the Device and Tools I'm using [/COLOR][/SIZE][COLOR=black][SIZE=3]
[/SIZE][/COLOR]• LPC11C14 BootLoader Vr: 7.1
• LPC11C14 Device ID: 0x1440102B
• IDE: KEIL uVision, LPCXpresso
• Debbuger: ULINK2, LPC-LINK
• ISP Programmer: Flash magic with [PEAK PCAN USB]