Entering ISP from user code

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

Entering ISP from user code

1,408 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MX21 on Mon Jan 03 11:26:49 MST 2011
I'm having problems entering and exiting ISP from user code with my LPC1114.

I have a device that plugs into a serial port on a PC. I want to have the user plug in the device, then run my PC application to load new code, and have the device restart and function without them having to hold a button or install a jumper and reset to get in and out of ISP.

I use the IAP function 57 to to get into ISP from user code:

#define IAP_LOCATION 0x1FFF1FF1
typedef void (*IAP)(unsigned int [], unsigned int[]);
IAP iap_entry;
void ISP_Enter(void)
{
 unsigned long command_IAP[5];
 unsigned long result_IAP[4];
 iap_entry = (IAP)IAP_LOCATION;
 command_IAP[0] = 57;
 iap_entry(command_IAP, result_IAP);
}


This successfully puts the chip in ISP mode. I can then send the "?" character and it responds with "Synchronized", but when I send "Synchronized" back, it does not respond any further.

Also, if I get into ISP by holding the ISP pin low at startup, then load a program, if I send "G 0 T<cr>" to start the user program, it runs, but the serial port doesn't work. I have to do a hard reset again for it to fully function.

Seems like something is quirky with serial I/O when using ISP from user code. Anyone else getting into / out of ISP mode successfully?

Thanks,

MX
0 Kudos
Reply
7 Replies

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by acno on Wed Aug 10 05:26:38 MST 2011

Quote: MX21
I'm having problems entering and exiting ISP from user code with my LPC1114.
....................
Seems like something is quirky with serial I/O when using ISP from user code. Anyone else getting into / out of ISP mode successfully?

Thanks,

MX



  I'm a bit late, but this application note covers the problem:
http://ics.nxp.com/support/documents/microcontrollers/pdf/an11015.pdf
0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jush on Mon Apr 11 00:51:49 MST 2011
Hi,

I don't know if this is the right thread to ask, since your talking about ISP, i have something wanted to clarify.
How the bootloader run during the program execution?Does this is been triggered by an interrupt handler?
As what happened in on-chip rom driver it has an USB_IRQHandler that points to driver table.

Thanks.
0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MX21 on Mon Mar 28 09:56:58 MST 2011
Thanks, your solution works great!


Quote: curtvm
[SIZE=4]I have my own little 40pin dip adapter with a lpc1114 mounted (and micro sd slot), using a cheapo serial usb-ttl adapter.[/SIZE]

