FLASH write issue

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

entik
Posts: 17
Joined: Tue Mar 13, 2012 5:19 pm

FLASH write issue

Tue Apr 17, 2012 11:38 am

Hello,
my goal is to write a bootloader for SAM3S4C, which will sit on RS232 line, and write incoming data to flash. When finished, it should jump to newly written code. Problem is in flash writing section, all the functions return zero codes (meaning ok), but the flash remains untouched (0xFFFF.....).

I am using FLASHD_ functions from SAM3S ek, along with IAP, so all the code is run from FLASH (no scatter file alternations), excetp the hard coded IAP routines, which are in ROM. Mclk frequency is set to 64MHz, voltage 1.8V, flash wait cycles FWS = 2 (so 3 cycles).

Constants for flash access

Code: Select all

#define AT91C_IFLASH  (0x00400000) /**< Internal Flash base address */

#define IFLASH_SIZE 					0x40000
#define IFLASH_PAGE_SIZE              	(256) /* Internal FLASH 0 Page Size: 256 bytes */
#define IFLASH_LOCK_REGION_SIZE     	(16384) /* Internal FLASH 0 Lock Region Size: 16 Kbytes */
#define IFLASH_NB_OF_PAGES           	(1024) /* Internal FLASH 0 Number of Pages: 1024 */
#define IFLASH_NB_OF_LOCK_BITS         	(16) /* Internal FLASH 0 Number of Lock Bits: 16 */
#define IRAM_SIZE 						0xC000

#define AT91C_IFLASH_PROG  				(0x00404000)
The size of the compiled code is ~12kb, so it comfortably fits into the first lock region of flash - 16kB, 64 pages, address 0x00400000 - 0x00403FFF.

Code of FLASH write function

Code: Select all

	uint8_t err = 0;
	uint16_t i;
	uint32_t addr = AT91C_IFLASH_PROG + args->address*IFLASH_PAGE_SIZE;	
	volatile uint8_t* cpdata = (volatile uint8_t*) addr;
	
	
    err = FLASHD_IsSecurityBitSet();

	//unlock
	err += FLASHD_Unlock(addr,addr + IFLASH_PAGE_SIZE,0,0);
	//write
	err += FLASHD_Write(addr,args->data,IFLASH_PAGE_SIZE);

	//verify
	for ( i = 0; i < IFLASH_PAGE_SIZE; i++ )
	{
		err += (cpdata[i] != args->data[i]);
		if ( err )
		{
			break;
		}
	}

	//lock
	err += FLASHD_Lock(addr,addr + IFLASH_PAGE_SIZE,0,0);
So to sum it up, page address is 0, so I am trying to write to address AT91C_IFLASH_PROG = 0x00404000, 256bytes.
FLASHD_IsSecurityBitSet returns 0
FLASHD_Unlock and FLASHD_Write returns 0

cpdata = 0xFF != args->data for i <0,255>

I would appreciate any ideas about what I am doing wrong.

Regards
Entik
przemekbary
Posts: 68
Joined: Fri Mar 09, 2012 1:34 pm

Re: FLASH write issue

Tue Apr 17, 2012 3:45 pm

Hi!
Check my files for programming FLASH in topic: forum/viewtopic.php/t,20723/p,36434/#p36434
Best regards
Przemyslaw Baranski
ngoncalves
Posts: 9
Joined: Tue Apr 03, 2012 3:34 pm

Re: FLASH write issue

Tue Apr 17, 2012 11:20 pm

At first glance your code seems OK, but there is something bothering me. The flash memory accesses must double word aligned (read 4 bytes at a time). And in the for loop you are byte aligned accesses.

It does not explain why it does not write, but it is strange.

Also, I found it much easier not to used the library flashd functions and instead just call directly the IAP function. My code is something like this

Code: Select all

uint32_t *flashPageBuffer ; // start address where I will write to flash
uint8_t *data ;                        // 256 byte array of data to write

flashPageBuffer = (uint32_t *)(FLASH_START_ADDRESS + pageNr*FLASH_PAGE_SIZE)

// write to the flash internal buffer
for(c = 0 ; c < FLASH_PAGE_SIZE/4 ; c++)
   flashPageBuffer[c] = (((uint32_t)data[4*c + 0]) << 24) |
                                        (((uint32_t)data[4*c + 1]) << 16) |
                                        (((uint32_t)data[4*c + 2]) << 8)   |
                                        (((uint32_t)data[4*c + 3])) ; 

// write to flash
__disable_irq() ; 

// setup key, page ID and command on the EEFC command register

// call the IAP function

__enable_irq() ; 

This as worked like a charm every single time I have used it.
entik
Posts: 17
Joined: Tue Mar 13, 2012 5:19 pm

Re: FLASH write issue

Wed Apr 18, 2012 3:36 pm

Thank you guys for fast replies. It turned out that the problem is in IAP function, it is returning "ok" error code even if I try to write without unlocking the page lock region, so there is clearly something wrong.

I ended up writing my own set of EEFC control functions (if anyone is reading this to find help, they have to be moved to RAM through scatter file/compiler directive) and along with the ngoncalves code, it really did worked like a charm.

Thanks again :)
Entik
ngoncalves
Posts: 9
Joined: Tue Apr 03, 2012 3:34 pm

Re: FLASH write issue

Wed Apr 18, 2012 5:02 pm

I am glad that I could help.

For the error code, I look at the EEFC status register (EEFC_FSR), not the IAP return value.
entik wrote:Thank you guys for fast replies. It turned out that the problem is in IAP function, it is returning "ok" error code even if I try to write without unlocking the page lock region, so there is clearly something wrong.

I ended up writing my own set of EEFC control functions (if anyone is reading this to find help, they have to be moved to RAM through scatter file/compiler directive) and along with the ngoncalves code, it really did worked like a charm.

Thanks again :)
Entik

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: No registered users and 1 guest