diff --git a/cpu/atmega_common/include/periph_cpu_common.h b/cpu/atmega_common/include/periph_cpu_common.h index 95cb0f1afbae546684222dc5dceb4f5eff23d097..56dc154db4b7dfccf5f764c9b6be5c1e8e398b55 100644 --- a/cpu/atmega_common/include/periph_cpu_common.h +++ b/cpu/atmega_common/include/periph_cpu_common.h @@ -146,6 +146,11 @@ typedef struct { } pwm_conf_t; /** @} */ +/** + * @brief EEPROM clear byte + */ +#define EEPROM_CLEAR_BYTE (0xff) + #ifdef __cplusplus } #endif diff --git a/drivers/include/periph/eeprom.h b/drivers/include/periph/eeprom.h index affdf13572b2c4a6c860fbf4563692d6a0cf06f1..e08a8ebca4935c8aa6cba7be37054f20ef06524a 100644 --- a/drivers/include/periph/eeprom.h +++ b/drivers/include/periph/eeprom.h @@ -34,6 +34,13 @@ extern "C" { #error "periph/eeprom: EEPROM_SIZE is not defined" #endif +/** + * @brief Default value of the EEPROM clear byte + */ +#ifndef EEPROM_CLEAR_BYTE +#define EEPROM_CLEAR_BYTE 0x00 +#endif + /** * @brief Read a byte at the given position in eeprom * @@ -79,6 +86,36 @@ void eeprom_write_byte(uint32_t pos, uint8_t data); */ size_t eeprom_write(uint32_t pos, const uint8_t *data, size_t len); +/** + * @brief Set @p len bytes from the given position @p pos with value @p val + * + * @param[in] pos start position in eeprom + * @param[in] val the value to set + * @param[in] len the number of bytes to set + * + * @return the number of bytes set + */ +size_t eeprom_set(uint32_t pos, uint8_t val, size_t len); + +/** + * @brief Clear @p len bytes from the given position @p pos + * + * Clearing a byte in EEPROM simply consists in setting it to 0 + * + * @param[in] pos start position in eeprom + * @param[in] len the number of bytes to clear + * + * @return the number of bytes cleared + */ +size_t eeprom_clear(uint32_t pos, size_t len); + +/** + * @brief Erase the whole EEPROM content + * + * @return the EEPROM_SIZE + */ +size_t eeprom_erase(void); + #ifdef __cplusplus } #endif diff --git a/drivers/periph_common/eeprom.c b/drivers/periph_common/eeprom.c index d22c512701d15df1eb8977dcd940be8abcfe9bcc..ccbcea78463690022fa727a2b33164fecaf41a91 100644 --- a/drivers/periph_common/eeprom.c +++ b/drivers/periph_common/eeprom.c @@ -40,4 +40,24 @@ void eeprom_write_byte(uint32_t pos, uint8_t byte) eeprom_write(pos, &byte, 1); } +size_t eeprom_set(uint32_t pos, uint8_t val, size_t len) +{ + assert(pos + len <= EEPROM_SIZE); + + for (size_t i = 0; i < len; i++) { + eeprom_write_byte(pos++, val); + } + + return len; +} + +size_t eeprom_clear(uint32_t pos, size_t len) +{ + return eeprom_set(pos, EEPROM_CLEAR_BYTE, len); +} + +size_t eeprom_erase(void) +{ + return eeprom_clear(0, EEPROM_SIZE); +} #endif diff --git a/tests/periph_eeprom/main.c b/tests/periph_eeprom/main.c index 0eac47877f6c3eb016e180798a39217ead634ad3..fddd7de8b0a79d9b515be10bbe4aac3351f0c76b 100644 --- a/tests/periph_eeprom/main.c +++ b/tests/periph_eeprom/main.c @@ -139,6 +139,74 @@ static int cmd_write_byte(int argc, char **argv) return 0; } +static int cmd_set(int argc, char **argv) +{ + if (argc < 4) { + printf("usage: %s <pos> <char> <count>\n", argv[0]); + return 1; + } + + uint32_t pos = atoi(argv[1]); + uint32_t count = atoi(argv[3]); + + if (strlen(argv[2]) != 1) { + puts("Failed: char must be a single digit"); + return 1; + } + + uint8_t c = (uint8_t)argv[2][0]; + + if (pos + count > EEPROM_SIZE) { + puts("Failed: cannot clear out of eeprom bounds"); + return 1; + } + + size_t ret = eeprom_set(pos, c, count); + printf("%d bytes set to %c in EEPROM\n", (int)ret, c); + + return 0; +} + +static int cmd_clear(int argc, char **argv) +{ + if (argc < 3) { + printf("usage: %s <pos> <count>\n", argv[0]); + return 1; + } + + uint32_t pos = atoi(argv[1]); + uint32_t count = atoi(argv[2]); + + if (pos + count > EEPROM_SIZE) { + puts("Failed: cannot clear out of eeprom bounds"); + return 1; + } + + size_t ret = eeprom_clear(pos, count); + printf("%d bytes cleared in EEPROM\n", (int)ret); + + return 0; +} + +static int cmd_erase(int argc, char **argv) +{ + if (argc != 1) { + printf("usage: %s\n", argv[0]); + return 1; + } + + size_t ret = eeprom_erase(); + if (ret == EEPROM_SIZE) { + puts("EEPROM erased with success"); + } + else { + puts("EEPROM erase failed"); + return 1; + } + + return 0; +} + static int cmd_test(int argc, char **argv) { (void)argv; @@ -148,24 +216,25 @@ static int cmd_test(int argc, char **argv) return 1; } - const char *test = "test"; + const char *expected = "test"; /* test read/write function */ /* read/write from beginning of EEPROM */ - size_t ret = eeprom_write(0, (uint8_t *)test, 4); + size_t ret = eeprom_write(0, (uint8_t *)expected, 4); assert(ret == 4); - char *expected[4]; - ret = eeprom_read(0, (uint8_t *)expected, 4); - assert(strncmp((const char *)expected, (const char *)test, 4) == 0); + char *result[4]; + ret = eeprom_read(0, (uint8_t *)result, 4); + assert(strncmp((const char *)result, (const char *)expected, 4) == 0); assert(ret == 4); /* read/write at end of EEPROM */ - ret = eeprom_write(EEPROM_SIZE - 4, (uint8_t *)test, 4); + ret = eeprom_write(EEPROM_SIZE - 4, (uint8_t *)expected, 4); assert(ret == 4); - ret = eeprom_read(EEPROM_SIZE - 4, (uint8_t *)expected, 4); - assert(strncmp((const char *)expected, test, 4) == 0); + memset(result, 0, 4); + ret = eeprom_read(EEPROM_SIZE - 4, (uint8_t *)result, 4); + assert(strncmp((const char *)result, expected, 4) == 0); assert(ret == 4); /* read/write single byte */ @@ -176,6 +245,30 @@ static int cmd_test(int argc, char **argv) eeprom_write_byte(EEPROM_SIZE / 2, 'A'); assert(eeprom_read_byte(EEPROM_SIZE / 2) == 'A'); + /* clear some bytes */ + eeprom_clear(0, 4); + memset(result, 0, 4); + ret = eeprom_read(0, (uint8_t *)result, 4); + assert(strncmp((const char *)result, "", 4) == 0); + assert(ret == 4); + + eeprom_clear(EEPROM_SIZE - 4, 4); + ret = eeprom_read(EEPROM_SIZE - 4, (uint8_t *)result, 4); + assert(strncmp((const char *)result, "", 4) == 0); + assert(ret == 4); + + /* set some bytes */ + eeprom_set(0, 'A', 4); + ret = eeprom_read(0, (uint8_t *)result, 4); + assert(strncmp((const char *)result, "AAAA", 4) == 0); + assert(ret == 4); + + memset(result, 0, 4); + eeprom_set(EEPROM_SIZE - 4, 'A', 4); + ret = eeprom_read(EEPROM_SIZE - 4, (uint8_t *)result, 4); + assert(strncmp((const char *)result, "AAAA", 4) == 0); + assert(ret == 4); + puts("SUCCESS"); return 0; } @@ -187,6 +280,9 @@ static const shell_command_t shell_commands[] = { { "write", "Write bytes to eeprom", cmd_write }, { "read_byte", "Read a single byte from eeprom", cmd_read_byte }, { "write_byte", "Write a single byte to eeprom", cmd_write_byte }, + { "set", "Set bytes to eeprom", cmd_set}, + { "clear", "Clear bytes to eeprom", cmd_clear}, + { "erase", "Erase whole eeprom", cmd_erase}, { "test", "Test the EEPROM implementation", cmd_test }, { NULL, NULL, NULL } };