[SIZE=4]I have been messing around with the bootloader, and created a little code to reset back to the app from the bootloader. The code-[/SIZE]
[FONT=Fixedsys][SIZE=2][COLOR=black]test_reset:[/COLOR][/SIZE][/FONT]
[SIZE=2][FONT=Fixedsys][COLOR=black]   ldr r0,aircr[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   ldr r1,aircr_val[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   str r1,[r0][/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   //dsb[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   1:[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   b 1b[/COLOR][/FONT][/SIZE]
 
[SIZE=2][FONT=Fixedsys][COLOR=black]   .balign 4[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   aircr:[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   .word 0xE000ED0C[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   aircr_val:[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]   .word 0x05FA000[/COLOR] 4[/FONT][/SIZE]
[SIZE=4]which then was uuencoded. I can now reset into the app via these commands-[/SIZE]
[FONT=Fixedsys][COLOR=black][SIZE=2]W 268435456 16[/SIZE][/COLOR][/FONT]
[SIZE=2][FONT=Fixedsys][COLOR=black]0`4@"20%@_N<,[0#@!`#Z!0``[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]1462[/COLOR][/FONT][/SIZE]
[SIZE=2][FONT=Fixedsys][COLOR=black]G 268435456 T[/COLOR][/FONT][/SIZE]
[SIZE=4]The code is written to ram (0x10000000), then simply executed (Go).[/SIZE]

[SIZE=4]Seems to work ok. Not sure why DSB is used in the cmsis version, but until I understand why its required, I'll leave it out. I'm sure it doesn't hurt to include it, but I would rather understand why its required first- maybe I'll find out.[/SIZE]

[SIZE=4]Other methods could be used of course. Like changing the linker script, putting the reset code in a specific address, then 'G'oing to the code (in the app just programmed). Instead of changing the linker script, one could also put the reset code into the ".isr_vector" section which would put the code right after the vector table (fixed address), but may not be a good idea as the possibility exists for the linker to order the isr_vectors section backwards. Or one could modify the isr vector array to include the reset code either inside (reserved word locations has enough space), or add to the end of the table. In either case there would be a known address to 'G'o to.[/SIZE]

0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by curtvm on Sun Jan 09 08:05:41 MST 2011
[SIZE=4]I have my own little 40pin dip adapter with a lpc1114 mounted (and micro sd slot), using a cheapo serial usb-ttl adapter.

I have been messing around with the bootloader, and created a little code to reset back to the app from the bootloader. The code-[/SIZE]
[FONT=Fixedsys][SIZE=2][COLOR=Black]test_reset:
    ldr r0,aircr
    ldr r1,aircr_val
    str r1,[r0]
    //dsb
    1:
    b 1b

    .balign 4
    aircr:
    .word 0xE000ED0C
    aircr_val:
    .word 0x05FA000[/COLOR] 4[/SIZE][/FONT]
[SIZE=4]which then was uuencoded. I can now reset into the app via these commands-[/SIZE]
[FONT=Fixedsys][COLOR=Black][SIZE=2]W 268435456 16
0`4@"20%@_N<,[0#@!`#Z!0``
1462
G 268435456 T[/SIZE][/COLOR][/FONT]
[SIZE=4]The code is written to ram (0x10000000), then simply executed (Go).

Seems to work ok. Not sure why DSB is used in the cmsis version, but until I understand why its required, I'll leave it out. I'm sure it doesn't hurt to include it, but I would rather understand why its required first- maybe I'll find out.

Other methods could be used of course. Like changing the linker script, putting the reset code in a specific address, then 'G'oing to the code (in the app just programmed). Instead of changing the linker script, one could also put the reset code into the ".isr_vector" section which would put the code right after the vector table (fixed address), but may not be a good idea as the possibility exists for the linker to order the isr_vectors section backwards. Or one could modify the isr vector array to include the reset code either inside (reserved word locations has enough space), or add to the end of the table. In either case there would be a known address to 'G'o to.
[/SIZE]
0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MX21 on Wed Jan 05 09:18:06 MST 2011
Good points.  I'm using the NVIC_SystemReset() function in my code already, so if  I could specify a fixed address for that function, I could then use "G <fixed address> T" force a reset.

Thanks,

MX



Quote: curtvm
I'm not an expert, but I think you are mistaken that a 'go' to address 0 will do anything useful. Address 0 holds the address of the initial sp value, so who knows what happens when trying to execute that address. Address 0x4 holds the reset address, but you can't just 'go' to that either. I am assuming that a 'go' command will actually load the pc with the value given, and set bit0 if the 't' option is given.

I would guess you could go a couple ways- either 'read memory' of the reset vector, then 'go' to that address.

Or if you want a 'true' reset, compile a function using NVIC_SystemReset() , get the compiled code for that function (a one time thing), write that code to ram, then 'go' to that ram address.

I don't know what state the 'go' command leaves behind, but a true reset would leave no doubt about what the state of the lpc is in when your code starts.

I could be wrong.

0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by curtvm on Tue Jan 04 13:44:19 MST 2011
I'm not an expert, but I think you are mistaken that a 'go' to address 0 will do anything useful. Address 0 holds the address of the initial sp value, so who knows what happens when trying to execute that address. Address 0x4 holds the reset address, but you can't just 'go' to that either. I am assuming that a 'go' command will actually load the pc with the value given, and set bit0 if the 't' option is given.

I would guess you could go a couple ways- either 'read memory' of the reset vector, then 'go' to that address.

Or if you want a 'true' reset, compile a function using NVIC_SystemReset() , get the compiled code for that function (a one time thing), write that code to ram, then 'go' to that ram address.

I don't know what state the 'go' command leaves behind, but a true reset would leave no doubt about what the state of the lpc is in when your code starts.

I could be wrong.
0 Kudos
Reply

1,102 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MX21 on Mon Jan 03 14:02:24 MST 2011
[COLOR=#1f497d][FONT=Calibri]Fixed the first part – I can get into ISP ok now. Found there was an interrupt still enabled. Once I made sure they were all off, it goes into ISP and loads. Still can’t get from ISP back to normal operation yet. [/FONT][/COLOR]

[FONT=Calibri][COLOR=#1f497d]So for completeness, here's my isp.c file that successfully jumps into ISP mode:[/COLOR][/FONT]

#include "LPC11xx.h"/* LPC11xx definitions */
 
#define IAP_LOCATION 0x1FFF1FF1
 
typedef void (*IAP)(unsignedint [], unsignedint[]);
 
IAP iap_entry;
 
void ISP_Enter(void)
{
    unsigned long command_IAP[5];
    unsigned long result_IAP[4];
 
    __disable_irq();
 
    iap_entry = (IAP) IAP_LOCATION;
 
    command_IAP[0] = 57;
 
    iap_entry(command_IAP, result_IAP);
}


[LEFT]The __disable_irq() call is in the LPCXpresso CMSIS code.[/LEFT]

[LEFT][COLOR=#1f497d][FONT=Calibri]MX[/FONT][/COLOR][/LEFT]
0 Kudos
Reply