How to write_page_buffer to page address greater than 64k?

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

I'm trying to adapt a bootloader so that it's compatible with AVR's with >64k program flash. The function for writing buffer to flash shown below.

This function works fine as long as the AVR has less than 64k flash. If it has greater the 64k it wraps and starts writing from x0000 ('page' address overflows). 

I know this is because the boot_page_write address is a byte address, so the 16 bit byte address can only point up to 64k.

In the code below 'page' can only be an unit16.  Is it as simple as adding a 'page' offset when it gets to 65535 and setting RAMPZ before the boot_page_write function?

 

/*********Atmel Studio 6 avr-gcc w/ AT90USB1286***************/

 

inline void write_buffer_to_flash()
{
    
    uint16_t i;
    const uint8_t* p = rx_buffer; //index of 257, will write whole page at once 
    eeprom_busy_wait();

    boot_page_erase(page);
    boot_spm_busy_wait(); //wait for page erase

    for (i = 0; i < SPM_PAGESIZE; i += 2)// bytes
    {
        uint16_t w = *p++; //flash divided in words
        w |= (*p++) << 8;//fills LSB first and shifts 
         boot_page_fill(page + i, w);//fill the write buffer
    }

    boot_page_write(page);
    
    boot_spm_busy_wait();
    boot_rww_enable();
}

Last Edited: Sun. May 15, 2016 - 12:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The boot.h has extended versions of the flash macros for devices with FLASHEND > USHRT_MAX (i.e. > 64K). These use 32-bit addresses.

A bootloader for the AT90USB1286 I use writes into a buffer where the first word is the page address and then the data for that page:

union {
	uint16_t Words[129];
	uint8_t  Bytes[258];
} SRAM_Data_Buffer;

and accesses that data as:

            PageAddress = SRAM_Data_Buffer.Words[0];	// Get the Page Address (16-bit) for the Flash write
                
            if (PageAddress == 0xFFFF) {		// Is it the code to Jump-to-Application?
                Jump_Application_flag = 1;
            } else {
                PageAddress32 = ((uint32_t)PageAddress << 8);
                boot_page_erase(PageAddress32);	        // Erase the FLASH page
                boot_spm_busy_wait();			// Wait till erase complete
                        // Fill the temporary FLASH page buffer from SRAM
                for (uint8_t PageWord = 0; PageWord < (SPM_PAGESIZE / 2); PageWord++) {
                    boot_page_fill(PageAddress32 + ((uint16_t)PageWord << 1), SRAM_Data_Buffer.Words[PageWord+1]);
                }
                boot_page_write(PageAddress32);	// Write the temporary page buffer to FLASH
                boot_spm_busy_wait();	        // Wait till write complete
                boot_rww_enable();		// Re-enable RWW section
            }

 

David (aka frog_jr)