microReticulumTbeam/lib/tbeam_clock/src/TBeamClock.h

75 lines
2.1 KiB
C++

#pragma once
#include <Arduino.h>
#include <Wire.h>
namespace tbeam
{
struct DateTime
{
uint16_t year = 0;
uint8_t month = 0;
uint8_t day = 0;
uint8_t hour = 0;
uint8_t minute = 0;
uint8_t second = 0;
uint8_t weekday = 0;
};
struct ClockConfig
{
uint8_t rtcAddress = 0x51;
int sda = -1;
int scl = -1;
bool beginWire = true;
};
class TBeamClock
{
public:
explicit TBeamClock(TwoWire &wire = Wire1);
bool begin(const ClockConfig &config = ClockConfig{});
void update();
bool readRtc(DateTime &out, bool &lowVoltageFlag) const;
bool readValidRtc(DateTime &out, int64_t *epochOut = nullptr) const;
bool writeRtc(const DateTime &dt) const;
bool ready() const { return ready_; }
bool valid() const { return valid_; }
bool lowVoltage() const { return lowVoltage_; }
const DateTime &lastRtc() const { return lastRtc_; }
int64_t lastEpoch() const { return lastEpoch_; }
const char *lastError() const { return lastError_; }
static bool isValidDateTime(const DateTime &dt);
static int64_t toEpochSeconds(const DateTime &dt);
static bool fromEpochSeconds(int64_t seconds, DateTime &out);
static void formatIsoUtc(const DateTime &dt, char *out, size_t outSize);
static void formatCompactUtc(const DateTime &dt, char *out, size_t outSize);
static void makeRunId(const DateTime &dt, const char *boardId, char *out, size_t outSize);
static bool parseDateTime(const char *text, DateTime &out);
private:
static uint8_t toBcd(uint8_t value);
static uint8_t fromBcd(uint8_t value);
static bool isLeapYear(uint16_t year);
static uint8_t daysInMonth(uint16_t year, uint8_t month);
static int64_t daysFromCivil(int year, unsigned month, unsigned day);
void setError(const char *message) const;
void clearError() const;
TwoWire &wire_;
ClockConfig config_{};
bool ready_ = false;
bool valid_ = false;
bool lowVoltage_ = false;
DateTime lastRtc_{};
int64_t lastEpoch_ = 0;
mutable char lastError_[128] = {};
};
} // namespace tbeam