SAM3S4C FlashWrite resets PC

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

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

SAM3S4C FlashWrite resets PC

Tue Mar 04, 2014 4:51 pm

Hi all,
I am programming a bootloader - well described topic here in the forums. I wanted to try to program and read back single page first, but I encountered a problem, that during the flash write command execution, PC is set to 0x00000000.
The program receives 256B of data via serial port, and writes it to the very last page of flash memory. For the flash access itself, I tried both IAP and RAM func

Page number and other constants are defined

Code: Select all

#define AT91C_IFLASH                        (0x00400000)
#define IFLASH_NB_OF_PAGES           	(1024)
#define FLASH_STORE_PAGE		(IFLASH_NB_OF_PAGES-1)
#define IFLASH_PAGE_SIZE              	(256)
For the function calls, page = FLASH_STORE_PAGE.

IAP

Code: Select all

uint8_t FLASH_DoEFCCommand(uint32_t page, uint8_t cmd)
{
	uint32_t f_status, f_cmd;
	static uint32_t (*IAP_PerformCommand)(uint32_t,uint32_t);
	
	DisableInterrupts();
	
	IAP_PerformCommand = (uint32_t (*)( uint32_t, uint32_t ))*((uint32_t*)CHIP_FLASH_IAP_ADDRESS );
	
	f_cmd = ((EEFC_FCR_FKEY & (0x5A << 24)) | (EEFC_FCR_FARG & (page << 8)) | (EEFC_FCR_FCMD & cmd));

	f_status = IAP_PerformCommand(0,f_cmd);

	EnableInterrupts();

	return (f_status & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));	
}
RAM func

Code: Select all

uint8_t FLASH_DoEFCCommand(uint32_t page, uint8_t cmd)
{
	uint32_t res;
	
	DisableInterrupts();

	EFC->EEFC_FCR = ((EEFC_FCR_FKEY & (0x5A << 24)) | (EEFC_FCR_FARG & (page << 8)) | (EEFC_FCR_FCMD & cmd));

	res = EFC->EEFC_FSR;
	while ( (res & EEFC_FSR_FRDY) != EEFC_FSR_FRDY )
	{
		res = EFC->EEFC_FSR;	
	}

	EnableInterrupts();	

	return (res & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE));
}
located in pe_efc.c and scatter file

Code: Select all

LR_IROM1 0x00400000 0x00040000  {    ; load region size_region
  ER_IROM1 0x00400000 0x00040000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }  
  RW_IRAM1 0x20000000 0x0000C000  {  ; RW data
   pe_efc.o
   .ANY (+RW +ZI)
  }
}
Regarding the whole write sequence, I unlock the page (EFC_FCMD_CLB 0x09), write the page to "latch buffer" to address

Code: Select all

flashPageBuffer = (uint32_t *)(AT91C_IFLASH + page*IFLASH_PAGE_SIZE);
erase and write (EFC_FCMD_EWP 0x03) and lock again (EFC_FCMD_SLB 0x08).

I am using flash wait cycles FWS = 6 (accoridng to some note in manual errata), but I have tried anything from 0x2 to 0xE(14).

What happens is that when using IAP, unlocking goes well, but PC is set to 0 when erasing and writing the page. With RAM func, PC is reset in random one of the 3 operations. Strange thing is that when I am debugging the RAM func code, there is a fair chance that the PC is not zeroed when going over the flash access code line by line. That would point to some delay problem, but I have no idea what might help.

Information that might be useful
The flash page, if the PC is zeroed in/after erase and write operation, is actually written. When I reset the uP and read the flash page, previously written content is there.
J-LINK throws this line and pauses code execution every time the PC is zeroed
**JLink Warning: T-bit of XPSR is 0 but should be 1. Changed to 1.

Thanks for any ideas
Entik
ankit.parikh
Posts: 1
Joined: Wed Jul 30, 2014 3:01 am

Re: SAM3S4C FlashWrite resets PC

Wed Jul 30, 2014 3:03 am

Hello,

Any update on this problem. I am experiencing the same issue. I have also logged a bug with the Atmel team.

You can find the bug here
http://asf.atmel.com/bugzilla/show_bug.cgi?id=3469

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

Re: SAM3S4C FlashWrite resets PC

Wed Aug 20, 2014 2:57 pm

Based on the ankit.parikh conversation with Atmel guys, I have found a solution to this, so I am posting it here, just in case somebody has the same problem.

PC is set to 0x00 (among other cases) when the EFC is working with memory, interrupt occurs and instruction is about to be fetched from flash.

So the problem lies in my DisableInterrupts(); function. I figured out that this implementation is not sufficient

Code: Select all

NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
Following function call did the trick

Code: Select all

__disable_irq();
Entik
eng.mmostafa80
Posts: 29
Joined: Sat Nov 26, 2011 10:20 am

Re: SAM3S4C FlashWrite resets PC

Mon Aug 25, 2014 4:27 pm

I had the same problem.
and I used also __disable_irq(); and __enable_irq(); around the write command.
It worked well for a while but the problem happened again without changing to the code.

do you have any other ideas for this?

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: No registered users and 3 guests