diff --git a/include/storage.h b/include/storage.h index 7fb8b67..a7f4c17 100644 --- a/include/storage.h +++ b/include/storage.h @@ -26,6 +26,13 @@ constexpr long maximumTemperature = temperatureShiftForStorage + 255 * 500; constexpr uint8_t temperatureMaximumValue = 255; +enum class StorageFlags: uint8_t { + HasInitializedEEPROM = 1, + FailedToInitEEPROM = 2, + FailedToWriteEEPROM = 4, + RTCStorageOverflow = 5, +}; + void storageConfigure(bool isFirstRun); /** @@ -50,4 +57,6 @@ uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex); uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count); -void discardAllRecordedBytes(); \ No newline at end of file +void discardAllRecordedBytes(); + +uint8_t getStorageErrorFlags(); \ No newline at end of file diff --git a/src/storage.cpp b/src/storage.cpp index 24e5c9d..f4dae77 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -5,8 +5,7 @@ constexpr uint8_t absoluteTemperatureIndicator = 0xFF; -// The number of bytes to accumulate in RTC memory before writing it to EEPROM -constexpr uint32_t eepromChunkSize = 100; +RTC_DATA_ATTR uint8_t storageFlags = 0; // Storage for temperature measurements in RTC memory that survives deep sleep RTC_DATA_ATTR uint8_t data[rtcStorageSize]; @@ -18,31 +17,47 @@ RTC_DATA_ATTR uint32_t numberOfDiscardedMeasurements = 0; RTC_DATA_ATTR uint32_t eepromIndex = 0; RTC_DATA_ATTR bool isFirstRunAfterPowerOn = true; +constexpr uint16_t eepromOffset = sizeof(uint16_t); +constexpr uint16_t eepromDataSize = eepromSize - eepromOffset; + // Keeps the last valid temperatures for each sensor RTC_DATA_ATTR Temperature lastTemperatures[temperatureSensorCount]; RTC_DATA_ATTR uint32_t lastValidTemperatureTime[temperatureSensorCount]; RTC_DATA_ATTR uint8_t lastMeasurements[temperatureSensorCount] = {0, 0}; -bool didSetupEEPROM = false; +void setStorageFlag(StorageFlags flag) { + storageFlags |= static_cast(flag); +} -// On first boot, this is set to true; Afterwards it's remembered to be false -RTC_DATA_ATTR bool eepromIsConsideredEmpty = true; +void clearStorageFlag(StorageFlags flag) { + storageFlags &= ~static_cast(flag); +} -constexpr uint16_t eepromOffset = sizeof(uint16_t); -constexpr uint16_t eepromDataSize = eepromSize - eepromOffset; +bool hasStorageFlag(StorageFlags flag) { + return storageFlags & static_cast(flag); +} + +bool hasInitializedEEPROM() { + return hasStorageFlag(StorageFlags::HasInitializedEEPROM); +} + +void didInitializeEEPROM() { + setStorageFlag(StorageFlags::HasInitializedEEPROM); +} void setupEEPROMIfNeeded() { - if (didSetupEEPROM) { + if (hasInitializedEEPROM()) { return; } bool success = EEPROM.begin(eepromSize); if (!success) { Serial.println("Failed to set up EEPROM"); - didSetupEEPROM = false; + setStorageFlag(StorageFlags::FailedToInitEEPROM); } Serial.print("EEPROM size: "); Serial.println(eepromSize); - didSetupEEPROM = true; + clearStorageFlag(StorageFlags::FailedToInitEEPROM); + setStorageFlag(StorageFlags::HasInitializedEEPROM); } void resetLastMeasurements() { @@ -59,29 +74,18 @@ void storageConfigure(bool isFirstRun) { // Ensure that first values are stored resetLastMeasurements(); } -} - -uint16_t getNumberOfBytesStoredInEEPROM() { - if (eepromIsConsideredEmpty) { - return 0; // Discard any previous bytes - } - setupEEPROMIfNeeded(); - return EEPROM.readShort(0); + // Initialize EEPROM on every wake + // setupEEPROMIfNeeded(); + //setStorageFlag(StorageFlags::HasInitializedEEPROM); } void moveDataToEEPROMIfNeeded() { - if (dataIndex < eepromChunkSize) { - return; // Wait until more bytes are available + if (dataIndex < rtcStorageSize) { + return; } - // Determine EEPROM start address - uint16_t eepromIndex = getNumberOfBytesStoredInEEPROM() + eepromOffset; - if (eepromIndex >= eepromDataSize) { - return; // No more space in EEPROM, keep filling RTC memory - } - // Preparing to write new data, so set to false - eepromIsConsideredEmpty = false; + setupEEPROMIfNeeded(); - if (!didSetupEEPROM) { + if (!hasInitializedEEPROM()) { return; } @@ -89,7 +93,6 @@ void moveDataToEEPROMIfNeeded() { uint16_t bytesRemaining = eepromDataSize - eepromIndex; uint16_t bytesToWrite = min(dataIndex, bytesRemaining); EEPROM.writeBytes(eepromIndex, data, bytesToWrite); // TODO: Check that result == bytesToWrite - EEPROM.writeShort(0, eepromIndex + bytesToWrite); EEPROM.commit(); // Move remaining data to front of array (if any) @@ -99,8 +102,13 @@ void moveDataToEEPROMIfNeeded() { } void saveByteAtCurrentIndex(uint8_t byte) { + if (dataIndex >= rtcStorageSize) { + setStorageFlag(StorageFlags::RTCStorageOverflow); + return; + } data[dataIndex] = byte; dataIndex += 1; + //moveDataToEEPROMIfNeeded(); } uint8_t byteForAbsoluteTemperature(Temperature* temp) { @@ -199,13 +207,11 @@ void saveTemperatures(Temperature* temperatures) { saveByteAtCurrentIndex(valueToStore); } } - - moveDataToEEPROMIfNeeded(); numberOfMeasurements += 1; } uint16_t getTotalNumberOfStoredBytes() { - return getNumberOfBytesStoredInEEPROM() + dataIndex; + return dataIndex; // + eepromIndex; } uint16_t getNumberOfMeasurements() { @@ -225,8 +231,14 @@ uint16_t getTimeSinceValidTemperature(uint8_t sensorIndex) { } uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t count) { + // Copy remaining bytes from RTC memory + uint16_t remainingBytes = dataIndex - offset; + uint16_t bytesToCopy = min(count, remainingBytes); + memcpy(buffer, data + offset, count); + return bytesToCopy; + /* // TODO: Check limits - uint16_t eepromByteCount = getNumberOfBytesStoredInEEPROM(); + uint16_t eepromByteCount = eepromIndex; uint16_t endIndex = offset + count; uint16_t eepromStart = min(offset, eepromByteCount); uint16_t eepromEnd = min(endIndex, eepromByteCount); @@ -242,11 +254,16 @@ uint16_t getRecordedBytesAtOffset(uint8_t* buffer, uint16_t offset, uint16_t cou uint16_t bytesToCopyFromRTC = min(count, dataIndex); memcpy(buffer + bytesToCopyFromEEPROM, data + offset, bytesToCopyFromRTC); return bytesToCopyFromEEPROM + bytesToCopyFromRTC; + */ } void discardAllRecordedBytes() { - eepromIsConsideredEmpty = true; + eepromIndex = 0; dataIndex = 0; numberOfDiscardedMeasurements += numberOfMeasurements; numberOfMeasurements = 0; +} + +uint8_t getStorageErrorFlags() { + return storageFlags; } \ No newline at end of file