Same driver surface as the yazoalfa version — clock and alarm get/set, alarm interrupts, flag check/clear — plus oscillator-stop detection and die temperature. One source for tiny85 (software I2C) and mega328P (TWI), built against libavr in both generated and reflect mode, byte-identical .text across modes. Errors surface as std::expected instead of being dropped; weekday-rate alarms now really set the DY bit (legacy cleared it); multi-register access is one coherent bus transaction. Legacy stays on master. Co-Authored-By: Claude <noreply@anthropic.com>
33 lines
999 B
C++
33 lines
999 B
C++
#include <ds3231/ds3231.hpp>
|
|
#include <libavr/libavr.hpp>
|
|
|
|
using namespace avr::literals;
|
|
|
|
// One source for the tiny85 (open-drain software I2C on the USI pins) and
|
|
// the mega328P (TWI hardware). On first power-up the clock is seeded and
|
|
// alarm 1 armed; then the LED mirrors the seconds parity — a stuck LED
|
|
// means bus errors.
|
|
using dev = avr::device<{.clock = 8_MHz}>;
|
|
using bus = dev::i2c<{.frequency = 100_kHz}>;
|
|
using rtc = ds3231::device<bus>;
|
|
using led = dev::output<avr::pb3>;
|
|
|
|
int main()
|
|
{
|
|
avr::init<bus, led>();
|
|
|
|
if (auto stopped = rtc::oscillator_stopped(); stopped.value_or(false)) {
|
|
(void)rtc::write_clock({{2026, 1, 1}, {12, 0, 0}});
|
|
(void)rtc::set_alarm1({}, ds3231::alarm1_rate::once_per_second);
|
|
(void)rtc::clear_oscillator_stopped();
|
|
}
|
|
|
|
while (true) {
|
|
if (auto now = rtc::read_clock(); now.has_value())
|
|
led::write(now->second % 2 == 0);
|
|
if (auto fired = rtc::alarm1_fired(); fired.value_or(false))
|
|
(void)rtc::clear_alarm1();
|
|
dev::delay<100_ms>();
|
|
}
|
|
}
|