#include #include 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; using led = dev::output; int main() { avr::init(); if (auto stopped = rtc::oscillator_stopped(); stopped.value_or(false)) { // A failed seed leaves the LED dark before the loop ever runs - the // same signal a stuck bus gives it below. const bool seeded = rtc::write_clock({{2026, 1, 1}, {12, 0, 0}}) && rtc::set_alarm1({}, ds3231::alarm1_rate::once_per_second) && rtc::clear_oscillator_stopped(); led::write(seeded); } 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) && !rtc::clear_alarm1()) { led::clear(); // a clear that failed holds the LED dark, like any bus error } dev::delay<100_ms>(); } }