How can I boot to LPC55 to BOOT ROM from firmware code? Previous method doesn't work

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

How can I boot to LPC55 to BOOT ROM from firmware code? Previous method doesn't work

Jump to solution
5,397 Views
cp1
Contributor III

I'm trying to get the LPC55 to enter the bootloader from application code.  I previously tried this solution which edits the `BOOTERRORCOUNTER` of the AOREG1 register.  This solution did work on my LPCXpresso55S69, but it does not work on my custom PCB with new LPC55 chips.

On the LPCXpresso (device revision marked "1"), it works and boots to BOOT ROM just fine.

On custom PCB (chip revision marked "1B"), it just boots the application again. 

In both cases I confirmed that BOOT ROM works/boots after mass erasing the flash.  I also figured out I could erase the first flash page from application code and reset, which results in BOOT ROM booting, but this is problematic since now the application needs to be reprogrammed.

Would there be a difference between chip revisions in how the boot rom handles `BOOTERRORCOUNTER` in AOREG1 register?  How else can I boot the BOOT ROM from application code (without erasing application)?

Labels (1)
1 Solution
4,507 Views
cp1
Contributor III

Actually I just solved this.

The trick is to set the INVERT attribute for Pio0_5 (ISP pin), and then jump to the bootrom without any soft reset.  The bootrom will think the ISP pin is asserted when it's not.

To do this safely, I used the following steps.

 1. Reset all peripherals & disconnect all interrupts (like in a soft reset)
2. Enable Iocon and set the INVERT attribute for Pio0_5 (ISP pin).
3. Jump to bootrom, which will think ISP pin is asserted.

Basically just repeat everything in a soft reset, but setting the INVERT attribute right before jumping.

My implementation is here: https://github.com/lpc55/lpc55-hal/pull/51/files

View solution in original post

15 Replies
2,551 Views
R3t0
Contributor II

Hi

I did a lot of tests with your solutions, here is my conclusion:

  • runbootloader() does not work for Rev-ID 1B
  • Chips with Rev-ID 1B and production date older than 2021 do not support entering ISP boot from application
  • For Chips with Rev-ID 1B and production date 2021 onward there is the following workaround according to Errata sheet LPC55S2x/LPC552x Rev. 2.2 Chapter 5.1:
    PMC->AOREG1 |=(0X0A <<16);
    NVIC_SystemReset();

I have also checked with NXP support as my chip has a production date of 2019 (Rev-ID 1B). I have no choice but to make the PIO0_5 accessible.
Because I do not have a chip with production date 2021 onward I could not test the workaround.

Regards, Reto

Tags (2)
0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi cp@solokeys.com

I'm glad to help, but I will require additional time to provide my feedback.

Please, stay tuned to my following reply. 

Best regards, Diego.

4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi cp@solokeys.com,

Using the LPC55s69 rev 1B,

I´ve been checking the following code  to  run the bootloader from application using UART as interface.

#define BOOTLOADER_TREE_LOCATION (0x1301fe00)
bootloader_tree_t *romApiTree = (bootloader_tree_t *)BOOTLOADER_TREE_LOCATION;
uint32_t arg = 0xEB120000; //0xEB: represents Enter Boot; 0x12: represents enter ISPmode by UART only

....

void runBootloader(void *arg)
{
romApiTree-> runBootloader(arg);
}

.... bootloader Tree structure can be found driver  fsl_iap.c

Code obtained from LPC55 user manual 9.3.4 runBootloader API

You could try this on your own,

 I'll look forward validating this method for the revision.

Best regards, Diego.

4,918 Views
cp1
Contributor III

Hi Diego,

Thanks a lot for your reply.  Turns out I was using the October manual release which missed this information.

I tried this solution, and unfortunately it doesn't work.  All it does is trigger a reboot and start the application normally again.  I've found a number of problems, and confirmed via disassembly that "runBootloader" only does a soft reset, and nothing else.

The "0x1301fe00" in the RM points to zero-valued memory on device, so it is probably incorrect.  The address used in the 2.7.1 SDK "0x130010f0" for the BOOTLOADER_TREE_LOCATION seems right (see flashiap1/drivers/fsl_iap.c). (also this 0x130010f0 is referenced elsewhere in the RM).

Using the 0x130010f0 address for the BOOTLOADER_TREE_LOCATION location, it points to the following data, which I've readout.

Screen Shot 2020-05-04 at 1.06.10 PM.png

It seems to match to the "bootloader_tree_t" type correctly since I can see the version numbers and copyright string.  So "runBootloader" resides at address 0x13014939.

Looking at the disassembled code for the function at 0x13014939 though, it's a bit disappointing.  It takes no function parameters, and all it does is a normal system reset (using the ARM SCB module mapped at 0xe000ed04).

