Self programming flash on SAM4

Discussion around product based on ARM Cortex M4 core.

Moderators: nferre, ncollot

Posts: 11
Joined: Mon Sep 08, 2014 7:38 pm

Self programming flash on SAM4

Mon Sep 08, 2014 8:00 pm


I'm trying to program flash from a bootloader, using the IAP commands in ROM, but don't understand how you actually program the values in to flash.

It looks to me like it's reasonably straightforward, once you'd correct the myriad mistakes in the code in the datasheet to use the function at address 0x00800008 by calling:

flash_status = IAP_Function (EFCIndex, flash_cmd);

And making the flash_cmd up to write the correct value into FCR.

At least it's easy to see how you'd send, say, an erase command because the FARG part of that register requests a start page and the number of pages to erase.

However, to program the flash, there seems to be no way of passing the address to program or the value. I could understand it if you had to program a poade, passed the page into FARG and there was a register where you wrote a pointer to the first value to write.

The arcane code in the asf seems to suggest that you just do a memcpy from RAM to flash, but if that is the case it would seem pointless to have the write command passed into the FARG of the FCR.

Actually, re-reading the flash_write function in flash_efc.c I'm not sure hat the three memcpy things do at all, because there seems to be writing to flash with this piece of code:

Code: Select all

for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / sizeof(uint32_t)); ++ul_idx) 
			*p_aligned_dest++ = gs_ul_page_buffer[ul_idx];
Do you have to write to flash addresses, then write correct values into the FCR to actually accomplish the writing? Does the act of doing that make the code wait until the writing has finished?

This is the first time I have found ST's documentationn to be better than Atmel's. All does not seem well with the world! :shock:

Yours confusedly!

Posts: 238
Joined: Thu Dec 06, 2012 6:40 am

Re: Self programming flash on SAM4

Mon Sep 08, 2014 11:11 pm

Yes, its a little bit confusing, but there are clues in the data sheet.

This is from the SAM4S data sheet
One write buffer that manages page programming. The write buffer size is equal to the page size. This buffer
is write-only and accessible all along the 1 MByte address space, so that each word can be written to its final
and also see section Commands for detailed information on how this works, there are specifics (like only writing 32 bit values, etc...)

So when writing data to the internal flash, you first load the "Write (latch) Buffer" by writing data to the page you want to update. (at this time the data is not written) You then send the command to program, this is when the data in the "Write (latch) Buffer" will be programmed into the flash.
NOTE: writes are 1 page in size, (you *can* do partial page programming, but there are rules associated with this, see the data sheet). So if you have data you want to preserve you must read the page into a buffer, update the bits you want to change then write the buffer back to the page (this puts it into the "Write latch buffer"), then you follow this with the command to write the data, (you should use the erase then write command).

Hope i didn't confuse the issue further :)

Or you could just use the ASF code ;)

Posts: 11
Joined: Mon Sep 08, 2014 7:38 pm

Re: Self programming flash on SAM4

Tue Sep 09, 2014 10:14 am

No, that's not confused me further. Au contraire! :) Many thanks!

(Wish they'd explained it like that in the Safe and Secure bootloader apps note!)
Posts: 11
Joined: Mon Sep 08, 2014 7:38 pm

Re: Self programming flash on SAM4

Tue Sep 09, 2014 12:18 pm

Afraid I need to ask a further question. My ciode is like this:

Code: Select all

  FlashPageNumber = Address/512;
    DestinationAddress = (uint32_t *)Address;
    for (i=0;i<512;i++) 
        *DestinationAddress++ = *Data++;
    IAP_Function = (unsigned int (*)(unsigned long))0x00800008;
    flash_cmd =  (0x5A << 24) | (FlashPageNumber << 8) | EFC_FCMD_EWP;
    /* Call the IAP function with appropriate command */
    flash_status = IAP_Function (EFCIndex, flash_cmd);
However, it crashes with a hardfault as soon as I call:

Code: Select all

    flash_status = IAP_Function (EFCIndex, flash_cmd);
I was advised on stack overflow that this line:

Code: Select all

    IAP_Function = (unsigned int (*)(unsigned long))0x00800008;
Which in the datasheet as below and did not compile:

Code: Select all

IAP_Function = ((unsigned long) (*)(unsigned long))
Should have a set of parentheses removed as IAP_Function was just being set to a pointer to 0x00800008. However, it's this line that is crashing, so I am now doubting that advice.

There is a line of assembley code:

Code: Select all

blx r3
R3 contains 0x00800008 and once it attempts to execute that pice of machine code it crashes.

0x00800008 does contain something (0x00800E2D).

Also, that address as far as I can see is in the middle of normal code space, not ROM. The datsheet seems to indicate you need to jump to the contents of that address. However, the datasheet is so clearly completely incorrect I'm now doubting everything it says.

Anyone got a piece of [non-ASF] working code or know what uis going on here please?

Thanks! :)
Posts: 7
Joined: Wed Aug 13, 2014 12:06 pm

Re: Self programming flash on SAM4

Wed Sep 24, 2014 10:50 am

I dont know about your problem but I think the command EFC_FCMD_EWP is not support in sam4 MCU.

Return to “SAM4 Cortex-M4 MCU”

Who is online

Users browsing this forum: No registered users and 1 guest