EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Writing to Flash LPC2106

Started by Ananda Regmi September 17, 2009
Hello,

I am trying to write a block of 512 bytes of data to flash in LPC2106. For
some reason it only writes a first couple of bytes. After the write
operation, it does return FLASH_CMD_SUCCESS. Anyone have any idea why would
it do that.

Here's the my flash write function:

Uint32 FlashDriver_write_configuration(FlashDriver * this)
{
Uint8 memmap;
Uint32 cpsr;

cpsr = disableINTs(); // disable all interrupts
memmap = SCB_MEMMAP; // get current memory map
SCB_MEMMAP = MEMMAP_FLASH; // map User Flash into low 64
bytes

// prepare sectors 14 for programing
flashParams[0] = 50; // prepare sectors
flashParams[1] = 14; // start sector
flashParams[2] = 14; // end sector
callIAP();

if (flashParams[0] != FLASH_CMD_SUCCESS)
{
SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts
return flashParams[0];
}

flashParams[0] = 51; // copy RAM to Flash
flashParams[1] = (Uint32)CURRENT_CONFIGURATION_ADDRESS; // destination
flashParams[2] = (Uint32)this->flash_interface->configuration_data; //
source
flashParams[3] = 512; // byte count
flashParams[4] = CCLK/1000; // CCLK in KHz
callIAP();

SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts

if (flashParams[0] != FLASH_CMD_SUCCESS)
return (Uint32)flashParams[0];
return FLASH_CMD_SUCCESS;
}


An Engineer's Guide to the LPC2100 Series

--- In l..., Ananda Regmi wrote:
>
> Hello,
>
> I am trying to write a block of 512 bytes of data to flash in LPC2106. For
> some reason it only writes a first couple of bytes. After the write
> operation, it does return FLASH_CMD_SUCCESS. Anyone have any idea why would
> it do that.
>
> Here's the my flash write function:
>
> Uint32 FlashDriver_write_configuration(FlashDriver * this)
> {
> Uint8 memmap;
> Uint32 cpsr;
>
> cpsr = disableINTs(); // disable all interrupts
> memmap = SCB_MEMMAP; // get current memory map
> SCB_MEMMAP = MEMMAP_FLASH; // map User Flash into low 64
> bytes
>
> // prepare sectors 14 for programing
> flashParams[0] = 50; // prepare sectors
> flashParams[1] = 14; // start sector
> flashParams[2] = 14; // end sector
> callIAP();
>
> if (flashParams[0] != FLASH_CMD_SUCCESS)
> {
> SCB_MEMMAP = memmap & 0x03; // restore the memory map
> restoreINTs(cpsr); // restore all interrupts
> return flashParams[0];
> }
>
> flashParams[0] = 51; // copy RAM to Flash
> flashParams[1] = (Uint32)CURRENT_CONFIGURATION_ADDRESS; // destination
> flashParams[2] = (Uint32)this->flash_interface->configuration_data; //
> source
> flashParams[3] = 512; // byte count
> flashParams[4] = CCLK/1000; // CCLK in KHz
> callIAP();
>
> SCB_MEMMAP = memmap & 0x03; // restore the memory map
> restoreINTs(cpsr); // restore all interrupts
>
> if (flashParams[0] != FLASH_CMD_SUCCESS)
> return (Uint32)flashParams[0];
> return FLASH_CMD_SUCCESS;
> }
>
>
There are some flash routines in the Files folder here on Yahoo:
http://f1.grp.yahoofs.com/v1/QJWySlr_yvxjdJklebY2UnP7JT20oxXmxeznIyh5AtcPGvveaaijGKmoDC2lAVHBUgtAHdL5lAz8IcTfi-9xlB52Cg_5f8WkodbMRUtkK1g4gA/LPC-FlashRoutines-18Feb05.zip

There are a lot of other code samples there as well.

There is LPC2148 code at www.jcwren.com/arm that should work on the 2106 as well.

Richard

Thanks for your reply Richard!

My code worked just the way it is when I erased the sector before writing
it. Is it necessary to erase the whole sector before it is possible to write
to it?

I am writing 512 bytes starting at 0x1C000, which is also the start of the
14th sector. But this sector is bigger than 512 bytes and right now I only
using the first 512 bytes of this sector. So, I don't mind erasing the whole
sector before writing to it. But what if I had data there.

Here's final code that works:

