6 years, 8 months ago.

Re-invoke USB bootloader on LPC11U68

Hey guys, I've been using the following code to re-invoke the USB bootloader on the LPC11U35 QuickStart Board, but it doesn't work on the LPC11U68. I believe *((unsigned int *)(0x10000054)) = 0x0; may be the problem, since I remember reading somewhere that this magic address was different between the LPC11U2X and LPC11U3X microcontrollers. Anybody have any ideas?

/* 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 IAP_ReinvokeISP()
{
    //Make sure USB clock is turned on before calling ISP
    LPC_SYSCON->SYSAHBCLKCTRL |= 0x04000;

    //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;

    //Prepare the command array
    m_Command[0] = 57;

    //Initialize the storage state machine
    *((unsigned int *)(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(*((unsigned int *)0x00000000));

    //Invoke IAP call...
    IAP_Entry(m_Command, m_Result);

    //Shouldn't return
    while(1);
}

Question relating to:

After some further experiments, it seems that *((unsigned int *)(0x10000054)) = 0x0; and __set_MSP(*((unsigned int *)0x00000000)); have no effect on the LPC11U35. Are these lines just a carryover from an older LPC series? Anyway, removing them still doesn't fix the LPC11U68, it seems to be resetting rather than starting the bootloader... In fact, if I hold down the ISP button while trying to re-invoke ISP the bootloader runs, so it's definitely resetting.

posted by Neil Thiessen 23 May 2014

1 Answer

6 years, 7 months ago.

Hi,

Following code works with LPCXpresso11U68. I got a CRP DISABLED mass storage by this program.

#include "mbed.h"

#define IAP_ENTRY_LOCATION        0X1FFF1FF1
typedef void (*IAP_ENTRY_T)(unsigned int[5], unsigned int[4]);

void IAP_Entry(unsigned int cmd_param[5], unsigned int status_result[4])
{
    ((IAP_ENTRY_T) IAP_ENTRY_LOCATION)(cmd_param, status_result);
}

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

    SCB->VTOR = 0;
    LPC_SYSCON->SYSAHBCLKCTRL |= 0x14440;
    LPC_SYSCON->SYSAHBCLKDIV = 1;
    
    command[0] = 57;
    IAP_Entry(command, result);
}

int main() {
    IAP_ReinvokeISP();
}

Accepted Answer

Thanks, I'll give this a try tomorrow. Just curious, but what does SCB->VTOR = 0 accomplish?

posted by Neil Thiessen 08 Jun 2014

When any interrupt is defined (e.g. using Ticker or wait etc), VTOR is remapped to bottom of SRAM area. "SCB->VTOR = 0;" sets the value by default.

posted by Toyomasa Watarai 08 Jun 2014

@NEIL - VTOR = 0, means vector table offset is to the address 0. More information : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0321a/BIHHDGBC.html

posted by Martin Kojtal 08 Jun 2014

Awesome! That was the missing line! :D

posted by Neil Thiessen 09 Jun 2014