Xmega Application Note


flash_write_example.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00050 /* Define flash memory and page size of target MCU */
00051 #define APP_END 0x40000
00052 #define FLASH_PAGE_SIZE 512 //Bytes
00053 
00054 #include "sp_driver.h"
00055 
00056 
00057 /* Temporary storage used for NVM-workaround. */
00058 uint8_t sleepCtr;
00059 uint8_t statusStore;
00060 uint8_t pmicStore;
00061 uint8_t globalInt;
00062 uint8_t spmintStore;
00063 
00064 /* SPM wakeup interrupt */
00065 ISR(NVM_SPM_vect)
00066 {
00067         /* Disable the SPM interrupt */
00068         NVM.INTCTRL = (NVM.INTCTRL & ~NVM_SPMLVL_gm);
00069         /* Restore sleep settings */
00070         SLEEP.CTRL = sleepCtr;
00071         /* Restore PMIC status and control registers */
00072         PMIC.STATUS = statusStore;
00073         PMIC.CTRL = pmicStore;
00074         /* Restore SPM interruptsettings */
00075         NVM.INTCTRL = spmintStore;
00076         /* Restore global interrupt settings */
00077         SREG = globalInt;
00078         return;
00079 }
00080 
00081 /* Set interrupt vector location to boot section of flash */
00082 void PMIC_SetVectorLocationToBoot( void )
00083 {
00084         uint8_t temp = PMIC.CTRL | PMIC_IVSEL_bm;
00085         CCP = CCP_IOREG_gc;
00086         PMIC.CTRL = temp;
00087 }
00088 
00089 /*Set interrupt vector location to application section of flash */
00090 void PMIC_SetVectorLocationToApplication( void )
00091 {
00092         uint8_t temp = PMIC.CTRL & ~PMIC_IVSEL_bm;
00093         CCP = CCP_IOREG_gc;
00094         PMIC.CTRL = temp;
00095 }
00096 
00097 /* Save register settings before entering sleep mode */
00098 void Prepare_to_Sleep( void )
00099 {
00100         sleepCtr = SLEEP.CTRL;
00101         /* Set sleep mode to IDLE */
00102         SLEEP.CTRL =  0x00; 
00103         /* Save the PMIC Status and control registers */
00104         statusStore = PMIC.STATUS;                                                              
00105         pmicStore = PMIC.CTRL;          
00106         /* Enable only the highest level of interrupts */                                                                       
00107         PMIC.CTRL = (PMIC.CTRL & ~PMIC_HILVLEN_bm) | PMIC_HILVLEN_bm;
00108         /* Save SREG for later use */
00109         globalInt = SREG;
00110         /* Enable global interrupts */
00111         sei();
00112         /* Save SPM interrupt settings for later */ 
00113         spmintStore = NVM.INTCTRL;
00114 }
00115 
00116 /* New function declarations used for the NVM-workaround */
00117 void EraseApplicationPage(uint32_t address)
00118 {
00119         /*Set the correct settings and store critical registers before NVM-workaround*/
00120         Prepare_to_Sleep();
00121         /*Assembly "function" to preform page erase*/
00122         SP_EraseApplicationPage(address);
00123 }
00124 
00125 void EraseWriteApplicationPage(uint32_t address)
00126 {
00127         /*Set the correct settings and store critical registers before NVM-workaround*/
00128         Prepare_to_Sleep(); 
00129         /*Assembly "function" to preform page erase-write*/
00130         SP_EraseWriteApplicationPage(address);
00131 }
00132 
00133 void ClearFlashBuffer(void)
00134 {
00135         /*Set the correct settings and store critical registers before NVM-workaround*/
00136         Prepare_to_Sleep(); 
00137         /*Assembly "function" to erase flash buffer*/
00138         SP_EraseFlashBuffer();
00139 }
00140 
00141 void LoadFlashWord(uint32_t address, uint16_t word)
00142 {
00143         /*Set the correct settings and store critical registers before NVM-workaround*/
00144         Prepare_to_Sleep();   
00145         /*Assembly "function" to load flash buffer*/
00146         SP_LoadFlashWord(address, word);
00147 }
00148 
00149 
00152 int main(void)
00153 {
00154         /* Assume success until proven otherwise. */
00155         bool success = true;
00156         PMIC_SetVectorLocationToBoot();
00157         /* Fill the entire application section of the flash memory with bogus data */
00158         for (uint32_t address = 0; address < APP_END; address+=FLASH_PAGE_SIZE) {
00159         
00160                 /* Load flash buffer with data */
00161                 ClearFlashBuffer(); //Clear the flash buffer first to avoid data corruption
00162                 for (uint16_t i = 0; i < FLASH_PAGE_SIZE; i += 2) {
00163                         uint8_t lowByte = i;
00164                         uint8_t highByte = i+1;
00165                         
00166                         LoadFlashWord((uint32_t)i, ((uint16_t) highByte << 8) | lowByte);
00167                         SP_WaitForSPM();
00168                 }
00169                 
00170                 /* Perform erase-page write. */ 
00171                 EraseWriteApplicationPage(address);
00172         }
00173         
00174         /* Check if data is written correctly */
00175         for (uint32_t address = 0; address < APP_END; address++)
00176         {
00177            if(SP_ReadByte(address) != (uint8_t)address) success = false;
00178         }
00179         
00180         /* Allow for breakpoint to check the value of "success". */
00181         if (success) {
00182                 while(true){
00183                         nop();
00184                 }
00185         } else {
00186                 while(true){
00187                         nop();
00188                 }
00189         }
00190 }
@DOC_TITLE@
Generated on Wed Sep 2 10:55:21 2009 for AVR1008: Writing EEPROM and Flash in ATxmega256A3 / ATxmega256A3B - Rev B by doxygen 1.5.9