AnsweredAssumed Answered

Update FW in QSPI flash from secondary bootloader in internal flash

Question asked by Klaas Hoekstra on Jul 12, 2019
Latest reply on Sep 6, 2019 by Klaas Hoekstra

Hello,

 

For a project I am writing a bootloader on an EA LPC4088 Display Module.
The firmware is running from QSPI flash and uses the external SDRAM.

 

I've written a bootloader in internal flash that uses the spifi rom api to update the firmware on the QSPI flash.

I first read the binary file of my firmware and then program it to QSPI flash per 4096 bytes.

Here is the code I use to program the QSPI flash:

 

SpifiError_t spifi_program(uint32_t address, uint8_t *data, uint16_t lenght)
{
   if (!_initialized) {
      return SpifiError_Uninitialized;
   }

   int rc;
   SPIFIopers opers;

   opers.dest = (char *) address;
   opers.length = lenght;
   opers.scratch = NULL; // unprogrammed data is not saved/restored
   opers.protect = -1; // save & restore protection
   opers.options = S_VERIFY_PROG;

   rc = _spifi->spifi_program (&_romData, (char *)data, &opers);
   if (rc) {
      return spifi_translateError(rc);
   }
   return SpifiError_Ok;
}

 

This all works as expected, and the binary file is copied to the QSPI flash.
However, when I try to jump to the QSPI flash, a hard fault is detected.
When I program the firmware to QSPI with the GUI flash tool in MCUXpresso and then start my bootloader, the jump to the QSPI works as expected.

 

This is the code to jump to the QSPI flash:

 

void Execute_Application(unsigned address)
{
   pFunction appEntry;
   uint32_t appStack;

   appStack = (uint32_t) *((__IO uint32_t*) address);

   appEntry = (pFunction) *(__IO uint32_t*) (address + 4);

   __disable_irq(); // Disable interrupts before changing interrupt vectors

   SCB->VTOR = address;

   __set_MSP(appStack);

   __enable_irq();

   appEntry();
}

 

Can somebody tell me what I am missing and why the firmware will not execute when I program the QSPI flash though the bootloader?
Thank you in advance!

Outcomes