PIC24 and EEPROM

by kacang bawang

If you’re reading this, chances are you are in the same boat I was in before writing this text – I wanted to save some data to EEPROM on a PIC24F and … it doesn’t have one. (The manual claims that PIC24F has EEPROM, but that is not fully so – only select models, namely PIC24F___K_, do). What to do? Well, there is this nice lib (AN1095) from Microchip that implements software EEPROM. The lib is well written, lots of docs, but alas – it does not run out of the box. This post is about the additional steps that it took to get it running.

Before going further, let me state the equipment that I am using.

Chip: PIC24FJ256GB206
IDE: MPLabX 2.30
Debugger: PickIt3

The problem one is faced with after first trying to use the software EEPROM code is this – the written data does not survive a cold reset (but works as expected until then).

The cause of the problem is the programmer/debugger. It erases our EEPROM while reprogramming the chip (which happens every time we start a new debug session). Let’s see why.

Here is the line of code that declares the array that holds the EEPROM data (line 117 from eeprom_emu.c):

The compiler creates the following sections in the program memory (numbers given are specific to my project)

This results in a randomly named section being created an inserted somewhere in the middle of the program data (compiler selects placement). Well, you will want to debug your program sometime, right? Just know that PickIt3 erases all pages that house the code, so if something is placed in their midst (such as, oh I don’t know, an EEPROM section), it also gets erased. Ok, no problem, we’re smart – we know that under Project Properties -> PickIt3 we can set the range of flash addresses to be programmed. We select some settings that look like this (using some example numbers):

Program: 0x0 – 0x7fff <—– the higher this value, the longer it takes to program
Protect: 0x2c00 – 0x33ff

Unfortunately that won't work. The protected section does not get protected if it is placed in the middle of program range. Further experiments showed that the protected range has to be at the end, like this:

Program: 0x0 – 0x7fff
Protect: 0x2c00 – 0x7fff

This means that:
1. We have to somehow place our EEPROM array at the end of program memory.
2. We have to specify (and keep updating as the program grows/shrinks) the erasure area.

Above creates upkeep headaches, but, having EEPROM is more important to us, so let's keep going. First we need to tell the compiler to reserve our array memory a little differently:

The additional options give our data section (it ends up in its own section) a readable name, and we manually specify the program memory offset (0x8000 in our case) where the allocation will begin. I suppose the aligned attribute is not necessary anymore, but I left it just in case I make a typo in the address.

The new section table looks like this:

With this setup your data should survive between debug sessions at the expense of having to micromanage its location.