Wednesday, February 18, 2015

NXP LPC8xx EEPROM emulation

Screen grab from terminal of demo showing
the reprogramming of a byte in 'EEPROM'
(actually a page in flash memory).
Summary: The NXP LPC8xx series of MCU lack traditional EEPROM capability to preserve settings across power cycles, but this functionality can be emulated using in-application flash programming. I've written a demo program to show this in operation.

The LPC8xx series is a popular range of of ARM Cortex-M0 MCUs from NXP. One feature that I find indispensable is the ability to preserve settings across power cycles.

Many MCUs feature a small EEPROM bank for this purpose. But the LPC8xx does not have EEPROM. However it does allow the flash memory to be reprogrammed in 64 byte pages from within the application. This can be used to emulate EEPROM functionality.

I found an example [1] which worked after some initial trouble [2]. The example however fails to address one important question: how to allocate a space in flash that's safe to read/write for this purpose.

I posted a query to stackexchange.com [3] and received a few good suggestions on how to achieve this. One suggestion was to use the uppermost flash page. However that required prior knowledge as to the particular part being used (LPC810 has 4kB flash, LPC812 16kB etc). An alternative suggestion which I preferred was to use this:

const uint8_t eeprom_flashpage[64] __attribute__ ((aligned (64))) = {0};

This is probably specific to the GCC compiler, but other compilers will have an equivalent for directing a 64 byte alignment of the allocation. I found the "={0}" assignment necessary, otherwise the array was allocated in RAM.

I implemented all this in a little demo program which has been tested on a LPC812, but should work on all LPC8xx series of MCU. You can find the code on GitHub: https://github.com/jdesbonnet/LPC8xx_Flash_EEPROM/

Flash vs EEPROM

There are some downsides to using flash. First, it does wear out eventually (as does EEPROM, but EEPROM endurance is typically an order of magnitude greater than flash: (in the order of 100 kcycles vs 10 kcycles). [4]

The other problem which can be seen in the screen shot above: a whopping 101ms to complete a write. That's forever! (typically EEPROMs have write times in the order of a few milliseconds). What happens if the power fails during a write? (I actually don't know!)

References:

[1]  http://www.lpcware.com/content/forum/eeprom-emulation

[2] I was initially attempting to test by writing some constants defined in the program (and therefore were stored in flash). The iap_copy_ram_to_flash() function must receive the source data from RAM. Flash to flash copy is not possible during this operation. Ref UM10601 22.5.2.2 Copy RAM to flash (IAP).

[3]  http://electronics.stackexchange.com/questions/153424/how-to-automatically-allocate-a-page-of-flash-for-in-application-storage-of-sett

[4] The LPC81XM datasheet, section 12.1 specifies flash endurance typically at 100 kcycles, erase time for 64 bytes typically 100ms and write time for 64 bytes typically 1ms.

3 comments:

Anton Veretenenko said...

There is a technique to use circular buffer to make flash endurance like or better than of eeprom. I saw it earlier in msp430 application notes, take a look
http://processors.wiki.ti.com/index.php/Emulating_EEPROM_in_MSP430_Flash

But this technique requires to use several flash bytes just for emulating single eeprom byte.

faststoff said...

I am very late to the party, but I'll try my luck:

How do you control the exact flash location that the eeprom_flashpage gets located at?
Your print-out example shows that it is located from address 0x0DC0 (ie. page 55, if I am not mistaken) - but how did it end up exactly there? Is there some linker directive in the background somewhere or did the compiler simply allocate it to a section it did not use? I tried looking into the github project, but I did not bet any wiser. Thanks in any case for a great write-up :)

faststoff said...

I am very late to the party, but I'll try my luck:

How do you control the exact flash location that the eeprom_flashpage gets located at?
Your print-out example shows that it is located from address 0x0DC0 (ie. page 55, if I am not mistaken) - but how did it end up exactly there? Is there some linker directive in the background somewhere or did the compiler simply allocate it to a section it did not use? I tried looking into the github project, but I did not bet any wiser. Thanks in any case for a great write-up :)