Unable to write flash of ATmega2560 after 256 pages(64kB)

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

We are using avr/boot.h for writing the flash memory of ATmega2560 in our bootloader. With the boot_page_erase() ,boot_page_fill() or boot_page_write() functions we are able to write successfully to upto 256 pages but as soon as we try to write to pages beyond 256 the data is written again from page 0. We have made sure the address we are passing to the functions is 32-bit(uint32_t). Any help with this is highly appreciated.

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

Those functions are defined in boot.h with 3 possible options, if its using the 'normal' one for some reason on your >64k device, then you will not get rampz set. If rampz is not set, your address limit is 64k, which happens to be where you get the wrap-around (256*128*2).

 

You could verify in the asm listing that rampz is accessed for these inline asm functions, or you could just directly use the _extended versions of those inline asm functions. Once that is verified to work you can figure out why the correct version is not being selected from the #if/elif/else.

 

If its already using the rampz correctly, then I don't know.

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

curtvm wrote:

Those functions are defined in boot.h with 3 possible options, if its using the 'normal' one for some reason on your >64k device, then you will not get rampz set. If rampz is not set, your address limit is 64k, which happens to be where you get the wrap-around (256*128*2).

 

You could verify in the asm listing that rampz is accessed for these inline asm functions, or you could just directly use the _extended versions of those inline asm functions. Once that is verified to work you can figure out why the correct version is not being selected from the #if/elif/else.

 

If its already using the rampz correctly, then I don't know.

 

And these 3 possible options are...

 

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

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

>And these 3 possible options are...

find those functions in the boot.h file, they are defined 3 times depending on your which avr you have and what FLASHEND happens to be- you end up with _alternate, _extended, and _normal versions of the inline asm. The _extended version uses rampz, the _normal does not, and the _alternate is for a few specific avr's.

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

We forced it to use _extended still could not get it to work. Any other reasons why it couldn't get it to work

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

Well, then a new guess- you are not reading the flash correctly. The lpm instruction does not use rampz, the elpm does. If you wrote to to correct page, but then are reading the flash using the lpm version of pgm_read_something, you will be seeing the page0 data instead of the page256 data.

 

From pgmspace.h there is a _far version of pgm_read (I didn't take the time to figure out if this choice is 'automatic' depending on which avr is in use, but I don't think it is, so you would then need to specify).

 

Here is my simple test, which I just used to see what was happening (in the objdump produced assembly listing). I am using MPLABX, and cannot simulate it. The rampz is being set, and all looks ok until you don't use the _far version of pgm_read, then you see lpm being used which causes me to think that could be trouble if unaware.

#include <xc.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>

//-Wl,--section-start=.text=0x3F000
//${MP_CC_DIR}/../avr/bin/avr-objdump -d ${ImageDir}/${PROJECTNAME}.${IMAGE_TYPE}.elf > list.txt;

int main(void) {
    uint32_t page = 0x10000;
    boot_page_erase( page );
    boot_spm_busy_wait ();
    boot_page_fill ( page, 0 );
    boot_page_write ( page );
    boot_spm_busy_wait();
    if( 0 == pgm_read_word_far( 0x10000 ) ){ /*led on or something*/ }
    for(;;){}
}

 

I'm running out of guesses, and I doubt I can come up with any more.