lpcware

In-Application Programming Erase Sector Works Initially But Fails After Reboot (LPC1313)

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by mroe on Mon Aug 04 18:31:10 MST 2014
Hello,

I am trying to use IAP to store a variable in NV Flash RAM that will retain its state after reboot.
I am using my own linker script and storing the variable at location 0x6000 far away from anything else.
This the memory is being properly written to when I initially debug the application, but not after reboot.  After rebooting, the code crashes when I try to erase the iap sector before writing to it.

Here is the relevant portion of my iap code:
int iap_erase_sector(unsigned int sector_start, unsigned int sector_end)
{
    unsigned int command[5];
    unsigned int result[4];

    command[0] = ERASE_SECTOR; // 52
    command[1] = (unsigned int)sector_start;
    command[2] = (unsigned int)sector_end;
    command[3] = SystemCoreClock / 1000;
    iap_entry(command, result);

    return result[0];
}

int iap_prepare_sector(unsigned int sector_start, unsigned int sector_end)
{
    unsigned int command[5];
    unsigned int result[4];

    command[0] = PREPARE_SECTOR; // 50
    command[1] = (unsigned int) sector_start;
    command[2] = (unsigned int) sector_end;
    iap_entry(command, result);

    return result[0];
}

int iap_copy_ram_to_flash(void* ram_address, void* flash_address, unsigned int count)
{
    unsigned int command[5];
    unsigned int result[4];

    command[0] = COPY_RAM_TO_FLASH; // 51
    command[1] = (unsigned int)flash_address;
    command[2] = (unsigned int)ram_address;
    command[3] = count;
    command[4] = SystemCoreClock / 1000;
    iap_entry(command, result);

    return result[0];
}

int iap_write(void *ram_address, void *flash_address, unsigned int count, unsigned int sector, unsigned int sector_size)
{
   int iap_status = 0; // CMD_SUCCESS

    SystemCoreClockUpdate();

    iap_status = iap_prepare_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;

    // after reboot, this crashes when I try to erase the sector
    iap_status = iap_erase_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;

    iap_status = iap_prepare_sector(sector, sector_size);
    if (iap_status != 0) return iap_status;

    iap_status = iap_copy_ram_to_flash(ram_address, flash_address, count);
    if (iap_status != 0) return iap_status;

    return iap_status;
}

Here is the relevant section of my linker script:
    .var (0x6000) :
    {
        KEEP(*(.var*))
    } > MFlash32

Here is the relevant section of my calling code:

__CRP const unsigned int CRP_WORD = CRP_NO_CRP;

static unsigned char var_temp[] = {0, 1, 1, 1, 1, 1, 1, 1, 1};

__attribute__ ((section(".var"))) unsigned char var[256];

int main()
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 16);

if (var[0] == 0)
{
                // after reboot, this crashes when I try to erase the sector
                // iap_write(ram_address, flash_address, count, sector, sector_size)
iap_write(&var_temp, (void *)0x6000, 256, 6, 7);
}

while (1)
{
}

return 0;
}

Thanks in advance for your help.

Outcomes