diff --git a/zephcore/adapters/clock/ZephyrRTCDiscover.c b/zephcore/adapters/clock/ZephyrRTCDiscover.c index 59ecf13..7f0b6b5 100644 --- a/zephcore/adapters/clock/ZephyrRTCDiscover.c +++ b/zephcore/adapters/clock/ZephyrRTCDiscover.c @@ -3,7 +3,7 @@ * * Compact raw-I2C hardware-RTC auto-discovery. See ZephyrRTCDiscover.h. * - * Register layouts (sec/min/hour/.../month/year, all BCD) and the per-chip + * Register layouts (sec/min/hour/.../month/year) and the per-chip * power-loss flags are carried in devicetree via the "zephcore,rtc-i2c" * binding, so this reader is generic — adding a new chip is a DT node, not * code. Maps were taken from Zephyr's own drivers (rtc_pcf8563.c, @@ -39,6 +39,7 @@ struct rtc_desc { uint8_t status_reg; /* power-loss flag register, or RTC_STATUS_IN_SECONDS */ uint8_t status_mask; /* "time unreliable" bit within status_reg */ const uint8_t *zero; /* 7 bytes of bits the data sheet shows as 0, or NULL */ + bool week_one_hot; /* weekday as one bit per day, not 0-6 */ #if RTC_RV3028_CFG const uint8_t *cfg; /* rv3028-eeprom-config triplets, or NULL */ uint8_t cfg_len; @@ -89,6 +90,7 @@ DT_FOREACH_STATUS_OKAY(RTC_COMPAT, RTC_CFG_ARRAY) .zero = COND_CODE_1( \ DT_NODE_HAS_PROP(node, zero_mask), \ (RTC_ZERO_NAME(node)), (NULL)), \ + .week_one_hot = DT_PROP(node, weekday_one_hot), \ RTC_CFG_FIELDS(node) \ .name = DT_NODE_FULL_NAME(node), \ }, @@ -227,7 +229,7 @@ static enum rtc_verdict rtc_identify(const struct rtc_desc *d, uint8_t blk[7]) return RTC_FOUND; } -/* The 7-byte BCD time block for an epoch, in d's register order. */ +/* The 7-byte time block for an epoch, in d's register order. */ static void rtc_time_block(const struct rtc_desc *d, uint32_t epoch, uint8_t blk[7]) { int y; @@ -244,7 +246,7 @@ static void rtc_time_block(const struct rtc_desc *d, uint32_t epoch, uint8_t blk blk[2] = BIN2BCD(hour); /* weekday occupies whichever of index 3/4 the date doesn't. */ blk[d->date_index] = BIN2BCD(day); - blk[d->date_index == 4 ? 3 : 4] = (uint8_t)dow; + blk[d->date_index == 4 ? 3 : 4] = d->week_one_hot ? (uint8_t)BIT(dow) : (uint8_t)dow; blk[5] = BIN2BCD(m); blk[6] = BIN2BCD((unsigned)(y % 100)); } diff --git a/zephcore/boards/common/rtc-i2c.dtsi b/zephcore/boards/common/rtc-i2c.dtsi index b4edf1c..2dabd13 100644 --- a/zephcore/boards/common/rtc-i2c.dtsi +++ b/zephcore/boards/common/rtc-i2c.dtsi @@ -78,4 +78,6 @@ rtc_rx8130ce: rtc-rx8130ce@32 { status-mask = <0x02>; /* VLF — voltage low */ /* RX8130CE Application Manual ETM50E-10, 13.2.1 Table 12, p. 22 */ zero-mask = [80 80 c0 80 c0 e0 00]; + /* 14.1.2 Table 15, p. 27: Sunday 01h ... Saturday 40h */ + weekday-one-hot; }; diff --git a/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts b/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts index 514578e..f9e07a0 100644 --- a/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts +++ b/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts @@ -354,6 +354,8 @@ date-index = <4>; status-reg = <0x0e>; status-mask = <0x02>; + /* RX8900 Application Manual ETM45E-11, 8.2.2 Table 15, p. 16 */ + weekday-one-hot; }; }; diff --git a/zephcore/dts/bindings/rtc/zephcore,rtc-i2c.yaml b/zephcore/dts/bindings/rtc/zephcore,rtc-i2c.yaml index f241ecc..efde767 100644 --- a/zephcore/dts/bindings/rtc/zephcore,rtc-i2c.yaml +++ b/zephcore/dts/bindings/rtc/zephcore,rtc-i2c.yaml @@ -6,9 +6,12 @@ # the properties below. This keeps the boot-time RTC restore compact # (~2-3 KB total, "Path B") instead of pulling in the full RTC subsystem. # -# All supported chips use a 7-byte BCD time block (sec, min, hour, then -# weekday/date, month, year) starting at "time-reg". Only the day-of-month -# byte offset varies between parts, captured by "date-index". +# All supported chips use a 7-byte time block (sec, min, hour, then +# weekday/date, month, year) starting at "time-reg", BCD in every field but +# the weekday. The day-of-month byte offset varies between parts, captured +# by "date-index". The weekday is written as a number 0-6 (Sunday 0), as +# Zephyr's DS3231, PCF8563 and RV3028 drivers write it, or as one bit per +# day where "weekday-one-hot" is set. description: ZephCore data-only I2C RTC descriptor (raw-I2C, no Zephyr RTC driver) @@ -20,7 +23,7 @@ properties: time-reg: type: int required: true - description: Register address of the seconds byte (start of the 7-byte BCD block). + description: Register address of the seconds byte (start of the 7-byte time block). date-index: type: int @@ -52,6 +55,13 @@ properties: this RTC and is never adopted. Leave it out for a chip whose unused bits are not documented as reading 0. + weekday-one-hot: + type: boolean + description: > + The weekday register holds one bit per day (Sunday bit 0 to Saturday + bit 6) rather than a number 0-6. Set it for a chip whose data sheet + says so, such as the RX8130CE. + rv3028-eeprom-config: type: uint8-array description: >