fix: an alarm clear keeps the other alarm's flag, and arming keeps BBSQW
A1F and A2F ignore a written 1, so the status write-back now writes the flag not being cleared as 1: an alarm firing between the read and the write was cleared with the other. BBSQW gates the alarm interrupt on battery as well as the square wave (19-5170 rev. 4), so arming an alarm no longer clears it. Both register computations are consteval-tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
50c424d3d2
commit
4df536d0a5
2 files changed
+52
-22
No files matched your search
@@ -79,4 +79,22 @@ static_assert(static_cast<std::uint8_t>(alarm2_rate::once_per_minute) ==
|
||||
static_assert(static_cast<std::uint8_t>(alarm2_rate::weekday_time_match) ==
|
||||
static_cast<std::uint8_t>(alarm1_rate::weekday_time_match) >> 1);
|
||||
|
||||
// A1F and A2F ignore a written 1 and OSF holds until written 0 (19-5170,
|
||||
// Status Register): clearing one alarm must write the other as 1, or an alarm
|
||||
// firing between the read and the write is lost.
|
||||
using ds3231::detail::status_clearing;
|
||||
static_assert(status_clearing(0x00, 0x01) == 0x02); // A2F set after the read survives
|
||||
static_assert(status_clearing(0x03, 0x02) == 0x01);
|
||||
static_assert(status_clearing(0x88, 0x01) == 0x8a); // OSF and EN32kHz kept as read
|
||||
static_assert(status_clearing(0x80, 0x80) == 0x03);
|
||||
|
||||
// BBSQW keeps INT/SQW driven on battery for the alarm interrupt as well as the
|
||||
// square wave (19-5170, Control Register and rev. 4), so arming an alarm must
|
||||
// leave it as found.
|
||||
using ds3231::alarm_interrupt;
|
||||
using ds3231::detail::control_with;
|
||||
static_assert(control_with(0x40, 0x01, alarm_interrupt::on) == 0x45);
|
||||
static_assert(control_with(0x00, 0x02, alarm_interrupt::on) == 0x06);
|
||||
static_assert(control_with(0x47, 0x01, alarm_interrupt::off) == 0x46);
|
||||
|
||||
} // namespace
|
||||
Reference in new issue
Block a user