Flash Programming

In the AVR DA family, the Flash accesses are handled through the NVM controller. This means that each part (in blocks of 32 KB) of the Flash area is mapped into data space by utilizing the NVMCTRL.CTRLB register and the erase and write operations are handled by utilizing the NVMCTRL.CTRLA register.

The current implementation of the bootloader uses program memory space to access the entire Flash. The addressing is done using LPM/SPM instructions.

The Flash is erased by page and is written with word granularity when it is mapped in the program memory space. To write a word, the page that contains the respective word address must be previously erased, otherwise the result will be an AND between the existing value and the new one.

The current implementation of the bootloader assumes that the write address is incremented step-by-step, so the Flash Page Erase (FLPER) command is sent via the NVMCTRL.CTRLA register when the write address enters a new page. To effectively start the erase operation, a dummy write to the selected page needs to be executed:

    
if((addr_flash % MAPPED_PROGMEM_PAGE_SIZE) == 0x0000)                         //new page 
{
              /* Wait for completion of previous command */
              while (NVMCTRL.STATUS & NVMCTRL_FBUSY_bm)
              {
                  ;
              }
              /* Clear the current command */
              _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_NONE_gc);

              /* Erase the flash page */
              _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_FLPER_gc);

              /* Dummy write to start erase operation */
              pgm_word_write(flash_addr, 0x00);
}
Note: A change from one command to another must always go through the No Command (NOCMD) or No Operation (NOOP). Otherwise, the Command Collision error will be set in the ERROR bit field in the NVMCTRL.STATUS register and the current command will not be executed.

The write operation is initiated by writing a Flash Write Enable (FLWR) command into the NVMCTRL.CTRLA register. After this command, multiple byte writes are allowed to the selected page locations, as long as no other command is written into the NVMCTRL.CTRLA register.

              /* Enable flash Write Mode */
		_PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_FLWR_gc);

              /* Program flash word with desired value*/
		pgm_word_write((flash_addr & 0xFFFFFE), data_word);