Xmega Application Note


nvm.c

Go to the documentation of this file.
00001 
00038 #include <compiler.h>
00039 #include <ccp.h>
00040 #include <nvm.h>
00041 
00060 void nvm_read_device_serial(struct nvm_device_serial *storage)
00061 {
00062         storage->lotnum0 = nvm_read_production_signature_row(
00063                         nvm_get_production_signature_row_offset(LOTNUM0));
00064         storage->lotnum1 = nvm_read_production_signature_row(
00065                         nvm_get_production_signature_row_offset(LOTNUM1));
00066         storage->lotnum2 = nvm_read_production_signature_row(
00067                         nvm_get_production_signature_row_offset(LOTNUM2));
00068         storage->lotnum3 = nvm_read_production_signature_row(
00069                         nvm_get_production_signature_row_offset(LOTNUM3));
00070         storage->lotnum4 = nvm_read_production_signature_row(
00071                         nvm_get_production_signature_row_offset(LOTNUM4));
00072         storage->lotnum5 = nvm_read_production_signature_row(
00073                         nvm_get_production_signature_row_offset(LOTNUM5));
00074 
00075         storage->wafnum  = nvm_read_production_signature_row(
00076                         nvm_get_production_signature_row_offset(WAFNUM));
00077 
00078         storage->coordx0 = nvm_read_production_signature_row(
00079                         nvm_get_production_signature_row_offset(COORDX0));
00080         storage->coordx1 = nvm_read_production_signature_row(
00081                         nvm_get_production_signature_row_offset(COORDX1));
00082         storage->coordy0 = nvm_read_production_signature_row(
00083                         nvm_get_production_signature_row_offset(COORDY0));
00084         storage->coordy1 = nvm_read_production_signature_row(
00085                         nvm_get_production_signature_row_offset(COORDY1));
00086 }
00087 
00089 
00090 
00108 uint8_t nvm_eeprom_read_byte(uint8_t page_addr, uint8_t byte_addr)
00109 {
00110         /* Wait until NVM is ready */
00111         nvm_wait_until_ready();
00112         /* Calculate address */
00113         uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE)
00114                                     |(byte_addr & (EEPROM_PAGE_SIZE - 1));
00115 
00116         Assert(address <= EEPROM_SIZE);
00117 
00118         /* Set address to read from */
00119         NVM.ADDR2 = 0x00;
00120         NVM.ADDR1 = (address >> 8) & 0xFF;
00121         NVM.ADDR0 = address & 0xFF;
00122 
00123         /* Issue EEPROM Read command */
00124         nvm_issue_command(NVM_CMD_READ_EEPROM_gc);
00125 
00126         return NVM.DATA0;
00127 }
00128 
00139 void nvm_eeprom_flush_buffer(void)
00140 {
00141         /* Wait until NVM is ready */
00142         nvm_wait_until_ready();
00143 
00144         /* Flush EEPROM page buffer if necessary */
00145         if ((NVM.STATUS & NVM_EELOAD_bm) != 0) {
00146                 NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc;
00147                 nvm_exec();
00148         }
00149 }
00150 
00151 
00164 void nvm_eeprom_write_byte(uint8_t page_addr,uint8_t byte_addr,uint8_t value)
00165 {
00166         uint8_t old_cmd;
00167 
00168         /*  Flush buffer to make sure no unintetional data is written and load
00169          *  the "Page Load" command into the command register.
00170          */
00171         old_cmd = NVM.CMD;
00172         nvm_eeprom_flush_buffer();
00173 
00174         NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
00175 
00176         /* Calculate address */
00177         uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE)
00178                                     |(byte_addr & (EEPROM_PAGE_SIZE - 1));
00179 
00180         Assert(address <= EEPROM_SIZE);
00181 
00182         /* Set address to write to. */
00183         NVM.ADDR2 = 0x00;
00184         NVM.ADDR1 = (address >> 8) & 0xFF;
00185         NVM.ADDR0 = address & 0xFF;
00186 
00187         /* Load data to write, which triggers the loading of EEPROM page buffer. */
00188         NVM.DATA0 = value;
00189 
00190         /*  Issue EEPROM Atomic Write (Erase&Write) command. Load command, write
00191          *  the protection signature and execute command.
00192          */
00193         NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
00194         nvm_exec();
00195         NVM.CMD = old_cmd;
00196 }
00197 
00198 
00215 void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value)
00216 {
00217         uint8_t old_cmd;
00218         old_cmd = NVM.CMD;
00219 
00220         /* Wait until NVM is ready */
00221         nvm_wait_until_ready();
00222 
00223         NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
00224 
00225         /* Set address */
00226         NVM.ADDR2 = 0x00;
00227         NVM.ADDR1 = 0x00;
00228         NVM.ADDR0 = byte_addr & 0xFF;
00229 
00230         /* Set data, which triggers loading of EEPROM page buffer */
00231         NVM.DATA0 = value;
00232 
00233         NVM.CMD = old_cmd;
00234 }
00235 
00236 
00252 void nvm_eeprom_load_page_to_buffer(const uint8_t *values)
00253 {
00254         uint8_t old_cmd;
00255         old_cmd = NVM.CMD;
00256 
00257         /* Wait until NVM is ready */
00258         nvm_wait_until_ready();
00259 
00260         NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
00261 
00262         /*  Set address to zero, as only the lower bits matters. ADDR0 is
00263          *  maintained inside the loop below.
00264          */
00265         NVM.ADDR2 = 0x00;
00266         NVM.ADDR1 = 0x00;
00267 
00268         /* Load multible bytes into page buffer. */
00269         for (uint8_t i = 0; i < EEPROM_PAGE_SIZE; ++i) {
00270                 NVM.ADDR0 = i;
00271                 NVM.DATA0 = *values;
00272                 ++values;
00273         }
00274         NVM.CMD = old_cmd;
00275 }
00276 
00290 void nvm_eeprom_atomic_write_page(uint8_t page_addr)
00291 {
00292         /* Wait until NVM is ready */
00293         nvm_wait_until_ready();
00294 
00295         /* Calculate page address */
00296         uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
00297 
00298         Assert(address <= EEPROM_SIZE);
00299 
00300         /* Set address. */
00301         NVM.ADDR2 = 0x00;
00302         NVM.ADDR1 = (address >> 8) & 0xFF;
00303         NVM.ADDR0 = address & 0xFF;
00304 
00305         /* Issue EEPROM Atomic Write (Erase&Write) command. */
00306         nvm_issue_command(NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc);
00307 }
00308 
00320 void nvm_eeprom_split_write_page(uint8_t page_addr)
00321 {
00322         /* Wait until NVM is ready */
00323         nvm_wait_until_ready();
00324 
00325         /* Calculate page address */
00326         uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
00327 
00328         Assert(address <= EEPROM_SIZE);
00329 
00330         /* Set address. */
00331         NVM.ADDR2 = 0x00;
00332         NVM.ADDR1 = (address >> 8) & 0xFF;
00333         NVM.ADDR0 = address & 0xFF;
00334 
00335         /* Issue EEPROM Split Write command. */
00336         nvm_issue_command(NVM_CMD_WRITE_EEPROM_PAGE_gc);
00337 }
00338 
00352 void nvm_eeprom_fill_buffer_with_value(uint8_t value)
00353 {
00354         uint8_t old_cmd;
00355         old_cmd = NVM.CMD;
00356 
00357         nvm_eeprom_flush_buffer();
00358 
00359         NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
00360 
00361         /*  Set address to zero, as only the lower bits matters. ADDR0 is
00362          *  maintained inside the loop below.
00363          */
00364         NVM.ADDR2 = 0x00;
00365         NVM.ADDR1 = 0x00;
00366 
00367         /* Load multible bytes into page buffer. */
00368         for (uint8_t i = 0; i < EEPROM_PAGE_SIZE; ++i) {
00369                 NVM.ADDR0 = i;
00370                 NVM.DATA0 = value;
00371         }
00372         NVM.CMD = old_cmd;
00373 }
00374 
00383 void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr)
00384 {
00385         /* Wait until NVM is ready */
00386         nvm_wait_until_ready();
00387 
00388         /* Calculate page address */
00389         uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
00390 
00391         Assert(address <= EEPROM_SIZE);
00392 
00393         /* Set address. */
00394         NVM.ADDR2 = 0x00;
00395         NVM.ADDR1 = (address >> 8) & 0xFF;
00396         NVM.ADDR0 = address & 0xFF;
00397 
00398         /* Issue EEPROM Erase command. */
00399         nvm_issue_command(NVM_CMD_ERASE_EEPROM_PAGE_gc);
00400 }
00401 
00409 void nvm_eeprom_erase_page(uint8_t page_addr)
00410 {
00411         /* Mark all addresses to be deleted */
00412         nvm_eeprom_fill_buffer_with_value(0xff);
00413         /* Erase bytes */
00414         nvm_eeprom_erase_bytes_in_page(page_addr);
00415 }
00416 
00417 
00424 void nvm_eeprom_erase_bytes_in_all_pages(void)
00425 {
00426         /* Wait until NVM is ready */
00427         nvm_wait_until_ready();
00428 
00429         /* Issue EEPROM Erase All command. */
00430         nvm_issue_command(NVM_CMD_ERASE_EEPROM_gc);
00431 }
00432 
00438 void nvm_eeprom_erase_all(void)
00439 {
00440         /* Mark all addresses to be deleted */
00441         nvm_eeprom_fill_buffer_with_value(0xff);
00442         /* Erase all pages*/
00443         nvm_eeprom_erase_bytes_in_all_pages();
00444 }
00445 
@DOC_TITLE@
Generated on Fri Oct 22 12:15:25 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3