Files
ds3231/README.md
BlackMark dc89d0779a ide: the Atmel Studio solution master has, on the libavr port
master opens in Studio, so this branch should too. The solution builds
example/main.cpp — the port's only executable, the driver itself being an
INTERFACE library — for the ATmega328P that solution targeted, and the
acceptance is not that it builds but that it builds the same firmware: .text
comes out byte-identical to CMake's at 1242 B.

One project, one chip. Studio carries avrdevice as a project property, so the
attiny85 half of the presets would need a second project rather than a second
configuration; CMake stays the build system and covers both.

libavr is found beside this repo, anchored to the project directory rather than
written relative to the generated makefile, which runs from the configuration's
output directory. No LIBAVR_ROOT: a variable exported in a shell is invisible to
Studio launched from the Start menu.

Both configurations verified headless with LIBAVR_ROOT unset, and the flag
mirror checked against the CMake build's own compile_commands.json.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 19:33:39 +02:00

2.6 KiB

ds3231

Maxim DS3231 RTC driver on libavr: clock and alarm read/write, alarm interrupts, oscillator-stop detection, die temperature. One source runs on every libavr chip — TWI hardware on the mega328P, open-drain software I2C on the tinies. All bus errors surface as std::expected.

using bus = dev::i2c<{.frequency = 100_kHz}>;
using rtc = ds3231::device<bus>;

auto now = rtc::read_clock();       // result<date_time>
(void)rtc::set_alarm1({}, ds3231::alarm1_rate::once_per_second);

example/main.cpp is the full tour. Build with a libavr checkout:

LIBAVR_ROOT=/path/to/libavr cmake --preset attiny85-generated
cmake --build --preset attiny85-generated

Presets cover attiny85/atmega328p in both libavr modes (generated and reflect). The legacy yazoalfa-based driver lives on the master branch.

Atmel Studio

master carries a Studio solution, so this branch does too: ide/ds3231.atsln builds example/main.cpp for the ATmega328P — the chip that solution targeted — to a byte-identical .text (1242 B) against the CMake build, with the flags mirrored by hand. One project, one chip: avrdevice is a project-level property in Studio, so the attiny85 half of the presets has no equivalent here, and CMake remains the build system.

Studio expects libavr checked out beside this repo and finds it at $(MSBuildProjectDirectory)\..\..\libavr\include — anchored to the project, because a plain relative path is resolved against the generated makefile's directory (the configuration's output directory), not the project's. There is no LIBAVR_ROOT escape hatch: a variable exported in a shell is invisible to Studio launched from the Start menu. It also needs a GCC 16.1 toolchain registered as flavour avr-g++-16.1.0, nothing older reaching -std=c++26.

One generated file is required before the project will load, and one command checks the flags have not drifted (both from libavr's tools/atmelstudio/):

python ../libavr/tools/atmelstudio/componentinfo.py \
    ide/ds3231.componentinfo.xml --device ATmega328P
python ../libavr/tools/atmelstudio/check-flags.py --solution ide/ds3231.atsln \
    --compile-commands build/atmega328p-generated/compile_commands.json \
    --log build/atmelstudio.log

Release is what the gate compares, the presets defining no debug build; Debug carries the -Og -gdwarf-4 pair libavr's own debug preset uses.

Differences from legacy: weekday-rate alarms now actually set the DY bit (the old setAlarmHelper always cleared it), reads/writes are single coherent bus transactions, and errors are reported instead of ignored.