74 lines
3.0 KiB
C++
74 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <ctime>
|
|
|
|
/// Lightweight wall-clock facade.
|
|
///
|
|
/// The ESP32-C3 has no battery-backed RTC, so wall-clock time is lost on every
|
|
/// deep-sleep / power cycle. HalClock bridges this gap using three layers:
|
|
///
|
|
/// - **LP timer** (`esp_clk_rtc_time()`) — keeps running during deep sleep
|
|
/// when `keepClockAlive` is enabled (GPIO13 stays HIGH). Used to compute
|
|
/// elapsed time and correct the stored epoch on wake.
|
|
/// - **RTC memory** (`RTC_NOINIT_ATTR`) — survives deep sleep, lost on cold
|
|
/// boot. Stores the epoch + LP timer value captured before sleep.
|
|
/// - **NVS** (flash key-value store) — survives power cycles. Fallback when
|
|
/// RTC memory is unavailable (cold boot).
|
|
///
|
|
/// Usage:
|
|
/// 1. On boot, call `restore()` to seed the system clock from the best
|
|
/// available source (RTC memory + LP correction > NVS).
|
|
/// 2. After a successful NTP sync, call `syncNtp()`.
|
|
/// 3. Before entering deep sleep, call `saveBeforeSleep()`.
|
|
///
|
|
/// `now()` returns the best-effort epoch (0 if never synced).
|
|
namespace HalClock {
|
|
|
|
/// Perform an NTP sync (requires WiFi to be connected). Starts SNTP,
|
|
/// waits up to 5 seconds for completion, then captures the result.
|
|
/// Returns true if the sync succeeded.
|
|
bool syncNtp();
|
|
|
|
/// Apply timezone/DST rules via the POSIX TZ string for the given setting.
|
|
void applyTimezone(uint8_t timeZoneSetting);
|
|
|
|
/// Call just before deep sleep. Snapshots the current system time to RTC
|
|
/// memory and NVS so it can be restored on wake / cold boot. Pass true when
|
|
/// the LP timer is kept alive during sleep.
|
|
void saveBeforeSleep(bool keepLpAlive);
|
|
|
|
/// Call on boot to seed the system clock from the best available stored
|
|
/// value. When RTC memory is valid (deep-sleep wake) and the LP timer was
|
|
/// running, the restored time includes elapsed-time correction. Falls back
|
|
/// to NVS for cold boot (stale, but better than nothing).
|
|
void restore();
|
|
|
|
/// Returns the current best-effort wall-clock epoch, or 0 if the clock was
|
|
/// never set.
|
|
time_t now();
|
|
|
|
/// True if the clock has been set at least once (NTP or restore).
|
|
bool isSynced();
|
|
|
|
/// True if the last restore was from a backup (not NTP) — i.e. the clock
|
|
/// may have drifted. Cleared on NTP sync.
|
|
bool isApproximate();
|
|
|
|
/// Format the current time for display. Returns "--:--" if the clock was
|
|
/// never synced, prefixes with "~" if approximate.
|
|
/// When use24h is false, formats as "2:05pm" / "12:30am".
|
|
/// Output is written to `buf` (must be at least 16 bytes).
|
|
void formatTime(char* buf, size_t bufSize, bool use24h);
|
|
|
|
/// Format the current time for log timestamps. Returns "HH:MM:SS" if
|
|
/// synced, or an empty string if not.
|
|
void formatLogTime(char* buf, size_t bufSize);
|
|
|
|
/// Tear down WiFi cleanly. When skipNtpSync is false (default) and the
|
|
/// clock is approximate, performs an opportunistic NTP sync before
|
|
/// disconnecting — essentially free since we already have a connection.
|
|
void wifiOff(bool skipNtpSync = false);
|
|
|
|
} // namespace HalClock
|