EEFC page programming

I'm trying to write to pages using the EEFC on the SAM3X.

I've successfully managed to write and read lock-bits using code like the following.

EFC0->EEFC_FCR = (0x5A << 24) | 0x0A;
while (!EEFC_FSR_FRDY) {
}
Serial.print("FRR: ");
Serial.println(EFC0->EEFC_FRR);

If I read the flash descriptor using

EFC0->EEFC_FCR = (0x5A << 24) | 0x00;

I am informed that there is 1 plane of 256kB of memory. Each page is 256 bytes and there are 16 lock bits covering 16384 bytes (64 pages) each.

Isn't the SAM3X meant to have two planes of 256kB for a total of 512kB?

Nevertheless, using these figures I calculated that 0xBE800 should correspond to the 1000th page (0x3E8).

pp = (uint32_t*)0xBE800;
*pp++ = 0xFF00FF00;
*pp++ = 0xFF00FF00;
*pp++ = 0xFF00FF00;
*pp++ = 0xFF00FF00;
EFC0->EEFC_FCR = (0x5A << 24) | ( 0x3E8 << 8 ) | 0x03;

The Arduino hangs.
But upon reboot... success! The page of flash was written correctly.
If I try using EEFC1, the Arduino remains responsive but the page is not written.

I have come to the conclusion that I must use the IAP function stored in the ROM.

How to call this, I am unsure.

The example given in the datasheet passes it two arguments. The EEFC ID (0 or 1) and the contents to write to the EEFC_FCR register.
However, the description of the function specifies it only takes one argument.

In any case, I am unable to call it successfully. The Arduino simply hangs.

Perhaps there is some way to run a function from ram.

Ok... so, I've ditched the Arduino IDE and moved back to Atmel Studio 6.
The IDE causes all sorts of issues/conflicts that I can never figure out.

I can now call the IAP function using the exact same code I was trying to use in the Arduino IDE.

I am successfully programming the flash.

I now have two unanswered questions.

  • Why can I not call the IAP function using the Arduino IDE?
  • Why am I getting only one plane of 256kB when I retrieve the flash descriptor?
    (Should I not be getting 2x256kB?)

I was intending on setting the boot flag for flash0/flash1 to jump to/from a bootloader.

Scradam,

using EEFC to write flash has some troubles that are not reported in the datasheet (I've obtained such informations directly from Atmel and by looking the source code from ASF):

  1. You should execute code from SRAM during writes (the official reason is that the flash "page" you're writing could contain the code that is currently running)

  2. You must disable interrupts during writes (to avoid the chance of executing ISR code in flash memory for the same reason of 1)

  3. Flash page buffering-before-write should be done 32-bit at a time (you can't write one byte at a time for example... wrong writes happens)

  4. FWS (Flash Wait States) register should be set to 6 (look at the errata corrige at the end of the datasheet)

I'm writing a Flash library to use in Arduino IDE that take cares of all the above here:

If you need to set GPNVM bit the method:

SAM3X8E_EEFC::void command(Commands cmd, uint16_t arg)

may could be of any help for you.

WARNING the library is not finished yet, the API will change and its a totally Untested Solution™

C

I am aware of and have considered those four points. They're all pretty clearly stated in the datasheet.
Thanks, though.

My Due is reporting only one plane of 256kB. Strange.

I've seen that there are two EEFCs inside the CPU, and they reports 256KB each (I checked this some weeks ago btw, may I didn't remember well...).