diff --git a/cpu/atmega1281/include/cpu_conf.h b/cpu/atmega1281/include/cpu_conf.h index 438cbc70ed6368c41fab0af13a111b229279fee7..5109c6074d5bf7b5aa9ddffc409178be0444329a 100644 --- a/cpu/atmega1281/include/cpu_conf.h +++ b/cpu/atmega1281/include/cpu_conf.h @@ -43,6 +43,13 @@ extern "C" { #endif /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_SIZE (4096U) /* 4kB */ +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/atmega1284p/include/cpu_conf.h b/cpu/atmega1284p/include/cpu_conf.h index e87b7d2a01553ae7ecc01ed334e79544af6c4931..0731dc3964b576184d20bf3147b84103d2a35cf6 100644 --- a/cpu/atmega1284p/include/cpu_conf.h +++ b/cpu/atmega1284p/include/cpu_conf.h @@ -44,6 +44,13 @@ extern "C" { #define THREAD_STACKSIZE_IDLE (128) /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_SIZE (4096U) /* 4kB */ +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/atmega2560/include/cpu_conf.h b/cpu/atmega2560/include/cpu_conf.h index 1e7f0eac9a056e7c7a63dfb7efbe5935dd7315c6..a070cccca24590685d0e7ab8b934818a2a750fd9 100644 --- a/cpu/atmega2560/include/cpu_conf.h +++ b/cpu/atmega2560/include/cpu_conf.h @@ -42,6 +42,14 @@ extern "C" { #define THREAD_STACKSIZE_IDLE (128) /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_SIZE (4096U) /* 4kB */ +/** @} */ + + #ifdef __cplusplus } #endif diff --git a/cpu/atmega256rfr2/include/cpu_conf.h b/cpu/atmega256rfr2/include/cpu_conf.h index 0a4cee93685b722983d36571087315a479db86e4..b21ef3c3c5d0ccb3926728148fd9c58fe24816c3 100644 --- a/cpu/atmega256rfr2/include/cpu_conf.h +++ b/cpu/atmega256rfr2/include/cpu_conf.h @@ -47,5 +47,13 @@ extern "C" { #ifdef __cplusplus } #endif + +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_SIZE (8192U) /* 8kB */ +/** @} */ + #endif /* CPU_CONF_H */ /** @} */ diff --git a/cpu/atmega328p/include/cpu_conf.h b/cpu/atmega328p/include/cpu_conf.h index 91ac74da4d81e946d804bd006fd074b0edc69e34..1f0aab3eab7a8d9ba8826c28d8d081ef388960e6 100644 --- a/cpu/atmega328p/include/cpu_conf.h +++ b/cpu/atmega328p/include/cpu_conf.h @@ -42,6 +42,13 @@ extern "C" { #define THREAD_STACKSIZE_IDLE (128) /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_SIZE (1024U) /* 1kB */ +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/atmega_common/Makefile.features b/cpu/atmega_common/Makefile.features index 7a418ea511cb94cb5a2daed61773d99257e33013..ac0dd81727799a51f1c69a5b98e50cfa993506c7 100644 --- a/cpu/atmega_common/Makefile.features +++ b/cpu/atmega_common/Makefile.features @@ -1 +1,2 @@ FEATURES_PROVIDED += periph_pm +FEATURES_PROVIDED += periph_eeprom diff --git a/cpu/atmega_common/periph/eeprom.c b/cpu/atmega_common/periph/eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..2a3827336ddd08532d444a4137837c61fef83052 --- /dev/null +++ b/cpu/atmega_common/periph/eeprom.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_atmega_common + * @ingroup drivers_periph_eeprom + * @{ + * + * @file + * @brief Low-level EEPROM driver implementation for ATmega family + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * @} + */ + +#include <stdint.h> +#include <assert.h> + +#include "cpu.h" +#include "periph/eeprom.h" + +uint8_t eeprom_read_byte(uint32_t pos) +{ + assert(pos < EEPROM_SIZE); + + /* Wait for completion of previous operation */ + while (EECR & (1 << EEPE)) {} + + /* Set up address register */ + EEAR = pos; + + /* Start eeprom read by writing EERE */ + EECR |= (1 << EERE); + + /* Return data from Data Register */ + return EEDR; +} + +void eeprom_write_byte(uint32_t pos, uint8_t data) +{ + assert(pos < EEPROM_SIZE); + + /* Wait for completion of previous operation */ + while (EECR & (1 << EEPE)) {} + + /* Set up address and Data Registers */ + EEAR = pos; + EEDR = data; + + /* Write logical one to EEMPE */ + EECR |= (1 << EEMPE); + + /* Start eeprom write by setting EEPE */ + EECR |= (1 << EEPE); +} diff --git a/cpu/stm32_common/Makefile.include b/cpu/stm32_common/Makefile.include index e172bfbacf5f900550d44cf51c9959147e221bb6..1bb08442965d40b627c00d8de83db9d7478a2dc6 100644 --- a/cpu/stm32_common/Makefile.include +++ b/cpu/stm32_common/Makefile.include @@ -8,6 +8,12 @@ USEMODULE += periph_common # include stm32 common functions and stm32 common periph drivers USEMODULE += stm32_common stm32_common_periph +# flashpage and eeprom periph implementations share flash lock/unlock functions +# in periph_flash_common +ifneq (,$(filter periph_flashpage periph_eeprom,$(FEATURES_REQUIRED))) + FEATURES_REQUIRED += periph_flash_common +endif + # For stm32 cpu's we use the stm32_common.ld linker script export LINKFLAGS += -L$(RIOTCPU)/stm32_common/ldscripts LINKER_SCRIPT ?= stm32_common.ld diff --git a/cpu/stm32_common/periph/eeprom.c b/cpu/stm32_common/periph/eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..470ae47276ca167a6d9725ccecdd205d594e9607 --- /dev/null +++ b/cpu/stm32_common/periph/eeprom.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_stm32_common + * @ingroup drivers_periph_eeprom + * @{ + * + * @file + * @brief Low-level eeprom driver implementation + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <assert.h> + +#include "cpu.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#include "periph/eeprom.h" + +extern void _lock(void); +extern void _unlock(void); + +#ifndef EEPROM_START_ADDR +#error "periph/eeprom: EEPROM_START_ADDR is not defined" +#endif + +uint8_t eeprom_read_byte(uint32_t pos) +{ + assert(pos < EEPROM_SIZE); + + DEBUG("Reading data from EEPROM at pos %lu\n", pos); + return *(uint8_t *)(EEPROM_START_ADDR + pos); +} + +void eeprom_write_byte(uint32_t pos, uint8_t data) +{ + assert(pos < EEPROM_SIZE); + + DEBUG("Writing data '%c' to EEPROM at pos %lu\n", data, pos); + _unlock(); + *(uint8_t *)(EEPROM_START_ADDR + pos) = data; + _lock(); +} diff --git a/cpu/stm32_common/periph/flash_common.c b/cpu/stm32_common/periph/flash_common.c new file mode 100644 index 0000000000000000000000000000000000000000..34f92e75f06fcf084e8485c88eb02733d881d529 --- /dev/null +++ b/cpu/stm32_common/periph/flash_common.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_stm32_common + * @{ + * + * @file + * @brief Low-level flash lock/unlock implementation + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include "cpu.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) +/* Data EEPROM and control register unlock keys */ +#define FLASH_KEY1 ((uint32_t)0x89ABCDEF) +#define FLASH_KEY2 ((uint32_t)0x02030405) +#define CNTRL_REG (FLASH->PECR) +#define CNTRL_REG_LOCK (FLASH_PECR_PELOCK) +#define KEY_REG (FLASH->PEKEYR) +#else +#define CNTRL_REG (FLASH->CR) +#define CNTRL_REG_LOCK (FLASH_CR_LOCK) +#define KEY_REG (FLASH->KEYR) +#endif + +void _unlock(void) +{ + DEBUG("[flash-common] unlocking the flash module\n"); + if (CNTRL_REG & CNTRL_REG_LOCK) { + KEY_REG = FLASH_KEY1; + KEY_REG = FLASH_KEY2; + } +} + +void _lock(void) +{ + DEBUG("[flash-common] locking the flash module\n"); + CNTRL_REG |= CNTRL_REG_LOCK; +} diff --git a/cpu/stm32_common/periph/flashpage.c b/cpu/stm32_common/periph/flashpage.c index 1884579c11c0b6ab77ed68ef6327d8404acc8607..e4454b18183b3cbb6a8c5e0ce1589a8267d0a5bc 100644 --- a/cpu/stm32_common/periph/flashpage.c +++ b/cpu/stm32_common/periph/flashpage.c @@ -32,32 +32,26 @@ #include "periph/flashpage.h" #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) -/* Data EEPROM and control register unlock keys */ -#define FLASH_KEY1 ((uint32_t)0x89ABCDEF) -#define FLASH_KEY2 ((uint32_t)0x02030405) /* Program memory unlock keys */ #define FLASH_PRGKEY1 ((uint32_t)0x8C9DAEBF) #define FLASH_PRGKEY2 ((uint32_t)0x13141516) #define CNTRL_REG (FLASH->PECR) #define CNTRL_REG_LOCK (FLASH_PECR_PELOCK) -#define KEY_REG (FLASH->PEKEYR) #define FLASH_CR_PER (FLASH_PECR_ERASE | FLASH_PECR_PROG) #define FLASH_CR_PG (FLASH_PECR_FPRG | FLASH_PECR_PROG) #define FLASHPAGE_DIV (4U) /* write 4 bytes in one go */ #else #define CNTRL_REG (FLASH->CR) #define CNTRL_REG_LOCK (FLASH_CR_LOCK) -#define KEY_REG (FLASH->KEYR) #define FLASHPAGE_DIV (2U) #endif -static void _unlock(void) +extern void _lock(void); +extern void _unlock(void); + +static void _unlock_flash(void) { - DEBUG("[flashpage] unlocking the flash module\n"); - if (CNTRL_REG & CNTRL_REG_LOCK) { - KEY_REG = FLASH_KEY1; - KEY_REG = FLASH_KEY2; - } + _unlock(); #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) DEBUG("[flashpage] unlocking the flash program memory\n"); @@ -71,12 +65,6 @@ static void _unlock(void) #endif } -static void _lock(void) -{ - DEBUG("[flashpage] locking the flash module\n"); - CNTRL_REG |= CNTRL_REG_LOCK; -} - static void _erase_page(void *page_addr) { #if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) @@ -90,7 +78,7 @@ static void _erase_page(void *page_addr) #endif /* unlock the flash module */ - _unlock(); + _unlock_flash(); /* make sure no flash operation is ongoing */ DEBUG("[flashpage] erase: waiting for any operation to finish\n"); @@ -153,7 +141,7 @@ void flashpage_write_raw(void *target_addr, const void *data, size_t len) #endif DEBUG("[flashpage_raw] unlocking the flash module\n"); - _unlock(); + _unlock_flash(); DEBUG("[flashpage] write: now writing the data\n"); #if !(defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)) diff --git a/cpu/stm32f0/Makefile.features b/cpu/stm32f0/Makefile.features index d286ea06f23ab207993df550a7d7cf0e760ee7a4..e2a50dd8655e01458a40f536415b6127a15dbb0d 100644 --- a/cpu/stm32f0/Makefile.features +++ b/cpu/stm32f0/Makefile.features @@ -1,4 +1,5 @@ ifeq (,$(filter nucleo-f031k6,$(BOARD))) + FEATURES_PROVIDED += periph_flash_common FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_flashpage_raw endif diff --git a/cpu/stm32f1/Makefile.features b/cpu/stm32f1/Makefile.features index 5e5e8b9118b419c443eed05bbce504daae169842..e5e8c0f6d8c71ef93ae9da82b80ddc934dd9d416 100644 --- a/cpu/stm32f1/Makefile.features +++ b/cpu/stm32f1/Makefile.features @@ -1,3 +1,4 @@ +FEATURES_PROVIDED += periph_flash_common FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_flashpage_raw diff --git a/cpu/stm32l0/Makefile.features b/cpu/stm32l0/Makefile.features index ba0527ef1772adc63ee652cbb27d2857efd8665e..79346e3fde7d24e7bad26dc3f25c3642a1ffe49a 100644 --- a/cpu/stm32l0/Makefile.features +++ b/cpu/stm32l0/Makefile.features @@ -1,5 +1,7 @@ +FEATURES_PROVIDED += periph_flash_common FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_flashpage_raw +FEATURES_PROVIDED += periph_eeprom FEATURES_PROVIDED += periph_hwrng BOARDS_WITHOUT_HWRNG += nucleo-l031k6 diff --git a/cpu/stm32l0/include/cpu_conf.h b/cpu/stm32l0/include/cpu_conf.h index d8cb2b5ed42303acd4869aad8cb40dc549ac4a7b..bae780aef6d9ef6ba880d7eab0c640b2c0728df9 100644 --- a/cpu/stm32l0/include/cpu_conf.h +++ b/cpu/stm32l0/include/cpu_conf.h @@ -79,6 +79,20 @@ extern "C" { #define FLASHPAGE_RAW_ALIGNMENT (4U) /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_START_ADDR (0x08080000) +#if defined(CPU_MODEL_STM32L073RZ) || defined(CPU_MODEL_STM32L072CZ) +#define EEPROM_SIZE (6144U) /* 6kB */ +#elif defined(CPU_MODEL_STM32L053R8) +#define EEPROM_SIZE (2048U) /* 2kB */ +#elif defined(CPU_MODEL_STM32L031K6) +#define EEPROM_SIZE (1024U) /* 1kB */ +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/stm32l1/Makefile.features b/cpu/stm32l1/Makefile.features index 5e5e8b9118b419c443eed05bbce504daae169842..a49d3982606d994b90b0c56290c1cea3d5fafd48 100644 --- a/cpu/stm32l1/Makefile.features +++ b/cpu/stm32l1/Makefile.features @@ -1,4 +1,6 @@ +FEATURES_PROVIDED += periph_flash_common FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_flashpage_raw +FEATURES_PROVIDED += periph_eeprom -include $(RIOTCPU)/stm32_common/Makefile.features diff --git a/cpu/stm32l1/include/cpu_conf.h b/cpu/stm32l1/include/cpu_conf.h index cb86a3bf531cc7ea6612740562f7c76b8f47ada5..af78bf0516f48af5d2ece40c9dce5f1ef9168175 100644 --- a/cpu/stm32l1/include/cpu_conf.h +++ b/cpu/stm32l1/include/cpu_conf.h @@ -93,6 +93,18 @@ extern "C" { #define FLASHPAGE_RAW_ALIGNMENT (4U) /** @} */ +/** + * @name EEPROM configuration + * @{ + */ +#define EEPROM_START_ADDR (0x08080000) +#if defined(CPU_MODEL_STM32L152RE) +#define EEPROM_SIZE (16384UL) /* 16kB */ +#elif defined(CPU_MODEL_STM32L151RC) +#define EEPROM_SIZE (8192U) /* 8kB */ +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/drivers/include/periph/eeprom.h b/drivers/include/periph/eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..14750c594ee3c8b97dc5b376d7dbe40fb44e3560 --- /dev/null +++ b/drivers/include/periph/eeprom.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup drivers_periph_eeprom EEPROM driver + * @ingroup drivers_periph + * @brief Low-level EEPROM interface + * + * @{ + * @file + * @brief Low-level eeprom driver interface + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + */ + +#ifndef PERIPH_EEPROM_H +#define PERIPH_EEPROM_H + +#include <stdint.h> + +#include "cpu.h" +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EEPROM_SIZE +#error "periph/eeprom: EEPROM_SIZE is not defined" +#endif + +/** + * @brief Read a byte at the given position in eeprom + * + * @param[in] pos position to read + * + * @return the byte read + */ +uint8_t eeprom_read_byte(uint32_t pos); + +/** + * @brief Read @p len bytes from the given position + * + * @param[in] pos start position in eeprom + * @param[out] data output byte array to write to + * @param[in] len the number of bytes to read + * + * @return the number of bytes read + */ +size_t eeprom_read(uint32_t pos, uint8_t *data, size_t len); + +/** + * @brief Write a byte at the given position + * + * @param[in] pos position to write + * @param[in] data byte address to write to + */ +void eeprom_write_byte(uint32_t pos, uint8_t data); + +/** + * @brief Write @p len bytes at the given position + * + * @param[in] pos start position in eeprom + * @param[in] data input byte array to read into + * @param[in] len the number of bytes to read + * + * @return the number of bytes written + */ +size_t eeprom_write(uint32_t pos, const uint8_t *data, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_EEPROM_H */ +/** @} */ diff --git a/drivers/periph_common/eeprom.c b/drivers/periph_common/eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..f04c7af866ca9d0b4ce0e2e6a7503b59ed009d91 --- /dev/null +++ b/drivers/periph_common/eeprom.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers + * @{ + * + * @file + * @brief Common eeprom functions implementation + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <string.h> +#include "cpu.h" +#include "assert.h" + +/* guard this file, must be done before including periph/eeprom.h */ +#if defined(EEPROM_SIZE) + +#include "periph/eeprom.h" + +size_t eeprom_read(uint32_t pos, uint8_t *data, size_t len) +{ + assert(pos + len < EEPROM_SIZE); + + for (size_t i = 0; i < len; i++) { + data[i] = eeprom_read_byte(pos++); + } + + return len; +} + +size_t eeprom_write(uint32_t pos, const uint8_t *data, size_t len) +{ + assert(pos + len < EEPROM_SIZE); + + for (size_t i = 0; i < len; i++) { + eeprom_write_byte(pos++, data[i]); + } + + return len; +} + +#endif diff --git a/tests/periph_eeprom/Makefile b/tests/periph_eeprom/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a34d7a7e28e3dc88162c9f56d2932cdb39cb3e76 --- /dev/null +++ b/tests/periph_eeprom/Makefile @@ -0,0 +1,9 @@ +BOARD ?= b-l072z-lrwan1 +include ../Makefile.tests_common + +FEATURES_REQUIRED += periph_eeprom + +USEMODULE += shell +USEMODULE += shell_commands # provides reboot command + +include $(RIOTBASE)/Makefile.include diff --git a/tests/periph_eeprom/README.md b/tests/periph_eeprom/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6dbe0d879aa2bec51e3047bf266eab01814d70f4 --- /dev/null +++ b/tests/periph_eeprom/README.md @@ -0,0 +1,17 @@ +Expected result +=============== + +Use the provided shell commands to read and write bytes from/to the MCU's +internal EEPROM memory. + + # Read 10 bytes from the beginning of the eeprom + > read 0 10 + + # Write HelloWorld starting from the 10th position in the eeprom + > write 10 HelloWorld + +Background +========== + +This test application provides shell commands to verify the implementations of +the `eeprom` peripheral driver interface. diff --git a/tests/periph_eeprom/main.c b/tests/periph_eeprom/main.c new file mode 100644 index 0000000000000000000000000000000000000000..0de526c83a5dc3498e0487dff2a190b7809116a1 --- /dev/null +++ b/tests/periph_eeprom/main.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Manual test application for the EEPROM peripheral drivers + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "shell.h" + +#include "periph/eeprom.h" + +#ifndef BUFFER_SIZE +#define BUFFER_SIZE (42U) +#endif + +static char buffer[BUFFER_SIZE + 1]; + +static int cmd_info(int argc, char **argv) +{ + (void)argc; + (void)argv; + +#ifdef EEPROM_START_ADDR + printf("EEPROM start addr:\t0x%08x\n", (int)EEPROM_START_ADDR); +#endif + printf("EEPROM size:\t\t%i\n", (int)EEPROM_SIZE); + + return 0; +} + +static int cmd_read(int argc, char **argv) +{ + if (argc < 3) { + printf("usage: %s <pos> <count>\n", argv[0]); + return 1; + } + + uint32_t pos = atoi(argv[1]); + uint8_t count = atoi(argv[2]); + + if (!count) { + puts("Count should be greater than 0"); + return 1; + } + + if (count > BUFFER_SIZE) { + puts("Count exceeds buffer size"); + return 1; + } + + if (pos + count >= EEPROM_SIZE) { + puts("Failed: cannot read out of eeprom bounds"); + return 1; + } + + size_t ret = eeprom_read(pos, (uint8_t *)buffer, count); + buffer[count] = '\0'; + + printf("Data read from EEPROM (%d bytes): %s\n", (int)ret, buffer); + + return 0; +} + +static int cmd_write(int argc, char **argv) +{ + if (argc < 3) { + printf("usage: %s <pos> <data>\n", argv[0]); + return 1; + } + + uint32_t pos = atoi(argv[1]); + + if (pos + strlen(argv[2]) >= EEPROM_SIZE) { + puts("Failed: cannot write out of eeprom bounds"); + return 1; + } + + size_t ret = eeprom_write(pos, (uint8_t *)argv[2], strlen(argv[2])); + printf("%d bytes written to EEPROM\n", (int)ret); + + return 0; +} + +static const shell_command_t shell_commands[] = { + { "info", "Print information about eeprom", cmd_info }, + { "read", "Read bytes from eeprom", cmd_read }, + { "write", "Write bytes to eeprom", cmd_write}, + { NULL, NULL, NULL } +}; + +int main(void) +{ + puts("EEPROM read write test\n"); + puts("Please refer to the README.md for more details\n"); + + cmd_info(0, NULL); + + /* run the shell */ + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + return 0; +}