From 589b4aaf6adf3a60dd057c1100f30bd4e0d3ff2e Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 21 May 2011 01:29:18 +0200 Subject: [PATCH] move reinvoke_isp to separate file, and fix it. Note: Proto#1 badges need an small hardware patch %-) --- main.c | 61 -------------------------------------------------- reinvoke_isp.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 61 deletions(-) create mode 100644 reinvoke_isp.c diff --git a/main.c b/main.c index e29d671..c0837e6 100644 --- a/main.c +++ b/main.c @@ -125,64 +125,3 @@ int main(void) { return 0; } - -/* This data must be global so it is not read from the stack */ -typedef void (*IAP)(uint32_t [], uint32_t []); -IAP my_iap_entry = (IAP)0x1fff1ff1; -uint32_t command[5], result[4]; - -/* This function resets some microcontroller peripherals to reset - hardware configuration to ensure that the USB In-System Programming module - will work properly. It is normally called from reset and assumes some reset - configuration settings for the MCU. - Some of the peripheral configurations may be redundant in your specific - project. - */ - -void ReinvokeISP(void) { - 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; - /* Send Reinvoke ISP command to ISP entry point*/ - gpioSetValue (CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON); - - /* 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(*((uint32_t *)0x1FFF0000)); /* inline asm function */ - - *((uint32_t *)(0x10000054)) = 0x0; - - //set stack pointer - __asm(" ldr r0, =%0\n" - " mov sp, r0\n" - : - : "i" (0x1FFF0000)); - - - - /* Enter ISP. We call "iap_entry" to enter ISP because the ISP entry is done - through the same command interface as IAP. */ - __asm( - " ldr r0, =0x39\n" - " ldr r1, =0x39\n" - " ldr r2, =0x39\n" - " ldr r3, =0x39\n" - " push {r3}\n" - " ldr r4,=0x1fff1ff1\n" - " bx r4\n" - ); - //my_iap_entry(command, result); - // Not supposed to come back! -} diff --git a/reinvoke_isp.c b/reinvoke_isp.c new file mode 100644 index 0000000..0d05fea --- /dev/null +++ b/reinvoke_isp.c @@ -0,0 +1,52 @@ +#include "lpc134x.h" +#include "sysdefs.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 */ +}