Screen Shot 2020-05-04 at 1.12.09 PM.png

Basically, it just writes 0x5fa0004 to SCB->AIRCR, and then goes into a infinite loop, which is exactly how an ARM soft reset is done.

How else can I enter the bootloader?  Or what is the correct address for "runBootloader" if there is one?  This is all on the same 1B chip, and I've verified that bootloader mode works after mass-erase.

 

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hello, Conor

I'm checking this with the application team.

I will update you when I get the information.

Best regards, Diego

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi, Conor

We have results, but  I'm just waiting for confirmation. 

I'll keep you updated. 

Regards, Diego.

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi , Conor

 

For the LPC55S69 rev 1B there is no recommended way to reinvoke the bootloader from application code.

 

The  section 9.3.4 runBootloader API, that I proposed before,   was removed from  User manual  version 2.0 ( from 04 May 2020) due to incompatibility with the MCU. 

 

Sorry for the all the  inconvenience that this may generated.

 

Best regards, Diego.

0 Kudos
4,918 Views
cp1
Contributor III

Hi Charles,

Thanks for the reply.  The signed update mechanism is one of the core features my company is interested in the LPC55S69.  It's pretty strange if there's no way to update an existing application.  Can you check if the application team can provide a new 1B bootrom function that can be called to invoke the bootloader?

Thanks,

Conor

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi Connor,

It is possible to invoque the bootloloader from application code. However there is no recommended  workaround at the moment to use the rom bootloader API on rev 1B of the LPC55S69.   I'm waiting for confirmation from the applications team to see if is possible  to provide a similiar function.

Best regards, Diego.

4,918 Views
cp1
Contributor III

Thank you!  Also, if you can provide any other way to invoke the bootrom from application code, that would be great.  It doesn't need to use the bootrom API.

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi Conor,

I just wanted to provide you an update!

As soon  I get information I will let you know. Please, stay tuned for my following reply during the week.

Thank you for your  patience!

Best regards,

Diego.

0 Kudos
4,918 Views
diego_charles
NXP TechSupport
NXP TechSupport

Hi Connor,

 At the moment, there are no plans to provide a  function to re-invoke the  ROM bootloader from  firmware code in  the LPC55S69 rev 1B

Sorry for any inconvenience this may generated. 

Regards, 

Diego. 

4,539 Views
cp1
Contributor III

Hi Charles,

 

Hi hope you've been well.  I'm resurfacing this to check to see if there's been any update or changes on how to re-invoke the ROM bootloader from firmware code? 

My team is still just relying on erasing the flash and rebooting, and we're realizing this could risk issues with out customers.

Conor

0 Kudos
4,508 Views
cp1
Contributor III

Actually I just solved this.

The trick is to set the INVERT attribute for Pio0_5 (ISP pin), and then jump to the bootrom without any soft reset.  The bootrom will think the ISP pin is asserted when it's not.

To do this safely, I used the following steps.

 1. Reset all peripherals & disconnect all interrupts (like in a soft reset)
2. Enable Iocon and set the INVERT attribute for Pio0_5 (ISP pin).
3. Jump to bootrom, which will think ISP pin is asserted.

Basically just repeat everything in a soft reset, but setting the INVERT attribute right before jumping.

My implementation is here: https://github.com/lpc55/lpc55-hal/pull/51/files

4,442 Views
TwoBias
Contributor II

Hi,

thank you for sharing your solution. I have the same problem and i solved this with external hardware but your idea is more professional.

I inverted the pin, and set the clock to default (i read in an other thread) but the controller get stucked in an hardfault error.

Do you have a code snippet to jump to boot rom in MCUXpresso c-code?

I tried two codes i found in this forum with no success:

void (*runBootloader)(void);

void run_bootloader(void)
{
uint32_t runBootloaderAddress;

// Read the entry point from bootloader's vector table
runBootloaderAddress = *(uint32_t*)(0x03000000);
runBootloader = (void (*) (void))runBootloaderAddress;
runBootloader();
}

and this one nearly the same:

void boot_loader_start( void ) __attribute__ ((noreturn));

/* Function Pointer returning void, passed void pointer: */
void (*_boot_loader_start)( void * arg );

void boot_loader_start( void )
{
/* Read the function address from the ROM API tree: */
uint32_t const _boot_loader_start_address = **(uint32_t **)(0x03000000);

/* Turn address in to a function pointer: */
_boot_loader_start = (void (*)(void * arg))_boot_loader_start_address;
_boot_loader_start( NULL ); /* Call the function. Will not return from here */
for(;;) /* Pacify the compiler about returning from a no return function */
;
}

 

0 Kudos