Xmega Application Note


ATxmega256A3_EEPROM.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00050 #include "avr_compiler.h"
00051 
00052 #define PAGESIZE 32 //EEPROM page size
00053 
00054 
00055 void EEPROM_write_page (uint8_t * page, uint8_t page_no);
00056 
00057 /*
00058  * Please note that no other interrupts can have the highest
00059  * interrupt level than the EEPROM interrupt!
00060  */
00061 
00062 /* Interrupt handler for the EEPROM write "done" interrupt */
00063 ISR(NVM_EE_vect)
00064 {
00065         /* Disable the EEPROM interrupt */
00066         NVM.INTCTRL = (NVM.INTCTRL & ~NVM_EELVL_gm);
00067         return;
00068 }
00069 
00070 /*@main to test that the function works
00071 */
00072 int main (void)
00073 {
00074         uint8_t eeprom_page[PAGESIZE];
00075 
00076         /* Just create some data to put in the EEPROM */
00077         for(int i = 0; i < PAGESIZE; i++)
00078         {
00079                 eeprom_page[i] = i;
00080         }
00081         
00082         /* Call to the write page function */
00083         /* Write the contents of eeprom_page to EEPROM page nr. 2 */
00084         EEPROM_write_page(eeprom_page, 2);
00085         
00086         
00087         while(1){}      
00088 }
00089 /*@
00090 Function for writing a page to EEPROM while putting the device to sleep
00091 page: pointer to the first address of the page to be written
00092 page_no: which page number to write to EEPROM.
00093 */
00094 void EEPROM_write_page (uint8_t * page, uint8_t page_no)
00095 {
00096         /* Set the NVM command to load to the EEPROM buffer */
00097         NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
00098         
00099         /* Max buffersize is PAGESIZE, hence the upper addresses are not needed */
00100         NVM.ADDR2 = 0;
00101         NVM.ADDR1 = 0;  
00102 
00103         /* Load buffer with data */
00104         for(int i = 0; i < PAGESIZE; i++)
00105         {
00106                 /* Set the location where data is going to be put in the buffer */
00107                 NVM.ADDR0 = i;
00108                 /* Writing to the DATA register will trigger a write to the buffer */
00109                 NVM.DATA0 = page[i];
00110         }
00111         
00112         /* Load the NVM command with erase and then write EEPROM page */
00113         NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
00114 
00115         /* Calculate address */
00116         uint16_t address = (uint16_t)(page_no*PAGESIZE);
00117 
00118         /* Set address to write to. */
00119         NVM.ADDR0 = address & 0xFF;
00120         NVM.ADDR1 = (address >> 8) & 0x1F;
00121         NVM.ADDR2 = 0x00;
00122 
00123         /* Save the Sleep register */
00124         uint8_t sleepCtr = SLEEP.CTRL;
00125         /* Set sleep mode to IDLE */
00126         SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP.CTRL) | SLEEP_SMODE_IDLE_gc; 
00127         /* Save the PMIC Status and control registers */
00128         uint8_t statusStore = PMIC.STATUS;                                                              
00129         uint8_t pmicStore = PMIC.CTRL;          
00130         
00131         /* Enable only the highest level of interrupts */                                                                       
00132         PMIC.CTRL = (PMIC.CTRL & ~PMIC_HILVLEN_bm) | PMIC_HILVLEN_bm;
00133         /* Save SREG for later use */
00134         uint8_t globalInt = SREG;
00135         /* Enable global interrupts */
00136         sei();
00137         /* Set sleep enabled */
00138         SLEEP.CTRL |= SLEEP_SEN_bm; 
00139         /* Save eeprom interrupt settings for later */ 
00140         uint8_t eepromintStore = NVM.INTCTRL;
00141         
00142         
00143         /* Write the "safety code" to the CCP regiter */
00144         /* EEPROM write has to be executed within 4 cycles */
00145         CCP = CCP_IOREG_gc;
00146         /* Execute command to write buffer page to EEPROM */
00147         NVM.CTRLA = NVM_CMDEX_bm;
00148         /* Enable EEPROM interrupt */
00149         NVM.INTCTRL =  NVM_EELVL0_bm | NVM_EELVL1_bm;
00150         /* Sleep before 2.5uS has passed */
00151         __sleep();
00152         
00153         
00154         /* Restore sleep settings */
00155         SLEEP.CTRL = sleepCtr;
00156         /* Restore PMIC status and control registers */
00157         PMIC.STATUS = statusStore;
00158         PMIC.CTRL = pmicStore;
00159         /* Restore EEPROM interruptsettings */
00160         NVM.INTCTRL = eepromintStore;
00161         /* Restore global interrupt settings */
00162         SREG = globalInt;
00163 }
@DOC_TITLE@
Generated on Wed Sep 2 13:52:13 2009 for AVR1008: Writing EEPROM and Flash in ATxmega256A3 / ATxmega256A3B - Rev B by doxygen 1.5.9