nvm.h
Go to the documentation of this file.00001
00038 #ifndef NVM_H
00039 #define NVM_H
00040
00041 #include <compiler.h>
00042 #include <ccp.h>
00043
00044 #ifdef __cplusplus
00045 extern "C" {
00046 #endif
00047
00081 static inline void nvm_wait_until_ready( void )
00082 {
00083 do {
00084
00085 } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm);
00086 }
00087
00097 static inline void nvm_exec(void)
00098 {
00099 ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm);
00100 }
00101
00114 static inline void nvm_issue_command(NVM_CMD_t nvm_command)
00115 {
00116 uint8_t old_cmd;
00117
00118 old_cmd = NVM.CMD;
00119 NVM.CMD = nvm_command;
00120 ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm);
00121 NVM.CMD = old_cmd;
00122 }
00123
00138 uint8_t nvm_read_byte_near(uint8_t nvm_cmd, uint8_t address);
00139
00140
00154 void nvm_common_spm(uint32_t addr, uint8_t nvm_cmd);
00155
00157
00188 struct nvm_device_id {
00189 union {
00190 struct {
00191 uint8_t devid0;
00192 uint8_t devid1;
00193 uint8_t devid2;
00194 };
00195 uint8_t byte[3];
00196 };
00197 };
00198
00204 struct nvm_device_serial {
00205 union {
00206 struct {
00207 uint8_t lotnum0;
00208 uint8_t lotnum1;
00209 uint8_t lotnum2;
00210 uint8_t lotnum3;
00211 uint8_t lotnum4;
00212 uint8_t lotnum5;
00213 uint8_t wafnum;
00214 uint8_t coordx0;
00215 uint8_t coordx1;
00216 uint8_t coordy0;
00217 uint8_t coordy1;
00218 };
00219 uint8_t byte[11];
00220 };
00221 };
00222
00229 #if defined(__GNUC__)
00230 # define nvm_get_production_signature_row_offset(regname) \
00231 offsetof(NVM_PROD_SIGNATURES_t, regname)
00232 #elif defined(__ICCAVR__)
00233 # define nvm_get_production_signature_row_offset(regname) (regname##_offset)
00234 #else
00235 # error Unknown compiler
00236 #endif
00237
00238
00253 static inline uint8_t nvm_read_production_signature_row(uint8_t address)
00254 {
00255 return nvm_read_byte_near(NVM_CMD_READ_CALIB_ROW_gc, address);
00256 }
00257
00272 static inline uint8_t nvm_read_user_signature_row(uint8_t address)
00273 {
00274 return nvm_read_byte_near(NVM_CMD_READ_USER_SIG_ROW_gc, address);
00275 }
00276
00284 static inline void nvm_read_device_id(struct nvm_device_id *storage)
00285 {
00286 storage->devid0 = MCU.DEVID0;
00287 storage->devid1 = MCU.DEVID1;
00288 storage->devid2 = MCU.DEVID2;
00289 }
00290
00298 static inline uint8_t nvm_read_device_rev(void)
00299 {
00300 return MCU.REVID;
00301 }
00302
00303 void nvm_read_device_serial(struct nvm_device_serial *storage);
00304
00306
00307
00329 #ifndef EEPROM_PAGE_SIZE
00330 # if XMEGA_A||XMEGA_D
00331 # define EEPROM_PAGE_SIZE 32
00332 # else
00333 # error Unknown EEPROM page size
00334 # endif
00335 #endif
00336
00337 #ifndef CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA
00338 # if XMEGA_A3||XMEGA_D3
00339 # error This NVM driver does not support rev B of XMEGA A3/D3 devices. \
00340 Set CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA to disable this message
00341 # endif
00342 #endif
00343
00344 uint8_t nvm_eeprom_read_byte(uint8_t page_addr, uint8_t byte_addr);
00345 void nvm_eeprom_write_byte(uint8_t page_addr,uint8_t byte_addr,uint8_t value);
00346
00347 void nvm_eeprom_flush_buffer(void);
00348 void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value);
00349 void nvm_eeprom_load_page_to_buffer(const uint8_t *values);
00350 void nvm_eeprom_atomic_write_page(uint8_t page_addr);
00351 void nvm_eeprom_split_write_page(uint8_t page_addr);
00352 void nvm_eeprom_fill_buffer_with_value(uint8_t value);
00353 void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr);
00354 void nvm_eeprom_erase_page(uint8_t page_addr);
00355 void nvm_eeprom_erase_bytes_in_all_pages(void);
00356 void nvm_eeprom_erase_all(void);
00357
00359
00404 #ifdef __DOXYGEN__
00405 # define FLASH_PAGE_SIZE
00406 #elif defined(PROGMEM_PAGE_SIZE)
00407 # define FLASH_PAGE_SIZE (PROGMEM_PAGE_SIZE)
00408 #else
00409 # if part_is_defined(ATxmega64A1)
00410 # define FLASH_PAGE_SIZE (256)
00411 # elif part_is_defined(ATxmega128A1)
00412 # define FLASH_PAGE_SIZE (512)
00413 # elif part_is_defined(ATxmega64A3)
00414 # define FLASH_PAGE_SIZE (256)
00415 # elif part_is_defined(ATxmega128A3)
00416 # define FLASH_PAGE_SIZE (512)
00417 # elif part_is_defined(ATxmega256A3)
00418 # define FLASH_PAGE_SIZE (512)
00419 # elif part_is_defined(ATxmega256A3B)
00420 # define FLASH_PAGE_SIZE (512)
00421 # elif part_is_defined(ATxmega16A4)
00422 # define FLASH_PAGE_SIZE (256)
00423 # elif part_is_defined(ATxmega32A4)
00424 # define FLASH_PAGE_SIZE (256)
00425 # else
00426 # error Flash page size needs to be defined.
00427 # endif
00428 #endif
00429
00433 typedef uint32_t flash_addr_t;
00434
00438 #define IAR_FLASH_PTR __farflash
00439
00450 static inline uint8_t nvm_flash_read_byte(flash_addr_t addr)
00451 {
00452 #if defined(__GNUC__)
00453 return pgm_read_byte_far(addr);
00454 #elif defined(__ICCAVR__)
00455 uint8_t IAR_FLASH_PTR *flashptr = (uint8_t IAR_FLASH_PTR *)addr;
00456 return *flashptr;
00457 #else
00458 # error Unknown compiler
00459 #endif
00460 }
00461
00472 static inline uint16_t nvm_flash_read_word(flash_addr_t addr)
00473 {
00474 #if defined(__GNUC__)
00475 return pgm_read_word_far(addr);
00476 #elif defined(__ICCAVR__)
00477 uint16_t IAR_FLASH_PTR *flashptr = (uint16_t IAR_FLASH_PTR *)addr;
00478 return *flashptr;
00479 #endif
00480 }
00481
00482
00491 void nvm_flash_flush_buffer(void);
00492
00504 void nvm_flash_load_word_to_buffer(uint32_t word_addr, uint16_t data);
00505
00506
00514 static inline void nvm_flash_erase_app(flash_addr_t page_addr)
00515 {
00516 nvm_wait_until_ready();
00517 nvm_common_spm(page_addr, NVM_CMD_ERASE_APP_gc);
00518 }
00519
00527 static inline void nvm_flash_erase_app_page(flash_addr_t page_addr)
00528 {
00529 nvm_wait_until_ready();
00530 nvm_common_spm(page_addr, NVM_CMD_ERASE_APP_PAGE_gc);
00531 }
00532
00542 static inline void nvm_flash_split_write_app_page(flash_addr_t page_addr)
00543 {
00544 nvm_wait_until_ready();
00545 nvm_common_spm(page_addr, NVM_CMD_WRITE_APP_PAGE_gc);
00546 }
00547
00556 static inline void nvm_flash_atomic_write_app_page(flash_addr_t page_addr)
00557 {
00558 nvm_wait_until_ready();
00559 nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_APP_PAGE_gc);
00560 }
00561
00562
00570 static inline void nvm_flash_erase_boot_page(flash_addr_t page_addr)
00571 {
00572 nvm_wait_until_ready();
00573 nvm_common_spm(page_addr, NVM_CMD_ERASE_BOOT_PAGE_gc);
00574 }
00584 static inline void nvm_flash_split_write_boot_page(flash_addr_t page_addr)
00585 {
00586 nvm_wait_until_ready();
00587 nvm_common_spm(page_addr, NVM_CMD_WRITE_BOOT_PAGE_gc);
00588 }
00589
00598 static inline void nvm_flash_atomic_write_boot_page(flash_addr_t page_addr)
00599 {
00600 nvm_wait_until_ready();
00601 nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc);
00602 }
00603
00604
00611 static inline void nvm_flash_erase_user_section(void)
00612 {
00613 nvm_wait_until_ready();
00614 nvm_common_spm(0, NVM_CMD_ERASE_USER_SIG_ROW_gc);
00615 }
00616
00625 static inline void nvm_flash_write_user_page(void)
00626 {
00627 nvm_wait_until_ready();
00628 nvm_common_spm(0, NVM_CMD_WRITE_USER_SIG_ROW_gc);
00629 }
00630
00632
00633 #ifdef __cplusplus
00634 }
00635 #endif
00636
00637 #endif