From 9db0393b65292ca6821d72486b36404f9d7e37b6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 2 Jun 2016 14:34:28 +0800 Subject: [PATCH] Update RTC memory example --- .../examples/RTCUserMemory/RTCUserMemory.ino | 114 +++++++++++++----- 1 file changed, 84 insertions(+), 30 deletions(-) diff --git a/libraries/esp8266/examples/RTCUserMemory/RTCUserMemory.ino b/libraries/esp8266/examples/RTCUserMemory/RTCUserMemory.ino index 6506ffd05..289e651a1 100644 --- a/libraries/esp8266/examples/RTCUserMemory/RTCUserMemory.ino +++ b/libraries/esp8266/examples/RTCUserMemory/RTCUserMemory.ino @@ -1,52 +1,106 @@ -// Example: Storing struct data in RTC user memory +// Example: Storing struct data in RTC user rtcDataory // -// Struct data with the maximum size of 512 bytes can be stored in the RTC user memory using the ESP-specifc APIs. -// The stored data can be retained between deep sleep cycles. However, the data might be lost after power cycling the ESP8266. +// Struct data with the maximum size of 512 bytes can be stored +// in the RTC user rtcDataory using the ESP-specifc APIs. +// The stored data can be retained between deep sleep cycles. +// However, the data might be lost after power cycling the ESP8266. +// +// This example uses deep sleep mode, so connect GPIO16 and RST +// pins before running it. // // Created Mar 30, 2016 by Macro Yau. // // This example code is in the public domain. -typedef struct { - byte data[512]; -} rtcUserMemory; +// CRC function used to ensure data validity +uint32_t calculateCRC32(const uint8_t *data, size_t length); -rtcUserMemory mem; +// helper function to dump memory contents as hex +void printMemory(); -void printMemory(bool readFromRtc) { - char buf[3]; - Serial.print(readFromRtc ? "Read: " : "Write: "); - for (int i = 0; i < sizeof(mem); i++) { - sprintf(buf, "%02X", mem.data[i]); - Serial.print(buf); - Serial.print(" "); - } - Serial.println(); -} +// Structure which will be stored in RTC memory. +// First field is CRC32, which is calculated based on the +// rest of structure contents. +// Any fields can go after CRC32. +// We use byte array as an example. +struct { + uint32_t crc32; + byte data[508]; +} rtcData; void setup() { Serial.begin(115200); Serial.println(); + delay(1000); - // Read struct from RTC user memory - if (ESP.rtcUserMemoryRead((uint32_t*) &mem, sizeof(mem))) { - printMemory(true); + // Read struct from RTC memory + if (ESP.rtcUserMemoryRead(0, (uint32_t*) &rtcData, sizeof(rtcData))) { + Serial.println("Read: "); + printMemory(); + Serial.println(); + uint32_t crcOfData = calculateCRC32(((uint8_t*) &rtcData) + 4, sizeof(rtcData) - 4); + Serial.print("CRC32 of data: "); + Serial.println(crcOfData, HEX); + Serial.print("CRC32 read from RTC: "); + Serial.println(rtcData.crc32, HEX); + if (crcOfData != rtcData.crc32) { + Serial.println("CRC32 in RTC memory doesn't match CRC32 of data. Data is probably invalid!"); + } + else { + Serial.println("CRC32 check ok, data is probably valid."); + } } // Generate new data set for the struct - for (int i = 0; i < sizeof(mem); i++) { - mem.data[i] = random(0, 128); + for (int i = 0; i < sizeof(rtcData); i++) { + rtcData.data[i] = random(0, 128); + } + // Update CRC32 of data + rtcData.crc32 = calculateCRC32(((uint8_t*) &rtcData) + 4, sizeof(rtcData) - 4); + // Write struct to RTC memory + if (ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData))) { + Serial.println("Write: "); + printMemory(); + Serial.println(); } - // Write struct to RTC user memory - if (ESP.rtcUserMemoryWrite((uint32_t*) &mem, sizeof(mem))) { - printMemory(false); - } - - // Enter deep sleep mode for 10 seconds - ESP.deepSleep(10e6); + Serial.println("Going into deep sleep for 5 seconds"); + ESP.deepSleep(5e6); } void loop() { - +} + +uint32_t calculateCRC32(const uint8_t *data, size_t length) +{ + uint32_t crc = 0xffffffff; + while (length--) { + uint8_t c = *data++; + for (uint32_t i = 0x80; i > 0; i >>= 1) { + bool bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + } + return crc; +} + +void printMemory() { + char buf[3]; + for (int i = 0; i < sizeof(rtcData); i++) { + sprintf(buf, "%02X", rtcData.data[i]); + Serial.print(buf); + if ((i + 1) % 32 == 0) { + Serial.println(); + } + else { + Serial.print(" "); + } + } + Serial.println(); }