Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: FLASH write issue
PostPosted: Tue Apr 17, 2012 11:38 am 
Offline

Joined: Tue Mar 13, 2012 5:19 pm
Posts: 12
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:
#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:
   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[i] = 0xFF != args->data[i] for i <0,255>

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

Regards
Entik


Top
 Profile  
 
 Post subject: Re: FLASH write issue
PostPosted: Tue Apr 17, 2012 3:45 pm 
Offline

Joined: Fri Mar 09, 2012 1:34 pm
Posts: 68
Hi!
Check my files for programming FLASH in topic: http://www.at91.com/forum/viewtopic.php ... 34/#p36434

_________________
Best regards
Przemyslaw Baranski


Top
 Profile  
 
 Post subject: Re: FLASH write issue
PostPosted: Tue Apr 17, 2012 11:20 pm 
Offline

Joined: Tue Apr 03, 2012 3:34 pm
Posts: 9
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:
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.


Top
 Profile  
 
 Post subject: Re: FLASH write issue
PostPosted: Wed Apr 18, 2012 3:36 pm 
Offline

Joined: Tue Mar 13, 2012 5:19 pm
Posts: 12
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


Top
 Profile  
 
 Post subject: Re: FLASH write issue
PostPosted: Wed Apr 18, 2012 5:02 pm 
Offline

Joined: Tue Apr 03, 2012 3:34 pm
Posts: 9
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: