Content originally posted in LPCWare by diederichs on Sat Feb 16 11:20:31 MST 2013
I need some help with the SPIFI on the LPC4357.
We have a project that has an advanced Boot Loader executing from SPIFI. The Boot Loader in our project is capable of distributing firmware images to several areas including other sections of the SPIFI, IROM and other external devices. We are now attempting to have the Boot Loader update itself.
We already have a scatter file that places all of the Boot Loader application code into SRAM and we are successfully executing from there. We can successfully erase the SPIFI section containing the Boot Loader startup code and continue to execute. However, because the spifi_drv_M4.lib requires ARM ABI compatibility the attempt to write the new code using the spifi_program (SPIFIobj *obj, char *source, SPIFIopers *opers) crashes. Inside the spifi_program() call, it hangs on an attempt to execute __aeabi_memcpy4 which of course is no longer there. Just to absolutely clear here… our scatter file places spifi_drv_M4.lib in SRAM but the compiler has placed ABI commands in the startup ROM (spifi) after the code from our startup_LPC43xx.s file.
To attempt to get around this problem I have tried to enforce the relocating of all ABI functions to SRAM but have failed to figure out how to do it. I repeat that we have already placed the spifi_drv_M4.lib in SRAM.
I have also attempted to write to the SPIFI in command mode using the register definitions provided in Rev. 1.6 of the user manual. Here is my attempt:
static SPIFIobj obj; // The SPIFI interface is configured by the provided library prior to calling this function.
int spifi_flash_ProgramBootLoader (unsigned int adr, unsigned int sz, unsigned char *buf)
{
unsigned int Fail = 0;
unsigned int Command;
unsigned int * d = (unsigned int *)buf;
// Limit the Size to a single page. Limited to 512 on our Spansion flash using command code 0x38.
if (sz > 512) return 1;
// Write a reset to the status register.
*(unsigned int volatile *)0x4000301C |= 0x10;
// Wait for hardware to be ready for command. It will clear the Reset bit.
while (*(unsigned int volatile *)0x4000301C & 0x10);
// Change to command mode.
// Write the address to the SPIFI address register
*(unsigned int volatile *)0x40003008 = adr;
// Create the command word. Obj is configured prior to this call using the spifi_init().
// It chose a command word of obj.prog_cmd = 0x38B008000
Command = obj.prog_cmd;
Command |= sz;
*(unsigned int volatile *)0x40003004 = Command;
// Write the bytes to the SPIFI data register.
while (sz--) *(unsigned int volatile *)0x40003014 = *buf++;
// Read the status until command complete.
while (*(unsigned int volatile *)0x4000301C & 0x10);
// Set SPIFI back to Memory Mode.
Fail |= spifi_init(&obj, 3, S_RCVCLK | S_FULLCLK, 32);
return(Fail);
}
We have tried a couple variations on this theme (including writing bytes and words to the SPIFI data register). None of the attempts has modified the SPIFI Flash contents.
Help is greatly appreciated.