#include "lpc134x.h" #include "sysdefs.h" #include "basic/basic.h" #include "usb/usbmsc.h" /* Missing from core */ #define set_MSP(x) \ __asm( "msr MSP, %0\n" : : "r" (x) ) /* Jump back into bootcode, enable mass storage firmware flashing */ void ReinvokeISP(void) { uint32_t command[5]; // command[0] = 57; /* Disable SYSTICK timer and interrupt before calling into ISP */ SYSTICK_STCTRL &= ~(SYSTICK_STCTRL_ENABLE | SYSTICK_STCTRL_TICKINT); /* make sure USB clock is turned on before calling ISP */ SCB_SYSAHBCLKCTRL |= 0x04000; /* make sure 32-bit Timer 1 is turned on before calling ISP */ SCB_SYSAHBCLKCTRL |= 0x00400; /* make sure GPIO clock is turned on before calling ISP */ SCB_SYSAHBCLKCTRL |= 0x00040; /* make sure IO configuration clock is turned on before calling ISP */ SCB_SYSAHBCLKCTRL |= 0x10000; /* make sure AHB clock divider is 1:1 */ SCB_SYSAHBCLKDIV = 1; /* as per 19.2.1 of lpc13xx user manual, clear this byte of ram to avoid long delay before USB becomes active */ *((uint32_t *)(0x10000054)) = 0x0; /* Set stack pointer to ROM value (reset default) This must be the last piece of code executed before calling ISP, because most C expressions and function returns will fail after the stack pointer is changed. */ set_MSP(*(int*)0x1FFF0000); /* Enter ISP. We call "iap_entry" to enter ISP because the ISP entry is done through the same command interface as IAP. */ iap_entry(command, NULL); /* Alternative shorter direct assembler way: */ /* __asm( "ldr r0, =%0\n" "ldr lr, =0x1fff1ff1\n" : : "i" (&command) ); */ /* NOTREACHED */ } void EnableWatchdog(uint32_t ms){ /* Enable WDT clock */ SCB_SYSAHBCLKCTRL |= 0x8000; SCB_PDRUNCFG &= ~(1); /* select internal RC */ SCB_WDTCLKSEL = SCB_WDTCLKSEL_SOURCE_INTERNALOSC; /* enable */ SCB_WDTCLKUEN = 0; SCB_WDTCLKUEN = 1; #define INTERNAL_RC_HZ 12000000 WDT_WDTC= ((INTERNAL_RC_HZ/4)/1000) *ms; SCB_WDTCLKDIV = 1; WDT_WDMOD = WDT_WDMOD_WDRESET_ENABLED | WDT_WDMOD_WDEN_ENABLED; // frob watchdog once. WDT_WDFEED = WDT_WDFEED_FEED1; WDT_WDFEED = WDT_WDFEED_FEED2; }; void ISPandReset(void){ #if CFG_USBMSC if(usbMSCenabled&USB_MSC_ENABLEFLAG){ usbMSCOff(); delayms(500); }; #endif #if CFG_USBCDC if(usbMSCenabled&USB_CDC_ENABLEFLAG){ USB_Connect(FALSE); delayms(500); }; #endif EnableWatchdog(1000*15); ReinvokeISP(); };