Entering ISP mode from user code with LPC11U68JBD48

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Entering ISP mode from user code with LPC11U68JBD48

2,028 Views
davidyun
Contributor II

I'm using LPC11U68JBD48 microprocessor. I have a switch which toggles PIO0_1 pin. I can go into the ISP mode by pressing the switch and by applying power to the board (Resetting board).

Now I have my application code running and I would like to create a means to invoke the ISP USB MSD over my application so the toggle switch is not necessary. What I would like to do is that when I get a command from PC application by USB protocol, I would like my application (LP11U68) go into the SPI mode.
Is it possible with LPC11U68JBD48 microprocessor?

I'm using Chip_IAP_ReinvokeISP() function to make my application to go into the ISP USB mode.

What I have noticed so far:

1. If I call Chip_IAP_ReinvokeISP() very early in main function, it DOES go into the ISP mode, but if I put any delay (say 1 second), it doesn't go into the ISP mode.

2. When I set GPIO initialisation as below and call Chip_IAP_ReinvokeISP(), it does not go into the ISP mode.

LPC_IOCON->PIO0[1] &= 0;
LPC_IOCON->PIO0[1] |= (0x02<<3); /*internal pull up resistor*/

LPC_IOCON->PIO0[3] |= (1 << 0); /*set up of PIO0_3 register to USB_VBUS*/
LPC_IOCON->PIO0[3] |= (0 << 3); /*and inactive pull-up/pull-down resistors*/

3. I have tried everything above with LPC11U68 development board which has LPC11U68JBD100 and LPC4322JET100(Link 2), everything seems to be working fine.


Any help would be appreciated.

Thanks
David

Labels (2)
9 Replies

1,497 Views
nxf51211
NXP Employee
NXP Employee

Hi David,

I attempted setting the LPC11U68 to ISP mode using the LPCOpen example called "periph_flashiap" and it worked. For that, I took the mentioned project and modified it in order for it to have a delay of approximately 1s and proceed to call the Chip_IAP_ReinvokeISP() function; after the function is called, I used a terminal (Tera Term or Flash Magic) to check if ISP was correctly set.

