From e486829b8f432ca12b2c91d8aee78f4d4270ab73 Mon Sep 17 00:00:00 2001 From: jgromes Date: Thu, 6 Jul 2023 11:19:18 +0200 Subject: [PATCH] [HAL] Implemented basic persistent storage --- src/ArduinoHal.cpp | 27 ++++++++++++++++++++ src/ArduinoHal.h | 3 +++ src/Hal.cpp | 29 +++++++++++++++++++++ src/Hal.h | 63 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/ArduinoHal.cpp b/src/ArduinoHal.cpp index d42f0d0b..5bcafb05 100644 --- a/src/ArduinoHal.cpp +++ b/src/ArduinoHal.cpp @@ -2,6 +2,8 @@ #if defined(RADIOLIB_BUILD_ARDUINO) +#include + ArduinoHal::ArduinoHal(): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&RADIOLIB_DEFAULT_SPI), initInterface(true) {} ArduinoHal::ArduinoHal(SPIClass& spi, SPISettings spiSettings): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&spi), spiSettings(spiSettings) {} @@ -98,6 +100,31 @@ void inline ArduinoHal::spiEnd() { spi->end(); } +void ArduinoHal::readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) { + #if defined(ESP32) + EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE); + #endif + for(size_t i = 0; i < len; i++) { + buff[i] = EEPROM.read(addr + i); + } + #if defined(ESP32) + EEPROM.end(); + #endif +} + +void ArduinoHal::writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) { + #if defined(ESP32) + EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE); + #endif + for(size_t i = 0; i < len; i++) { + EEPROM.write(addr + i, buff[i]); + } + #if defined(ESP32) + EEPROM.commit(); + EEPROM.end(); + #endif +} + void inline ArduinoHal::tone(uint32_t pin, unsigned int frequency, unsigned long duration) { #if !defined(RADIOLIB_TONE_UNSUPPORTED) if(pin == RADIOLIB_NC) { diff --git a/src/ArduinoHal.h b/src/ArduinoHal.h index 59b0f1aa..7f9620d1 100644 --- a/src/ArduinoHal.h +++ b/src/ArduinoHal.h @@ -51,6 +51,9 @@ class ArduinoHal : public RadioLibHal { void spiEndTransaction() override; void spiEnd() override; + void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override; + void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override; + // implementations of virtual RadioLibHal methods void init() override; void term() override; diff --git a/src/Hal.cpp b/src/Hal.cpp index 1a42aa15..bd65819f 100644 --- a/src/Hal.cpp +++ b/src/Hal.cpp @@ -33,3 +33,32 @@ void RadioLibHal::yield() { uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) { return(pin); } + +void RadioLibHal::wipePersistentStorage() { + uint8_t dummy = 0; + for(size_t i = 0; i < RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE; i++) { + this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + i, &dummy, sizeof(uint8_t)); + } +} + +template +void RadioLibHal::setPersistentParameter(uint32_t id, T val) { + uint8_t *ptr = (uint8_t*)&val; + this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id], ptr, sizeof(T)); +} + +template void RadioLibHal::setPersistentParameter(uint32_t id, uint8_t val); +template void RadioLibHal::setPersistentParameter(uint32_t id, uint16_t val); +template void RadioLibHal::setPersistentParameter(uint32_t id, uint32_t val); + +template +T RadioLibHal::getPersistentParameter(uint32_t id) { + T val = 0; + uint8_t *ptr = (uint8_t*)&val; + this->readPersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id], ptr, sizeof(T)); + return(val); +} + +template uint8_t RadioLibHal::getPersistentParameter(uint32_t id); +template uint16_t RadioLibHal::getPersistentParameter(uint32_t id); +template uint32_t RadioLibHal::getPersistentParameter(uint32_t id); diff --git a/src/Hal.h b/src/Hal.h index 87fb561e..1be814e3 100644 --- a/src/Hal.h +++ b/src/Hal.h @@ -4,8 +4,27 @@ #include #include +#include "BuildOpt.h" + +// list of persistent parameters +#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_NONCE_ID (0) +#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_ADDR_ID (1) +#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_UP_ID (2) +#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_DOWN_ID (3) + +static const uint32_t RadioLibPersistentParamTable[] = { + 0x00, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_NONCE_ID + 0x02, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_ADDR_ID + 0x06, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_UP_ID + 0x0A, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_DOWN_ID +}; + +// static assert to make sure that the persistent parameter table will fit to the allocated storage space +#define RADIOLIB_STATIC_ASSERT(test) typedef char radiolib_static_assert[( !!(test) )*2-1 ] +RADIOLIB_STATIC_ASSERT( sizeof(RadioLibPersistentParamTable) <= RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE ); + /*! - \class Hal + \class RadioLibHal \brief Hardware abstraction library base interface. */ class RadioLibHal { @@ -205,6 +224,48 @@ class RadioLibHal { \returns The interrupt number of a given pin. */ virtual uint32_t pinToInterrupt(uint32_t pin); + + /*! + \brief Method to read from persistent storage (e.g. EEPROM). + \param addr Address to start reading at. + \param buff Buffer to read into. + \param len Number of bytes to read. + */ + virtual void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) = 0; + + /*! + \brief Method to write to persistent storage (e.g. EEPROM). + \param addr Address to start writing to. + \param buff Buffer to write. + \param len Number of bytes to write. + */ + virtual void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) = 0; + + /*! + \brief Method to wipe the persistent storage by writing to 0. + Will write at most RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE bytes. + */ + void wipePersistentStorage(); + + /*! + \brief Method to set arbitrary parameter to persistent storage. + This method DOES NOT perform any endianness conversion, so the value + will be stored in the system endian! + \param id Parameter ID to save at. + \param val Value to set. + */ + template + void setPersistentParameter(uint32_t id, T val); + + /*! + \brief Method to get arbitrary parameter from persistent storage. + This method DOES NOT perform any endianness conversion, so the value + will be retrieved in the system endian! + \param id Parameter ID to load from. + \returns The lodaded value. + */ + template + T getPersistentParameter(uint32_t id); }; #endif