EEPROM access functions including wear leveling. More...
#include "config-params.h"
Go to the source code of this file.
Defines | |
#define | EE_PARAM_BUFFER_SIZE (8) |
Number of levels in the buffer. | |
#define | EE_STATUS_BUFFER_SIZE EE_PARAM_BUFFER_SIZE |
#define | EE_BYTE_SIZE (1) |
Defines for different sizes of parameters. | |
#define | EE_WORD_SIZE (2) |
#define | EE_DWORD_SIZE (4) |
#define | EE_STATIC_PARAM_1 (0) |
List of static config parameters NOT using wear leveling, usually written once (e.g. calibration data). | |
#define | EE_STATIC_PARAM_2 (EE_STATIC_PARAM_1 + EE_STATIC_PARAM_1_SIZE) |
#define | EE_STATIC_PARAM_3 (EE_STATIC_PARAM_2 + EE_STATIC_PARAM_2_SIZE) |
#define | EE_STATIC_PARAM_4 (EE_STATIC_PARAM_3 + EE_STATIC_PARAM_3_SIZE) |
#define | EE_STATIC_PARAM_5 (EE_STATIC_PARAM_4 + EE_STATIC_PARAM_4_SIZE) |
#define | EE_STATIC_PARAM_6 (EE_STATIC_PARAM_5 + EE_STATIC_PARAM_5_SIZE) |
#define | EE_STATIC_PARAM_7 (EE_STATIC_PARAM_6 + EE_STATIC_PARAM_6_SIZE) |
#define | EE_STATIC_PARAM_LAST (EE_STATIC_PARAM_7 + EE_STATIC_PARAM_7_SIZE) |
#define | EE_PARAM_BUFFER_START (64) |
Size of reserved space for static config parameters. | |
#define | EE_PARAM_1 EE_PARAM_BUFFER_START |
List of config parameters using circular buffers for wear leveling. | |
#define | EE_PARAM_2 (EE_PARAM_1 + EE_PARAM_1_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_3 (EE_PARAM_2 + EE_PARAM_2_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_4 (EE_PARAM_3 + EE_PARAM_3_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_5 (EE_PARAM_4 + EE_PARAM_4_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_6 (EE_PARAM_5 + EE_PARAM_5_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_7 (EE_PARAM_6 + EE_PARAM_6_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_PARAM_LAST (EE_PARAM_7 + EE_PARAM_7_SIZE * EE_PARAM_BUFFER_SIZE + EE_STATUS_BUFFER_SIZE) |
#define | EE_ECHO (1) |
#define | EE_WRITE (1) |
Typedefs | |
typedef uint8_t * | ee_addr_t |
type of EEPROM address | |
Functions | |
uint8_t | read_config_byte (ee_addr_t parameter, ee_addr_t *address) |
read config parameter from EEPROM | |
uint16_t | read_config_word (ee_addr_t parameter, ee_addr_t *address) |
uint32_t | read_config_dword (ee_addr_t parameter, ee_addr_t *address) |
void | write_config_byte (ee_addr_t parameter, ee_addr_t *address, uint8_t data) |
write config parameter to EEPROM | |
void | write_config_word (ee_addr_t parameter, ee_addr_t *address, uint16_t data) |
void | write_config_dword (ee_addr_t parameter, ee_addr_t *address, uint32_t data) |
void | ee_find_current_buffer_address (ee_addr_t parameter, ee_addr_t *EeBufPtr, uint8_t param_size) |
find current EEPROM buffer position | |
void | ee_read_buffer (ee_addr_t address, void *data, uint8_t param_size) |
read from EEPROM buffer | |
void | ee_write_byte (ee_addr_t address, uint8_t data) |
write raw byte to EEPROM address | |
void | ee_write_buffer (ee_addr_t parameter, ee_addr_t *address, void *data, uint8_t param_size) |
write to EEPROM buffer |
EEPROM access functions including wear leveling.
The EEPROM is intended to hold all configuration parameters. Config parameters are defined in "config-params.h". There's no need to change the defines below, unless you want add more config parameters.
Please be aware of the difference: There are static parameters unlikely to change like calibration data and variable ones for config data that might change frequently. The latter ones require some wear leveling.
Static parameters can be accessed using the "eeprom_{read|write}_byte" functions provided by avr-libc.
Access to config data using wear leveling is provided by some functions: "read_config_{byte|word|dword}" and "write_config_{byte|word|dword}" All buffer handling is done internally.
Wear leveling is done using two circular buffers, one for the parameter itself and the other one holds a status byte indicating current buffer position. See Atmel's Application Note AVR101 for details.
#define EE_PARAM_BUFFER_SIZE (8) |
Number of levels in the buffer.
void ee_find_current_buffer_address | ( | ee_addr_t | parameter, | |
ee_addr_t * | EeBufPtr, | |||
uint8_t | param_size | |||
) |
find current EEPROM buffer position
parameter | buffer start address of config parameter | |
EeBufPtr | EEPROM buffer pointer | |
param_size | size of config parameter (length in bytes) |
{ char temp; ee_addr_t EeBufEnd; // Point to the status buffer *EeBufPtr = parameter + EE_PARAM_BUFFER_SIZE * param_size; // The first address outside the buffer EeBufEnd = *EeBufPtr + EE_STATUS_BUFFER_SIZE; // Identify the last written element of the status buffer do { temp = eeprom_read_byte (*EeBufPtr); #if EE_ECHO > 1 printf_P (PSTR(" ee_find_buf @0x%04X:0x%02X\r\n"), *EeBufPtr, temp); #endif (*EeBufPtr)++; // Break if end of buffer, so we don't compare out-of-bounds if (*EeBufPtr == EeBufEnd) break; } while (eeprom_read_byte (*EeBufPtr) == temp + 1); // Point to the last used element of the parameter buffer *EeBufPtr = parameter + param_size * (*EeBufPtr - EeBufEnd + EE_STATUS_BUFFER_SIZE - 1); }
void ee_read_buffer | ( | ee_addr_t | address, | |
void * | data, | |||
uint8_t | param_size | |||
) |
read from EEPROM buffer
address | EEPROM buffer address to read from | |
data | data read from EEPROM | |
param_size | size of config parameter (length in bytes) |
{ for (uint8_t i=0; i<param_size; i++) { while (!eeprom_is_ready()); EEAR = (uint16_t)(address + i); EECR |= (1<<EERE); *(uint8_t *)(data + i) = EEDR; #if EE_ECHO > 1 printf_P (PSTR(" ee_read_byte @0x%04X:0x%02X\r\n"), address + i, *(uint8_t *)(data + i)); #endif } }
write to EEPROM buffer
parameter | buffer start address of config parameter | |
address | EEPROM buffer address to write to | |
data | value of config parameter | |
param_size | size of config parameter (length in bytes) |
{ unsigned char EeOldStatusValue, EeOldBufElement; // Number of old buffer element [1...EE_PARAM_BUFFER_SIZE] EeOldBufElement = (*address - parameter) / param_size + 1; // Store the old status value and move pointer to the next element in the buffer EeOldStatusValue = eeprom_read_byte (parameter + EeOldBufElement - 1 + EE_PARAM_BUFFER_SIZE * param_size); (*address) += param_size; if (*address == parameter + EE_PARAM_BUFFER_SIZE * param_size) { // Wraparound if necessary. *address = parameter; EeOldBufElement = 0; } // If self-programming is used in the application, insert code here to wait for any // self-programming operations to finish before writing to the EEPROM. // Also make sure that interrupts are disabled during EEPROM write if interrupts // are used in the application, otherwise the 4-cycle limit could be exceeded. #ifdef EE_WRITE /* Update the parameter in the EEPROM buffer */ for (uint8_t i=0; i<param_size; i++) { ee_write_byte ((*address) + i, *(uint8_t *)(data + i)); } /* Update the status buffer */ ee_write_byte (parameter + EeOldBufElement + EE_PARAM_BUFFER_SIZE * param_size, EeOldStatusValue + 1); #endif }
void ee_write_byte | ( | ee_addr_t | address, | |
uint8_t | data | |||
) |
write raw byte to EEPROM address
address | EEPROM address to write to | |
data | value of config parameter |
{ eeprom_write_byte ((uint8_t *)address, data); #if EE_ECHO > 1 printf_P (PSTR(" ee_write_byte @0x%04X:0x%02X\r\n"), address, data); #endif }
read config parameter from EEPROM
Use this function to read a config byte from EEPROM like this: uint16_t BufPtrYourParam = CFG_YOUR_PARAM; cfg_byte = read_config_byte(CFG_YOUR_PARAM, &BufPtrYourParam);
parameter | buffer start address of config parameter | |
address | EEPROM address to read from |
{ uint8_t data; ee_find_current_buffer_address (parameter, address, EE_BYTE_SIZE); ee_read_buffer (*address, &data, EE_BYTE_SIZE); #if EE_ECHO > 0 printf_P (PSTR("config: read byte 0x%04X@0x%04X:0x%02X\r\n"), parameter, *address, data); #endif return data; }
write config parameter to EEPROM
Use this function to write a config byte to EEPROM like this: uint16_t BufPtrYourParam = CFG_YOUR_PARAM; write_config_byte(CFG_YOUR_PARAM, &BufPtrYourParam, cfg_byte);
parameter | buffer start address of config parameter | |
address | EEPROM address to write to | |
data | value of config parameter |
{ uint8_t olddata; ee_find_current_buffer_address (parameter, address, EE_BYTE_SIZE); #if EE_ECHO > 0 printf_P (PSTR("config: write byte 0x%04X@0x%04X:0x%02X\r\n"), parameter, *address, data); #endif // check if value changed in EEPROM ee_read_buffer (*address, &olddata, EE_BYTE_SIZE); if (data != olddata) { ee_write_buffer (parameter, address, &data, EE_BYTE_SIZE); } #if EE_ECHO > 0 else { printf_P (PSTR("config: value didn't change\r\n")); } #endif }