/* RTMEM MODULE Copyright (C) 2019 by Maxim Prokhorov */ #pragma once #include #include #include "espurna.h" // Base address of USER RTC memory // https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map#memmory-mapped-io-registers #define RTCMEM_ADDR_BASE (0x60001200) // RTC memory is accessed using blocks of 4 bytes. // Blocks 0..63 are reserved by the SDK, 64..192 are available to the user. // Blocks 64..96 are reserved by the eboot 'struct eboot_command' (128 -> (128 / 4) -> 32): // https://github.com/esp8266/Arduino/blob/master/bootloaders/eboot/eboot_command.h #define RTCMEM_OFFSET 32u #define RTCMEM_ADDR (RTCMEM_ADDR_BASE + (RTCMEM_OFFSET * 4u)) #define RTCMEM_BLOCKS 96u // Change this when modifying RtcmemData #define RTCMEM_MAGIC 0x46535076 // XXX: All access must be 4-byte aligned and always at full length. // Exactly like PROGMEM works. For example, using bitfields / inner structs / etc: // ... // uint32_t a : 8; // uint32_t b : 8; // uint32_t c : 8; // uint32_t d : 8; // ... // // This would not write the expected thing: // mem->d = 4; // TODO replace with custom memory segment in ldscript? // `magic` would need to be tracked differently struct RtcmemEnergy { uint32_t kwh; uint32_t ws; }; struct RtcmemData { uint32_t magic; uint32_t sys; uint32_t relay; uint32_t mqtt; uint64_t light; RtcmemEnergy energy[4]; }; static_assert(sizeof(RtcmemData) <= (RTCMEM_BLOCKS * 4u), "RTCMEM struct is too big"); constexpr uint8_t RtcmemSize = (sizeof(RtcmemData) / 4u); extern volatile RtcmemData* Rtcmem; bool rtcmemStatus(); void rtcmemSetup();