It is important to mention that I did not follow the GPIO initialization that you described (I didn't modify those pins at all). Here I attach the code I implemented (using the LPCOpen project I previously mentioned):

int main(void)
{
 /**Delay variables*/
 uint32_t i = 0;
 uint32_t j = 0;

 /* Generic Initialization */
 SystemCoreClockUpdate();
 Board_Init();

 /* Enable SysTick Timer */
 SysTick_Config(SystemCoreClock / TICKRATE_HZ);

 /* Disable interrupt mode so it doesn't fire during FLASH updates */
 __disable_irq();


 /** Delay*/
 for(i = 0; 100000 > i; i++)
  for(j = 0; 100 > j; j++);



 /* Enter ISP mode */
 Chip_IAP_ReinvokeISP();

 while (1) {
  __WFI();
 }

 return 0;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I hope this information can help you.

Ricardo Delsordo

1,497 Views
davidyun
Contributor II

Thanks Ricardo for your reply.

Your code above doesn't seem to be working for both LPC11U68 development board and my board in which there is a LPC11U68 chip. I checked whether it appeared as a Mass Storage Class (MSC) device or not.

See an example picture below which shows I could go into the ISP mode by pressing the switch(PIO0_1 pin) and by applying power to the board (Resetting the board). The idea is that my PC application would access CRP DISABLD (E:) drive and replace it with a newer firmware. This way, we could update the firmware in the field. Our product won't have any button, that's why I would like to go into the ISP mode at the runtime when I get a command from the PC application.

Mass storage class.png

Do you have any other suggestion for the field firmware update?

Can you update the firmware by using Tera Term or Flash Magic?

When I ran your code, it appeared as follows instead of the picture above.

Mass storage class - not working.png

My code below seems to be working if I comment out the line, LPC_IOCON->PIO0[3] &= (1 << 0);.

However, with LPC11U68 development board it seems to be working no matter that I comment out that line or not.

 

#include <board.h>

#define POWER_CON_SYSOSC (1<<5) /*register value to enable the power to system oscillator*/

#define BYPASS 1 /*register value to set Bypass system oscillator*/

#define FREQRANGE (1<<1) /*register value to determin frequency range for low-power oscillator*/

#define PLL_CTRL_CONFIG 0x23 /*register value to configure the PLL*/

#define PLL_ON ~(1<<7) /*register value to enable the PLL*/

#define PLL_LOCK 0x01 /*register value to lock the PLL*/

#define CLK_SEL_PLLOUT 3 /*register value to set the main system clock to the output of the pll*/

#define GPIO_CLK_EN (1<<6) /*register value to enable the clock signal to GPIO block*/

#define IOCON_CLK_EN (1<<16) /*register value to enable the clock signal to IOCON block*/

#define TIMERS_CLK_EN (0xF<<7) /*register value to enable the clock signal to all timers*/

#define UART_CLK_EN (1<<12) /*register value to enable the clock signal to UART block*/

#define PINT_CLK_EN (1<<19) /*register value to enable the clock signal to pin interrupt block*/

#define SSP0_CLK_EN (1<<11) /*register value to enable the clock signal to SSP0 block*/

#define SSP1_CLK_EN (1<<18) /*register value to enable the clock signal to SSP1 block*/

#define ADC_CLK_EN (1<<13) /*register value to enable the clock signal to ADC block*/

#define USB_CLK_EN (1<<14) /*register value to enable the clock signal to USB block*/

#define PIO0_17_D5_LED (1<<17) /*register value for the control bit for PIO0_17 pin*/

#define CLR_PIN_CONFIG 0x00000000 /*value to clear a pin's IOCON register*/

#define PULL_UP_EN (0x02<<3) /*register value used to set a GPIO pin to have an internal pull up resistor*/

#define USB_VBUS (1<<0) /*register value to configure pin as USB VBUS*/

#define PULL_UP_PULL_DOWN_INACTIVE ~(3<<3) /*register value to configure pin so that the internal pull-up/pull-down resistors are not active*/

 

int main(void) {

// System clock settings

LPC_SYSCTL->PDRUNCFG &= ~(POWER_CON_SYSOSC); ///Power-up System Osc

LPC_SYSCTL->PDRUNCFG &= ~(1<<4); /*ADC powered*/

LPC_SYSCTL->SYSOSCCTRL &= ~(BYPASS); /*system oscillator control register: Oscillator is not bypassed, frequency range is 1 - 20 MHz*/

LPC_SYSCTL->SYSOSCCTRL &= ~(FREQRANGE);

/*configure pll to give 48MHz clock output*/

LPC_SYSCTL->SYSPLLCTRL = PLL_CTRL_CONFIG;

LPC_SYSCTL->PDRUNCFG &= PLL_ON;

/*wait for pll lock*/

while(!(LPC_SYSCTL->SYSPLLSTAT & PLL_LOCK))

{

/*do nothing*/

}

/*connect main clock to pll output*/

LPC_SYSCTL->MAINCLKSEL |= CLK_SEL_PLLOUT;

LPC_SYSCTL->MAINCLKUEN = FALSE; /*Toggle enable for setting to take effect*/

LPC_SYSCTL->MAINCLKUEN = TRUE;

/*enable clock to required peripherals*/

g_systemControl->SYSAHBCLKCTRL |= IOCON_CLK_EN ///enable clock to IOCON

                                                               | USB_CLK_EN ///enable clock to USB

                                                               | GPIO_CLK_EN ///enable clock to GPIO

                                                               | TIMERS_CLK_EN ///enable clock to timers

                                                               | PINT_CLK_EN ///enable clock to pin interrupts

                                                               | SSP0_CLK_EN ///enable clock to SSP0

                                                               | ADC_CLK_EN; ///enable clock to ADC

//GPIO settings 

LPC_IOCON->PIO0[1] &= 0;

LPC_IOCON->PIO0[1] |= (0x02<<3); /*internal pull up resistor*/

/// USB_VBUS config

LPC_IOCON->PIO0[3] |= (1 << 0);  /// Set up of PIO0_3 register to USB_VBUS

LPC_IOCON->PIO0[3] &= (1 << 0);  /// and inactive pull-up/pull-down resistors

LPC_GPIO->DIR[0] |= PIO0_17_D5_LED; /// Port 0 - pin 17 LED

 

while(1) {

 

LPC_GPIO->SET[0] |= PIO0_17_D5_LED; /*Pin high initially so LEDs are On*/

for (int j = 0; j < 1000000; j++)

{

}

 

LPC_GPIO->CLR[0] |= PIO0_17_D5_LED; /*Pin low so LEDs are off*/

 for (int j = 0; j < 1000000; j++)

{

}

 

 

 

Chip_IAP_ReinvokeISP();

}

}

Thanks for your help.

David

0 Kudos

1,497 Views
davidyun
Contributor II

One more to add. Even if I comment out the line, LPC_IOCON->PIO0[3] &= (1 << 0), if I add another delay in the while loop as follows, it doesn't seem to work.

while(1) {

 

for (int j = 0; j < 10000000; j++)

{

}

LPC_GPIO->SET[0] |= PIO0_17_D5_LED; /*Pin high initially so LEDs are On*/

  for (int j = 0; j < 1000000; j++)

{

}

 

LPC_GPIO->CLR[0] |= PIO0_17_D5_LED; /*Pin low so LEDs are off*/

for (int j = 0; j < 1000000; j++)

{

}

 

 

 

Chip_IAP_ReinvokeISP();

}

Also, I have tried it by adding __disable_irq(); at the beginning of while loop, but it still doesn't work.

I

0 Kudos

1,497 Views
nxf51211
NXP Employee
NXP Employee

Hi David,

First I'd like to ask you if you tried my code modifying the LPC project I mentioned, or if you just tried the main function alone (this is because in the code I put on my first answer, the system initialization is made inside the "Generic Initialization" functions which were generated with the LPC Project).

Also, I tried the code that you used, and I was able to get the board to enter ISP mode even with all the delays you used and with the line LPC_IOCON->PIO0[3] &= (1 << 0). For that I just changed the g_systemControl->SYSAHBCLKCTRL for LPC_SYSCTL->SYSAHBCLKCTRL when you enable the clock:

#include <board.h>



#define POWER_CON_SYSOSC (1<<5) /*register value to enable the power to system oscillator*/
#define BYPASS 1 /*register value to set Bypass system oscillator*/
#define FREQRANGE (1<<1) /*register value to determin frequency range for low-power oscillator*/
#define PLL_CTRL_CONFIG 0x23 /*register value to configure the PLL*/
#define PLL_ON ~(1<<7) /*register value to enable the PLL*/
#define PLL_LOCK 0x01 /*register value to lock the PLL*/
#define CLK_SEL_PLLOUT 3 /*register value to set the main system clock to the output of the pll*/
#define GPIO_CLK_EN (1<<6) /*register value to enable the clock signal to GPIO block*/
#define IOCON_CLK_EN (1<<16) /*register value to enable the clock signal to IOCON block*/
#define TIMERS_CLK_EN (0xF<<7) /*register value to enable the clock signal to all timers*/
#define UART_CLK_EN (1<<12) /*register value to enable the clock signal to UART block*/
#define PINT_CLK_EN (1<<19) /*register value to enable the clock signal to pin interrupt block*/
#define SSP0_CLK_EN (1<<11) /*register value to enable the clock signal to SSP0 block*/
#define SSP1_CLK_EN (1<<18) /*register value to enable the clock signal to SSP1 block*/
#define ADC_CLK_EN (1<<13) /*register value to enable the clock signal to ADC block*/
#define USB_CLK_EN (1<<14) /*register value to enable the clock signal to USB block*/
#define PIO0_17_D5_LED (1<<17) /*register value for the control bit for PIO0_17 pin*/
#define CLR_PIN_CONFIG 0x00000000 /*value to clear a pin's IOCON register*/
#define PULL_UP_EN (0x02<<3) /*register value used to set a GPIO pin to have an internal pull up resistor*/
#define USB_VBUS (1<<0) /*register value to configure pin as USB VBUS*/
#define PULL_UP_PULL_DOWN_INACTIVE ~(3<<3) /*register value to configure pin so that the internal pull-up/pull-down resistors are not active*/



int main(void)
{

 // System clock settings
 LPC_SYSCTL->PDRUNCFG &= ~(POWER_CON_SYSOSC); ///Power-up System Osc
 LPC_SYSCTL->PDRUNCFG &= ~(1<<4); /*ADC powered*/

 LPC_SYSCTL->SYSOSCCTRL &= ~(BYPASS); /*system oscillator control register: Oscillator is not bypassed, frequency range is 1 - 20 MHz*/
 LPC_SYSCTL->SYSOSCCTRL &= ~(FREQRANGE);

 /*configure pll to give 48MHz clock output*/
 LPC_SYSCTL->SYSPLLCTRL = PLL_CTRL_CONFIG;
 LPC_SYSCTL->PDRUNCFG &= PLL_ON;

 /*wait for pll lock*/
 while(!(LPC_SYSCTL->SYSPLLSTAT & PLL_LOCK))
 {
 /*do nothing*/
 }

 /*connect main clock to pll output*/
 LPC_SYSCTL->MAINCLKSEL |= CLK_SEL_PLLOUT;
 LPC_SYSCTL->MAINCLKUEN = FALSE; /*Toggle enable for setting to take effect*/
 LPC_SYSCTL->MAINCLKUEN = TRUE;


 /*enable clock to required peripherals*/
 LPC_SYSCTL->SYSAHBCLKCTRL |= IOCON_CLK_EN ///enable clock to IOCON
                  | USB_CLK_EN ///enable clock to USB

                   | GPIO_CLK_EN ///enable clock to GPIO

                   | TIMERS_CLK_EN ///enable clock to timers

                   | PINT_CLK_EN ///enable clock to pin interrupts

                   | SSP0_CLK_EN ///enable clock to SSP0

                   | ADC_CLK_EN; ///enable clock to ADC



 //GPIO settings
 LPC_IOCON->PIO0[1] &= 0;
 LPC_IOCON->PIO0[1] |= (0x02<<3); /*internal pull up resistor*/

 /// USB_VBUS config
 LPC_IOCON->PIO0[3] |= (1 << 0);  /// Set up of PIO0_3 register to USB_VBUS
 LPC_IOCON->PIO0[3] &= (1 << 0);  /// and inactive pull-up/pull-down resistors
 LPC_GPIO->DIR[0] |= PIO0_17_D5_LED; /// Port 0 - pin 17 LED


 while(1)
 {
  for (int j = 0; j < 1000000; j++);
  LPC_GPIO->SET[0] |= PIO0_17_D5_LED; /*Pin high initially so LEDs are On*/
  for (int j = 0; j < 1000000; j++);
  LPC_GPIO->CLR[0] |= PIO0_17_D5_LED; /*Pin low so LEDs are off*/
  for (int j = 0; j < 1000000; j++);
  Chip_IAP_ReinvokeISP();
 }

}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Regarding the use of Flash Magic, you can indeed use it to update the firmware. With respect to TeraTerm, I just mentioned it because you can use it (just like the terminal that Flash Magic has) to send the "?" that allows you to have the ISP Synchronization. With this you can confirm that your board has entered ISP mode:

pastedImage_1.png

It is important to mention that I used the LPC11U68 evaluation board (OM13058) with only the JP2 jumpers connected.

I hope this information can help you.

Ricardo Delsordo.

1,497 Views
davidyun
Contributor II

Firstly, to your question, I used periph_flashiap project from the LPCOpen and replaced its main function with yours. It didn’t work. I was expecting CRP DISABLD drive to appear in my PC but only USB Device Not Recognized message appeared. I used same board as you, the LPC11U68 evaluation board (OM13058).

 

Now, please could you answer my questions below I would be very grateful:

  1. Is it possible for LPC11U68JBD48 to go into the ISP mode at runtime? What I mean with the ISP mode is that CRP DISABLD drive can appear in a PC. 
    It does seem to be working but with my board it seems to go into the ISP mode only if there is delay less than 600ms at the start up. If I add some delay (3 seconds) and then call Chip_IAP_ReinvokeISP() this function, it does not work.

  2. Do I need a USB-RS232 cable in order to use Flash Magic? If so, this won’t be feasible as our customer won’t have this cable. This is why we are developing a PC application which could send a usb command to the LPC microcontroller, then the LPC micro could go into the ISP mode at runtime. Would this be possible?
     
  3. I also checked my code with the LPC11U68 evaluation board (OM13058), and it seems to be working fine. Could you please check that CRP DISABLD drive can appear in a PC when you go into the ISP mode rather checking with Flash Magic? 

  4. I understand that it would be difficult to examine my problem as you don’t have my board and schematic but could you think of anything why my board it seems to go into the ISP mode if there is delay less than 600ms at the start up, but not with the delay (3 seconds) 

  5. Could you possibly give me a quick guideline how to use Flash Magic as I haven’t used this before? Would this be useful to debug the ISP mode?

    Many thanks for your support. 
    David
0 Kudos

1,497 Views
nxf51211
NXP Employee
NXP Employee

Hi David,

1. It is possible to enter ISP mode during run time. In order for the computer to recognize the board as a MSC device, pin P0_3 must be high when calling Reinvoke ISP just like it shows in the following booting flow chart:

pastedImage_1.png

2. If you want to use USB ISP then you don't need to use Flash Magic and neither a USB-RS232 cable. When you are in USB ISP mode you can easily drag and drop your new firmware to the MSC device in your PC. Please consider that when using USB ISP, the user code valid signature must be either part of the vector table, or the axf (or binary) file must be post-processed to insert the checksum.

Regarding your second question from this point, it's possible, but your application in the MCU will need to recognize this command in order to call the function Re-Invoke ISP.  

3. Thank you so much for clarifying this. I've already checked on my side, and when I call Reinvoke ISP and have P0_3 high I'm able to see the LPC as a MSC device (CRP DISABLD).

4. The delays shouldn't affect the ISP mode at all. You have to keep in mind that when you call the function Reinvoke ISP your pin P0_3 has to be high. For the development board OM13058, this pin is connected to VBUS on the J3 connector, so when you connect a cable to this connector this pin goes to high immediately. Please check this connection on your board.

pastedImage_12.png

5. Since you want to use USB_ISP, the use of Flash Magic is no longer necessary. Flash Magic is a good tool only when you want to use I2C_ISP, SPI_ISP or UART_ISP.

I hope this can answer your questions.

Best Regards,

Ricardo Delsordo

1,497 Views
davidyun
Contributor II

Thank you very much, Ricardo. Much appreciated. Your response is really helpful.

I have further questions following your answers.

  1. It is good to know that it is possible to enter ISP mode during run time.

    My following question is that how to get USB ISP (CRP DISABLD) once the user code is running from the diagram below? Pin P0_3 seems to be checked during the boot process after the reset. What about after entering the user code?

    Also, Pin P0_3 is always high once powered. Calling Reinvoke ISP seems to be working, but if I configure USB, it does no longer work. I have tested this with LPC11U68 evaluation board.

    pastedImage_1.png
  2. Could you please use usbd_rom_hid_generic project from the LPCOpen and try to go into the USP ISP (CRP DISABLD)? I tried it by simply adding the code below in the while (1) loop in main function. I used the LPC11U68 evaluation board (OM13058). It doesn’t work.
    As you said, P0_3 should be high once I connect a cable to the connector, so I don’t need to drive the pin P0_3. Is there anything else I need to set before calling Chip_IAP_ReinvokeISP() function?

    while (1) {

                  Chip_IAP_ReinvokeISP();

     

                  __WFI();

              }

  3. On your answer to question 2, could you please explain what it means with the user code valid signature must be either part of the vector, or the axf (or binary) file musht be post-processed to insert the checksum. How can I achieve these?

Many thanks for your support. 
David

0 Kudos

1,497 Views
davidyun
Contributor II

Thank you very much Ricardo. Much appreciated your consistent support. Indeed, it works with NVIC_DisableIRQ(USB0_IRQn). Previously I used __disable_irq();, then it didn't work. Do you know why?

Could you explain what Chip_IAP_ReinvokeISP() function does? When this function is called from the user code, how is microprocessor put into the boot loader? The above boot process diagram doesn't have details how it works from the user code. Please see my mark in read in the diagram.

 

In order to operate Chip_IAP_ReinvokeISP() function, what is required in terms of what a peripheral clock is required and any other things?

Many thanks,

David

0 Kudos

1,497 Views
nxf51211
NXP Employee
NXP Employee

Hi David,

1. The __disable_irq() function doesn't work because you need to disable all NVIC interrupts before being able to access ISP mode; if you check the usbd_rom_hid_generic LPCOpen project you can see that the NVIC Interrupt for the USB0 is enabled (that is why you need to disable it first).

2. The Chip_IAP_ReinvokeISP() function just sends the IAP command 57 (decimal) which invokes the bootloader in ISP mode (by accessing the ROM). By sending this IAP command, the device maps boot vectors, sets PCLK = CCLK,  configures UART pins and TXD, resets counter/timer CT32B1 and resets the USART0 FDR; in other words, the device re initializes itself to enter ISP mode when the function is called (so if you check the boot process diagram, you can see that you have to go through a reset in order to access the ISP). For more information, I recommend you check the LPC11U6x User Manual (Chapter 27).

3. In order to operate the Chip_IAP_ReinvokeISP() function you don't need to set anything, you just have to count with the iap entry functions (you can check this by accessing the iap.c/iap.h library inside your project). I tried this by calling the Reinvoke before anything else inside the main function, and was able to enter the ISP mode with no problems.

I hope this information can help you.

Ricardo Delsordo

0 Kudos