AVR32 UC3C 2512 - Flash Address calculation not producing intended results

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, the other day I implemented an option to save settings persistent in Flash. I used the ASF Framework and wrote at the userPage.
Now I want to store a bit more data (it doesn't fit into the userpage anymore, so I want to split the data into pieces and to maintain a certain order and aesthetics, I want to write each chunk beginning at the start of one page; Instead of emulating a cross-page-border write). Thats the theory so far.

 

I use the following code:

 

void test_writeNormalFlashPage(uint32_t*data, uint16_t wordcount, uint32_t destinationAddr)
{
    flashc_clear_page_buffer();
    uint32_t *psrc, *pdest ;
    uint8_t timeout = 0;
    
    psrc = (void*) (&(data[0]));
    pdest = (void*) destinationAddr ;
    while (wordcount--)
    {
        *pdest++ = *psrc++ ;
    }
    
    destinationAddr -= 0x80000000;
    while(!flashc_erase_page(destinationAddr/64,true) && timeout < 250)
    {
        timeout++;
    }
    
    if(timeout >= 250)
    {
        return;
    }
    
    flashc_write_page(destinationAddr/64);      
    while(!flashc_is_ready());
}

 

void test_readNormalPageFlash(uint32_t* result, uint16_t wordcount, uint32_t fAddress)
{
    uint32_t* source = (void*) fAddress;
    uint32_t* desti = result;
    
    while (wordcount--)
    {
        *desti++ = *source++;
    }
    
}

The Datasheet states the following:
 

Writing to an address A in the flash memory map will not update the
flash memory, but will instead update location A%64 in the page buffer. The PAGEN field in the
Flash Command (FCMD) register will at the same time be updated with the value A/64.

A page buffer writes a whole page, so if modulo 64 is used, the page size must be 64. PAGEN stores the index of the page, since it is 64 in size, the address is generated by dividing by 64. But if I choose a destination address 0x80001E00 (so 0x1E00 / 0x40 = 0x78) and issue a flash-write command, my data ends up at address 0x8000F000!

Why is my calculation incorrect? Or is something else fishy here?

 

All informations were gathered with the Atmel Studio debugger.

 

update: the "destinationAddr -= 0x80000000;" is obsolete, since the bits that would make the value too high are masked by hardware.

[insert smart signature here]

Last Edited: Wed. Apr 19, 2017 - 01:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Alright. I solved it... for all of the future viewers. The datasheet is wrong, it should go like "A%512" (depending on Variant of MCU) and "A/512".
Also, it is important to look for the reserved Flash. If you happen to target this zone, nothing will happen at all.

 

[insert smart signature here]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is a misleading example in that datasheet.
The correct page-size is given in the Physical Memory Map near the front of the datasheet and in the Module Configuration section at the end of the FLASHC module.
You could also read and decode the FLASHC PR register to obtain the page size at run-time.
I prefer to use the ASF #defines such as AVR32_FLASHC_PAGE_SIZE and AVR32_FLASHC_FLASH_SIZE and AVR32_FLASH_ADDRESS