Uint32 FlashDriver_write_configuration(FlashDriver * this)
{
Uint8 memmap;
Uint32 cpsr;

cpsr = disableINTs(); // disable all interrupts
memmap = SCB_MEMMAP; // get current memory map
SCB_MEMMAP = MEMMAP_FLASH; // map User Flash into low 64
bytes

// prepare sectors 14 for programing
flashParams[0] = 50; // prepare sectors
flashParams[1] = 14; // start sector
flashParams[2] = 14; // end sector
callIAP();

if (flashParams[0] != FLASH_CMD_SUCCESS)
{
SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts
return flashParams[0];
}
flashParams[0] = 52; // erase sector(s)
flashParams[1] = 14;
flashParams[2] = 14;
flashParams[3] = CCLK/1000; // CCLK in KHz
callIAP();
if (flashParams[0] != FLASH_CMD_SUCCESS)
{
SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts
return flashParams[0];
}

// prepare sectors 14 for programing
flashParams[0] = 50; // prepare sectors
flashParams[1] = 14; // start sector
flashParams[2] = 14; // end sector
callIAP();
if (flashParams[0] != FLASH_CMD_SUCCESS)
{
SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts
return flashParams[0];
}

flashParams[0] = 51; // copy RAM to Flash
flashParams[1] = (Uint32)CURRENT_CONFIGURATION_ADDRESS; // destination
flashParams[2] = (Uint32)this->configuration_data; // source
flashParams[3] = 512; // byte count
flashParams[4] = CCLK/1000; // CCLK in KHz
callIAP();

SCB_MEMMAP = memmap & 0x03; // restore the memory map
restoreINTs(cpsr); // restore all interrupts

if (flashParams[0] != FLASH_CMD_SUCCESS)
return (Uint32)flashParams[0];
return FLASH_CMD_SUCCESS;
}

Regards,
Ananda

On Thu, Sep 17, 2009 at 2:20 PM, rtstofer wrote:

> --- In l... , Ananda Regmi
> wrote:
> >
> > Hello,
> >
> > I am trying to write a block of 512 bytes of data to flash in LPC2106.
> For
> > some reason it only writes a first couple of bytes. After the write
> > operation, it does return FLASH_CMD_SUCCESS. Anyone have any idea why
> would
> > it do that.
> >
> > Here's the my flash write function:
> >
> > Uint32 FlashDriver_write_configuration(FlashDriver * this)
> > {
> > Uint8 memmap;
> > Uint32 cpsr;
> >
> > cpsr = disableINTs(); // disable all interrupts
> > memmap = SCB_MEMMAP; // get current memory map
> > SCB_MEMMAP = MEMMAP_FLASH; // map User Flash into low 64
> > bytes
> >
> > // prepare sectors 14 for programing
> > flashParams[0] = 50; // prepare sectors
> > flashParams[1] = 14; // start sector
> > flashParams[2] = 14; // end sector
> > callIAP();
> >
> > if (flashParams[0] != FLASH_CMD_SUCCESS)
> > {
> > SCB_MEMMAP = memmap & 0x03; // restore the memory map
> > restoreINTs(cpsr); // restore all interrupts
> > return flashParams[0];
> > }
> >
> > flashParams[0] = 51; // copy RAM to Flash
> > flashParams[1] = (Uint32)CURRENT_CONFIGURATION_ADDRESS; // destination
> > flashParams[2] = (Uint32)this->flash_interface->configuration_data; //
> > source
> > flashParams[3] = 512; // byte count
> > flashParams[4] = CCLK/1000; // CCLK in KHz
> > callIAP();
> >
> > SCB_MEMMAP = memmap & 0x03; // restore the memory map
> > restoreINTs(cpsr); // restore all interrupts
> >
> > if (flashParams[0] != FLASH_CMD_SUCCESS)
> > return (Uint32)flashParams[0];
> >
> >
> > return FLASH_CMD_SUCCESS;
> > }
> >
> >
> >
> > There are some flash routines in the Files folder here on Yahoo:
>
> http://f1.grp.yahoofs.com/v1/QJWySlr_yvxjdJklebY2UnP7JT20oxXmxeznIyh5AtcPGvveaaijGKmoDC2lAVHBUgtAHdL5lAz8IcTfi-9xlB52Cg_5f8WkodbMRUtkK1g4gA/LPC-FlashRoutines-18Feb05.zip
>
> There are a lot of other code samples there as well.
>
> There is LPC2148 code at www.jcwren.com/arm that should work on the 2106
> as well.
>
> Richard
>
>
>


--- In l..., Ananda Regmi wrote:
>
> Thanks for your reply Richard!
>
> My code worked just the way it is when I erased the sector before writing
> it. Is it necessary to erase the whole sector before it is possible to write
> to it?

Table 160 in the User Manual says the data length should be 512, 1k, 4k or 8k and must start on a 512 byte boundary.

If you have data in the sector, copy it to your RAM buffer and reprogram the entire sector.

Richard

Memfault Beyond the Launch