From fb63a214c47df17629f72401cc8b42728366994c Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Sun, 11 May 2025 03:05:52 +0200 Subject: [PATCH 01/20] Added alarm features --- ds3231/ds3231.go | 209 ++++++++++++++++++++++++++++++++++++++++++++ ds3231/registers.go | 23 +++++ 2 files changed, 232 insertions(+) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 4c6f11958..a3d9c77f7 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -5,6 +5,7 @@ package ds3231 // import "tinygo.org/x/drivers/ds3231" import ( + "errors" "time" "tinygo.org/x/drivers" @@ -148,6 +149,108 @@ func (d *Device) ReadTime() (dt time.Time, err error) { return } +func (d *Device) GetSqwPinMode() SqwPinMode { + data := []uint8{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return SQW_OFF + } + print("CTRL: ") + println(data[0]) + + data[0] &= 0x1C // turn off INTCON + if data[0]&0x04 != 0 { + return SQW_OFF + } + + return SqwPinMode(data[0]) +} + +func (d *Device) SetSqwPinMode(mode SqwPinMode) error { + data := []uint8{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + + data[0] &^= 0x04 // turn off INTCON + data[0] &^= 0x18 // set freq bits to 0 + + data[0] |= uint8(mode) + + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + + return nil +} + +// SetAlarm1 set the alarm1 time +func (d *Device) SetAlarm1(dt time.Time, mode Alarm1Mode) error { + dataCtrl := []uint8{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + if err != nil { + return err + } + if dataCtrl[0]&(1< 0 { + day = dowToDS3231(int(dt.Weekday())) + } + + data := make([]uint8, 4) + data[0] = uint8ToBCD(uint8(dt.Second())) | A1M1 + data[1] = uint8ToBCD(uint8(dt.Minute())) | A1M2 + data[2] = uint8ToBCD(uint8(dt.Hour())) | A1M3 + data[3] = uint8ToBCD(uint8(day)) | A1M4 | DY_DT + + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_ALARMONE, data) + if err != nil { + return err + } + + dataCtrl[0] |= AlarmFlag_Alarm1 + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + if err != nil { + return err + } + + return nil +} + +// ReadAlarm1 returns the alarm1 time +func (d *Device) ReadAlarm1() (dt time.Time, err error) { + data := make([]uint8, 5) + err = legacy.ReadRegister(d.bus, uint8(d.Address), REG_ALARMONE, data) + if err != nil { + return + } + second := bcdToInt(data[0] & 0x7F) + minute := bcdToInt(data[1] & 0x7F) + hour := hoursBCDToInt(data[2] & 0x3F) + + isDayOfWeek := (data[3] & 0x40) >> 6 + var day int + if isDayOfWeek > 0 { + day = bcdToInt(data[3] & 0x0F) + } else { + day = bcdToInt(data[3] & 0x3F) + } + + dt = time.Date(2000, 5, day, hour, minute, second, 0, time.UTC) + return +} + // ReadTemperature returns the temperature in millicelsius (mC) func (d *Device) ReadTemperature() (int32, error) { data := make([]uint8, 2) @@ -158,6 +261,104 @@ func (d *Device) ReadTemperature() (int32, error) { return milliCelsius(data[0], data[1]), nil } +// disableAlarm disable alarm +func (d *Device) disableAlarm(alarm_num uint8) error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + data[0] &^= (1 << (alarm_num - 1)) + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + return nil +} + +// DisableAlarm1 disable alarm1 +func (d *Device) DisableAlarm1() error { + return d.disableAlarm(1) +} + +// clearAlarm clear status of alarm +func (d *Device) clearAlarm(alarm_num uint8) error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] &^= (1 << (alarm_num - 1)) + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + +// ClearAlarm1 clear status of alarm1 +func (d *Device) ClearAlarm1() error { + return d.clearAlarm(1) +} + +// IsAlarmFired get status of alarm +func (d *Device) isAlarmFired(alarm_num uint8) bool { + dataCtrl := []byte{0} + legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + dataCtrl[0] &^= (1 << (alarm_num - 1)) + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return false + } + return (data[0] & (1 << (alarm_num - 1))) != 0x00 +} + +// IsAlarm1Fired get status of alarm1 +func (d *Device) IsAlarm1Fired() bool { + return d.isAlarmFired(1) +} + +// Enable32K enables the 32KHz output +func (d *Device) Enable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] |= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + +// Disable32K disables the 32KHz output +func (d *Device) Disable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] &^= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + +// IsEnabled32K get status of 32KHz output +func (d *Device) IsEnabled32K() bool { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return false + } + return (data[0] & (1 << EN32KHZ)) != 0x00 +} + // milliCelsius converts the raw temperature bytes (msb and lsb) from the DS3231 // into a 32-bit signed integer in units of milli Celsius (1/1000 deg C). // @@ -200,3 +401,11 @@ func hoursBCDToInt(value uint8) (hour int) { } return } + +// dowToDS3231 converts the day of the week to internal DS3231 format +func dowToDS3231(d int) int { + if d == 0 { + return 7 + } + return d +} diff --git a/ds3231/registers.go b/ds3231/registers.go index 05f17608f..cc0f8304f 100644 --- a/ds3231/registers.go +++ b/ds3231/registers.go @@ -46,3 +46,26 @@ const ( AlarmTwo Mode = 4 ModeAlarmBoth Mode = 5 ) + +// SQW Pin Modes +type SqwPinMode uint8 + +const ( + SQW_OFF SqwPinMode = 0x1C + SQW_1HZ SqwPinMode = 0x00 + SQW_1KHZ SqwPinMode = 0x08 + SQW_4KHZ SqwPinMode = 0x10 + SQW_8KHZ SqwPinMode = 0x18 +) + +// ALarm1 Modes +type Alarm1Mode uint8 + +const ( + A1_PER_SECOND Alarm1Mode = 0x0F + A1_SECOND Alarm1Mode = 0x0E + A1_MINUTE Alarm1Mode = 0x0C + A1_HOUR Alarm1Mode = 0x08 + A1_DATE Alarm1Mode = 0x00 + A1_DAY Alarm1Mode = 0x10 +) From ca5990adb8c9d3b2e160056fbda6ad8c72e2d4a5 Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Tue, 27 May 2025 23:46:15 +0200 Subject: [PATCH 02/20] more functions --- ds3231/ds3231.go | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index a3d9c77f7..aee6d042b 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -155,8 +155,6 @@ func (d *Device) GetSqwPinMode() SqwPinMode { if err != nil { return SQW_OFF } - print("CTRL: ") - println(data[0]) data[0] &= 0x1C // turn off INTCON if data[0]&0x04 != 0 { @@ -218,7 +216,6 @@ func (d *Device) SetAlarm1(dt time.Time, mode Alarm1Mode) error { if err != nil { return err } - dataCtrl[0] |= AlarmFlag_Alarm1 err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) if err != nil { @@ -276,11 +273,46 @@ func (d *Device) disableAlarm(alarm_num uint8) error { return nil } +// enableAlarm enable alarm +func (d *Device) enableAlarm(alarm_num uint8) error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + data[0] |= (1 << (alarm_num - 1)) + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return err + } + return nil +} + +// isEnabledAlarm check if alarm is enabled for interrupt +func (d *Device) isEnabledAlarm(alarm_num uint8) bool { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) + if err != nil { + return false + } + return (data[0] & (1 << (alarm_num - 1))) != 0x00 +} + +// IsEnabledAlarm1 checks if alarm1 is enabled +func (d *Device) IsEnabledAlarm1() bool { + return d.isEnabledAlarm(1) +} + // DisableAlarm1 disable alarm1 func (d *Device) DisableAlarm1() error { return d.disableAlarm(1) } +// EnableAlarm1 enable alarm1 +func (d *Device) EnableAlarm1() error { + return d.enableAlarm(1) +} + // clearAlarm clear status of alarm func (d *Device) clearAlarm(alarm_num uint8) error { data := []byte{0} From a69e37b55128d1ee06b0827a9c087d1e282c7ffa Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 12:47:42 +0200 Subject: [PATCH 03/20] chore: fix typo --- ds3231/registers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ds3231/registers.go b/ds3231/registers.go index cc0f8304f..3474e8352 100644 --- a/ds3231/registers.go +++ b/ds3231/registers.go @@ -58,7 +58,7 @@ const ( SQW_8KHZ SqwPinMode = 0x18 ) -// ALarm1 Modes +// Alarm1 Modes type Alarm1Mode uint8 const ( From a64a50fd95ff9af02367eed3c75672d32687d386 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 12:48:04 +0200 Subject: [PATCH 04/20] feat(ds3231): add Alarm2Mode type and mode consts --- ds3231/registers.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ds3231/registers.go b/ds3231/registers.go index 3474e8352..3a7c1463e 100644 --- a/ds3231/registers.go +++ b/ds3231/registers.go @@ -69,3 +69,14 @@ const ( A1_DATE Alarm1Mode = 0x00 A1_DAY Alarm1Mode = 0x10 ) + +// Alarm2 Modes +type Alarm2Mode uint8 + +const ( + A2_PER_MINUTE Alarm2Mode = 0x07 + A2_MINUTE Alarm2Mode = 0x06 + A2_HOUR Alarm2Mode = 0x04 + A2_DATE Alarm2Mode = 0x00 + A2_DAY Alarm2Mode = 0x08 +) From cc767312691a4495ed1c139d850eac6b3b65349a Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 12:48:58 +0200 Subject: [PATCH 05/20] docs(ds3231): add docstrings for SQW functions --- ds3231/ds3231.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index aee6d042b..e53a92e80 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -149,6 +149,7 @@ func (d *Device) ReadTime() (dt time.Time, err error) { return } +// GetSqwPinMode returns the current square wave output frequency func (d *Device) GetSqwPinMode() SqwPinMode { data := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) @@ -164,6 +165,7 @@ func (d *Device) GetSqwPinMode() SqwPinMode { return SqwPinMode(data[0]) } +// SetSqwPinMode sets the square wave output mode to the given frequency func (d *Device) SetSqwPinMode(mode SqwPinMode) error { data := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) From 526faa13334511e348f8a240d4b75a5c3ff0661c Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 12:49:34 +0200 Subject: [PATCH 06/20] feat(ds3231): add methods for Alarm2 --- ds3231/ds3231.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index e53a92e80..ae4d243ad 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -250,6 +250,67 @@ func (d *Device) ReadAlarm1() (dt time.Time, err error) { return } +// SetAlarm2 set the alarm2 time +func (d *Device) SetAlarm2(dt time.Time, mode Alarm1Mode) error { + dataCtrl := []uint8{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + if err != nil { + return err + } + if dataCtrl[0]&(1< 0 { + day = dowToDS3231(int(dt.Weekday())) + } + + data := make([]uint8, 4) + data[0] = uint8ToBCD(uint8(dt.Minute())) | A2M2 + data[1] = uint8ToBCD(uint8(dt.Hour())) | A2M3 + data[2] = uint8ToBCD(uint8(day)) | A2M4 | DY_DT + + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_ALARMTWO, data) + if err != nil { + return err + } + dataCtrl[0] |= AlarmFlag_Alarm2 + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + if err != nil { + return err + } + + return nil +} + +// ReadAlarm2 returns the alarm2 time +func (d *Device) ReadAlarm2() (dt time.Time, err error) { + data := make([]uint8, 5) + err = legacy.ReadRegister(d.bus, uint8(d.Address), REG_ALARMTWO, data) + if err != nil { + return + } + minute := bcdToInt(data[0] & 0x7F) + hour := hoursBCDToInt(data[1] & 0x3F) + + isDayOfWeek := (data[2] & 0x40) >> 6 + var day int + if isDayOfWeek > 0 { + day = bcdToInt(data[2] & 0x0F) + } else { + day = bcdToInt(data[2] & 0x3F) + } + + dt = time.Date(2000, 5, day, hour, minute, 0, 0, time.UTC) + return +} + // ReadTemperature returns the temperature in millicelsius (mC) func (d *Device) ReadTemperature() (int32, error) { data := make([]uint8, 2) @@ -315,6 +376,21 @@ func (d *Device) EnableAlarm1() error { return d.enableAlarm(1) } +// IsEnabledAlarm2 checks if alarm2 is enabled +func (d *Device) IsEnabledAlarm2() bool { + return d.isEnabledAlarm(2) +} + +// DisableAlarm2 disable alarm2 +func (d *Device) DisableAlarm2() error { + return d.disableAlarm(2) +} + +// EnableAlarm2 enable alarm2 +func (d *Device) EnableAlarm2() error { + return d.enableAlarm(2) +} + // clearAlarm clear status of alarm func (d *Device) clearAlarm(alarm_num uint8) error { data := []byte{0} @@ -335,6 +411,11 @@ func (d *Device) ClearAlarm1() error { return d.clearAlarm(1) } +// ClearAlarm2 clear status of alarm2 +func (d *Device) ClearAlarm2() error { + return d.clearAlarm(2) +} + // IsAlarmFired get status of alarm func (d *Device) isAlarmFired(alarm_num uint8) bool { dataCtrl := []byte{0} @@ -353,6 +434,11 @@ func (d *Device) IsAlarm1Fired() bool { return d.isAlarmFired(1) } +// IsAlarm2Fired get status of alarm2 +func (d *Device) IsAlarm2Fired() bool { + return d.isAlarmFired(2) +} + // Enable32K enables the 32KHz output func (d *Device) Enable32K() error { data := []byte{0} From 747789ac0d113d4df6969188a0fcc9cd46cde8e6 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 15:24:18 +0200 Subject: [PATCH 07/20] fix(ds3231): use Alarm2Mode for SetAlarm2 method --- ds3231/ds3231.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index ae4d243ad..09dd00315 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -251,7 +251,7 @@ func (d *Device) ReadAlarm1() (dt time.Time, err error) { } // SetAlarm2 set the alarm2 time -func (d *Device) SetAlarm2(dt time.Time, mode Alarm1Mode) error { +func (d *Device) SetAlarm2(dt time.Time, mode Alarm2Mode) error { dataCtrl := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) if err != nil { From 7a68ff19a60d8e7d6939c21faffb685677d39aac Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 15:41:19 +0200 Subject: [PATCH 08/20] docs(ds3231): add example for alarms --- examples/ds3231/alarms/main.go | 89 +++++++++++++++++++++++++++++ examples/ds3231/{ => basic}/main.go | 0 2 files changed, 89 insertions(+) create mode 100644 examples/ds3231/alarms/main.go rename examples/ds3231/{ => basic}/main.go (100%) diff --git a/examples/ds3231/alarms/main.go b/examples/ds3231/alarms/main.go new file mode 100644 index 000000000..f09a18d25 --- /dev/null +++ b/examples/ds3231/alarms/main.go @@ -0,0 +1,89 @@ +// Connects to an DS3231 I2C Real Time Clock (RTC) and sets both alarms. It then repeatedly checks +// if the alarms are firing and prints out a message if that is the case. +package main + +import ( + "machine" + "time" + + "fmt" + + "tinygo.org/x/drivers/ds3231" +) + +func main() { + machine.I2C0.Configure(machine.I2CConfig{}) + + rtc := ds3231.New(machine.I2C0) + rtc.Configure() + + valid := rtc.IsTimeValid() + if !valid { + date := time.Date(2019, 12, 05, 20, 34, 12, 0, time.UTC) + rtc.SetTime(date) + } + + // Set alarm1 so it triggers when the seconds match 59 => repeats every minute at dd:hh:mm:59 + if err := rtc.SetAlarm1(time.Date(0, 0, 0, 0, 0, 59, 0, time.UTC), ds3231.A1_SECOND); err != nil { + fmt.Println("Error while setting Alarm1") + } + if err := rtc.EnableAlarm1(); err != nil { + fmt.Println("Error while enabling Alarm1") + } + + // Set alarm2 so it triggers when the minutes match 59 => repeats every hour at dd:hh:59:ss + if err := rtc.SetAlarm2(time.Date(0, 0, 0, 0, 59, 0, 0, time.UTC), ds3231.A2_MINUTE); err != nil { + fmt.Println("Error while setting Alarm2") + } + if err := rtc.EnableAlarm2(); err != nil { + fmt.Println("Error while enabling Alarm2") + } + + running := rtc.IsRunning() + if !running { + err := rtc.SetRunning(true) + if err != nil { + fmt.Println("Error configuring RTC") + } + } + + for { + dt, err := rtc.ReadTime() + if err != nil { + fmt.Println("Error reading date:", err) + continue + } + + if rtc.IsAlarm1Fired() { + fmt.Printf( + "Alarm1 fired at %d/%s/%02d %02d:%02d:%02d \r\n", + dt.Year(), + dt.Month(), + dt.Day(), + dt.Hour(), + dt.Minute(), + dt.Second(), + ) + if err := rtc.ClearAlarm1(); err != nil { + fmt.Println("Error while clearing alarm1") + } + } + + if rtc.IsAlarm2Fired() { + fmt.Printf( + "Alarm2 fired at %d/%s/%02d %02d:%02d:%02d \r\n", + dt.Year(), + dt.Month(), + dt.Day(), + dt.Hour(), + dt.Minute(), + dt.Second(), + ) + if err := rtc.ClearAlarm2(); err != nil { + fmt.Println("Error while clearing alarm2") + } + } + + time.Sleep(time.Second * 1) + } +} diff --git a/examples/ds3231/main.go b/examples/ds3231/basic/main.go similarity index 100% rename from examples/ds3231/main.go rename to examples/ds3231/basic/main.go From 1883e16f171f2b5cc18bfe245acaa91c8137e25c Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 24 Jul 2025 21:06:51 +0200 Subject: [PATCH 09/20] docs(ds3231): refactor alarms example make main function more concise to avoid llvm error for pico --- examples/ds3231/alarms/main.go | 43 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/examples/ds3231/alarms/main.go b/examples/ds3231/alarms/main.go index f09a18d25..0fa83b79b 100644 --- a/examples/ds3231/alarms/main.go +++ b/examples/ds3231/alarms/main.go @@ -31,8 +31,8 @@ func main() { fmt.Println("Error while enabling Alarm1") } - // Set alarm2 so it triggers when the minutes match 59 => repeats every hour at dd:hh:59:ss - if err := rtc.SetAlarm2(time.Date(0, 0, 0, 0, 59, 0, 0, time.UTC), ds3231.A2_MINUTE); err != nil { + // Set alarm2 so it triggers when the minutes match 35 => repeats every hour at dd:hh:35:ss + if err := rtc.SetAlarm2(time.Date(0, 0, 0, 0, 35, 0, 0, time.UTC), ds3231.A2_MINUTE); err != nil { fmt.Println("Error while setting Alarm2") } if err := rtc.EnableAlarm2(); err != nil { @@ -54,34 +54,31 @@ func main() { continue } - if rtc.IsAlarm1Fired() { - fmt.Printf( - "Alarm1 fired at %d/%s/%02d %02d:%02d:%02d \r\n", - dt.Year(), - dt.Month(), - dt.Day(), - dt.Hour(), - dt.Minute(), - dt.Second(), - ) + a1 := rtc.IsAlarm1Fired() + a2 := rtc.IsAlarm2Fired() + + fmt.Printf( + "%d/%s/%02d %02d:%02d:%02d A1: %t A2: %t\r\n", + dt.Year(), + dt.Month(), + dt.Day(), + dt.Hour(), + dt.Minute(), + dt.Second(), + a1, + a2, + ) + + if a1 { if err := rtc.ClearAlarm1(); err != nil { fmt.Println("Error while clearing alarm1") } } - - if rtc.IsAlarm2Fired() { - fmt.Printf( - "Alarm2 fired at %d/%s/%02d %02d:%02d:%02d \r\n", - dt.Year(), - dt.Month(), - dt.Day(), - dt.Hour(), - dt.Minute(), - dt.Second(), - ) + if a2 { if err := rtc.ClearAlarm2(); err != nil { fmt.Println("Error while clearing alarm2") } + } time.Sleep(time.Second * 1) From 7de15fec24451dfff9612a9995328a80972f3f47 Mon Sep 17 00:00:00 2001 From: gkits Date: Wed, 29 Oct 2025 09:23:05 +0100 Subject: [PATCH 10/20] ci(ds3231): split basic and alarm tests --- smoketest.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smoketest.sh b/smoketest.sh index b0035988f..b7dccb428 100755 --- a/smoketest.sh +++ b/smoketest.sh @@ -22,7 +22,8 @@ tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go -tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go +tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/alarms/main.go +tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/basic/main.go tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi From 6ac18d28dd3ab87dae227fa8a168843f1c7ffe75 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 10:16:43 +0100 Subject: [PATCH 11/20] style(ds3231): reorder private funcs to the bottom --- ds3231/ds3231.go | 134 +++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 09dd00315..a5fe14cb9 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -186,7 +186,7 @@ func (d *Device) SetSqwPinMode(mode SqwPinMode) error { return nil } -// SetAlarm1 set the alarm1 time +// SetAlarm1 sets the alarm1 time func (d *Device) SetAlarm1(dt time.Time, mode Alarm1Mode) error { dataCtrl := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) @@ -250,7 +250,7 @@ func (d *Device) ReadAlarm1() (dt time.Time, err error) { return } -// SetAlarm2 set the alarm2 time +// SetAlarm2 sets the alarm2 time func (d *Device) SetAlarm2(dt time.Time, mode Alarm2Mode) error { dataCtrl := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) @@ -321,6 +321,71 @@ func (d *Device) ReadTemperature() (int32, error) { return milliCelsius(data[0], data[1]), nil } +// IsEnabledAlarm1 checks if alarm1 is enabled +func (d *Device) IsEnabledAlarm1() bool { + return d.isEnabledAlarm(1) +} + +// DisableAlarm1 disables alarm1 +func (d *Device) DisableAlarm1() error { + return d.disableAlarm(1) +} + +// EnableAlarm1 enables alarm1 +func (d *Device) EnableAlarm1() error { + return d.enableAlarm(1) +} + +// IsEnabledAlarm2 checks if alarm2 is enabled +func (d *Device) IsEnabledAlarm2() bool { + return d.isEnabledAlarm(2) +} + +// DisableAlarm2 disables alarm2 +func (d *Device) DisableAlarm2() error { + return d.disableAlarm(2) +} + +// EnableAlarm2 enables alarm2 +func (d *Device) EnableAlarm2() error { + return d.enableAlarm(2) +} + +// ClearAlarm1 clears status of alarm1 +func (d *Device) ClearAlarm1() error { + return d.clearAlarm(1) +} + +// ClearAlarm2 clears status of alarm2 +func (d *Device) ClearAlarm2() error { + return d.clearAlarm(2) +} + +// IsAlarm1Fired returns the status of alarm1 +func (d *Device) IsAlarm1Fired() bool { + return d.isAlarmFired(1) +} + +// IsAlarm2Fired returns the status of alarm2 +func (d *Device) IsAlarm2Fired() bool { + return d.isAlarmFired(2) +} + +// Enable32K enables the 32KHz output +func (d *Device) Enable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] |= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + // disableAlarm disable alarm func (d *Device) disableAlarm(alarm_num uint8) error { data := []byte{0} @@ -361,36 +426,6 @@ func (d *Device) isEnabledAlarm(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } -// IsEnabledAlarm1 checks if alarm1 is enabled -func (d *Device) IsEnabledAlarm1() bool { - return d.isEnabledAlarm(1) -} - -// DisableAlarm1 disable alarm1 -func (d *Device) DisableAlarm1() error { - return d.disableAlarm(1) -} - -// EnableAlarm1 enable alarm1 -func (d *Device) EnableAlarm1() error { - return d.enableAlarm(1) -} - -// IsEnabledAlarm2 checks if alarm2 is enabled -func (d *Device) IsEnabledAlarm2() bool { - return d.isEnabledAlarm(2) -} - -// DisableAlarm2 disable alarm2 -func (d *Device) DisableAlarm2() error { - return d.disableAlarm(2) -} - -// EnableAlarm2 enable alarm2 -func (d *Device) EnableAlarm2() error { - return d.enableAlarm(2) -} - // clearAlarm clear status of alarm func (d *Device) clearAlarm(alarm_num uint8) error { data := []byte{0} @@ -406,16 +441,6 @@ func (d *Device) clearAlarm(alarm_num uint8) error { return nil } -// ClearAlarm1 clear status of alarm1 -func (d *Device) ClearAlarm1() error { - return d.clearAlarm(1) -} - -// ClearAlarm2 clear status of alarm2 -func (d *Device) ClearAlarm2() error { - return d.clearAlarm(2) -} - // IsAlarmFired get status of alarm func (d *Device) isAlarmFired(alarm_num uint8) bool { dataCtrl := []byte{0} @@ -429,31 +454,6 @@ func (d *Device) isAlarmFired(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } -// IsAlarm1Fired get status of alarm1 -func (d *Device) IsAlarm1Fired() bool { - return d.isAlarmFired(1) -} - -// IsAlarm2Fired get status of alarm2 -func (d *Device) IsAlarm2Fired() bool { - return d.isAlarmFired(2) -} - -// Enable32K enables the 32KHz output -func (d *Device) Enable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] |= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - return nil -} - // Disable32K disables the 32KHz output func (d *Device) Disable32K() error { data := []byte{0} From 772c0d10a7ddc0ed2db4e54f4b6e09b0b4c833af Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 11:23:34 +0100 Subject: [PATCH 12/20] docs(ds3231): add docstring for alarm modes --- ds3231/registers.go | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/ds3231/registers.go b/ds3231/registers.go index 3a7c1463e..b1dc60624 100644 --- a/ds3231/registers.go +++ b/ds3231/registers.go @@ -58,25 +58,38 @@ const ( SQW_8KHZ SqwPinMode = 0x18 ) -// Alarm1 Modes +// Alarm1 Modes define which parts of the set alarm time has to match the current timestamp of the clock device for alarm1 to fire type Alarm1Mode uint8 const ( + // Alarm1 fires every second A1_PER_SECOND Alarm1Mode = 0x0F - A1_SECOND Alarm1Mode = 0x0E - A1_MINUTE Alarm1Mode = 0x0C - A1_HOUR Alarm1Mode = 0x08 - A1_DATE Alarm1Mode = 0x00 - A1_DAY Alarm1Mode = 0x10 + // Alarm1 fires when the seconds match + A1_SECOND Alarm1Mode = 0x0E + // Alarm1 fires when both seconds and minutes match + A1_MINUTE Alarm1Mode = 0x0C + // Alarm1 fires when seconds, minutes and hours match + A1_HOUR Alarm1Mode = 0x08 + // Alarm1 fires when seconds, minutes, hours and the day of the month match + A1_DATE Alarm1Mode = 0x00 + // Alarm1 fires when seconds, minutes, hours and the day of the week match + A1_DAY Alarm1Mode = 0x10 ) -// Alarm2 Modes +// Alarm2 Modes define which parts of the set alarm time has to match the current timestamp of the clock device for alarm2 to fire. +// +// Alarm2 only support matching down to the minute unlike alarm1 which supports matching down to the second. type Alarm2Mode uint8 const ( + // Alarm2 fires every minute A2_PER_MINUTE Alarm2Mode = 0x07 - A2_MINUTE Alarm2Mode = 0x06 - A2_HOUR Alarm2Mode = 0x04 - A2_DATE Alarm2Mode = 0x00 - A2_DAY Alarm2Mode = 0x08 + // Alarm2 fires when the minutes match + A2_MINUTE Alarm2Mode = 0x06 + // Alarm2 fires when both minutes and hours match + A2_HOUR Alarm2Mode = 0x04 + // Alarm2 fires when minutes, hours and the day of the month match + A2_DATE Alarm2Mode = 0x00 + // Alarm2 fires when minutes, hours and the day of the week match + A2_DAY Alarm2Mode = 0x08 ) From b4bf209e563c24f014938c89407ad32466b18756 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 11:24:52 +0100 Subject: [PATCH 13/20] docs(ds3231): make alarm docstrings more descriptive --- ds3231/ds3231.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index a5fe14cb9..10f62f9fa 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -186,7 +186,7 @@ func (d *Device) SetSqwPinMode(mode SqwPinMode) error { return nil } -// SetAlarm1 sets the alarm1 time +// SetAlarm1 sets alarm1 to the given time and mode func (d *Device) SetAlarm1(dt time.Time, mode Alarm1Mode) error { dataCtrl := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) @@ -250,7 +250,7 @@ func (d *Device) ReadAlarm1() (dt time.Time, err error) { return } -// SetAlarm2 sets the alarm2 time +// SetAlarm2 sets alarm2 to the given time and mode func (d *Device) SetAlarm2(dt time.Time, mode Alarm2Mode) error { dataCtrl := []uint8{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) @@ -321,7 +321,7 @@ func (d *Device) ReadTemperature() (int32, error) { return milliCelsius(data[0], data[1]), nil } -// IsEnabledAlarm1 checks if alarm1 is enabled +// IsEnabledAlarm1 returns true when alarm1 is enabled func (d *Device) IsEnabledAlarm1() bool { return d.isEnabledAlarm(1) } @@ -336,7 +336,7 @@ func (d *Device) EnableAlarm1() error { return d.enableAlarm(1) } -// IsEnabledAlarm2 checks if alarm2 is enabled +// IsEnabledAlarm2 returns true when alarm2 is enabled func (d *Device) IsEnabledAlarm2() bool { return d.isEnabledAlarm(2) } @@ -361,12 +361,12 @@ func (d *Device) ClearAlarm2() error { return d.clearAlarm(2) } -// IsAlarm1Fired returns the status of alarm1 +// IsAlarm1Fired returns true if alarm1 is firing func (d *Device) IsAlarm1Fired() bool { return d.isAlarmFired(1) } -// IsAlarm2Fired returns the status of alarm2 +// IsAlarm2Fired returns true if alarm2 is firing func (d *Device) IsAlarm2Fired() bool { return d.isAlarmFired(2) } From 3893fe36bc8960c338189a0e270cf1c67bec00e4 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 11:28:54 +0100 Subject: [PATCH 14/20] chore(ds3231): fix typo in docstring --- ds3231/registers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ds3231/registers.go b/ds3231/registers.go index b1dc60624..98e8fb2cd 100644 --- a/ds3231/registers.go +++ b/ds3231/registers.go @@ -78,7 +78,7 @@ const ( // Alarm2 Modes define which parts of the set alarm time has to match the current timestamp of the clock device for alarm2 to fire. // -// Alarm2 only support matching down to the minute unlike alarm1 which supports matching down to the second. +// Alarm2 only supports matching down to the minute unlike alarm1 which supports matching down to the second. type Alarm2Mode uint8 const ( From 3c0ee530d44458aa2329b270813ef5ca7ebc07ac Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 15:44:24 +0100 Subject: [PATCH 15/20] style(ds3231): reorder public functions --- ds3231/ds3231.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 10f62f9fa..af95e5a0c 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -149,6 +149,16 @@ func (d *Device) ReadTime() (dt time.Time, err error) { return } +// ReadTemperature returns the temperature in millicelsius (mC) +func (d *Device) ReadTemperature() (int32, error) { + data := make([]uint8, 2) + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_TEMP, data) + if err != nil { + return 0, err + } + return milliCelsius(data[0], data[1]), nil +} + // GetSqwPinMode returns the current square wave output frequency func (d *Device) GetSqwPinMode() SqwPinMode { data := []uint8{0} @@ -311,16 +321,6 @@ func (d *Device) ReadAlarm2() (dt time.Time, err error) { return } -// ReadTemperature returns the temperature in millicelsius (mC) -func (d *Device) ReadTemperature() (int32, error) { - data := make([]uint8, 2) - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_TEMP, data) - if err != nil { - return 0, err - } - return milliCelsius(data[0], data[1]), nil -} - // IsEnabledAlarm1 returns true when alarm1 is enabled func (d *Device) IsEnabledAlarm1() bool { return d.isEnabledAlarm(1) From 0c65ad7701761e11629d040661501c28bc366d5e Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 16:16:31 +0100 Subject: [PATCH 16/20] style(ds3231): reorder private methods --- ds3231/ds3231.go | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index af95e5a0c..426fe176b 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -386,6 +386,31 @@ func (d *Device) Enable32K() error { return nil } +// Disable32K disables the 32KHz output +func (d *Device) Disable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] &^= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + +// IsEnabled32K get status of 32KHz output +func (d *Device) IsEnabled32K() bool { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return false + } + return (data[0] & (1 << EN32KHZ)) != 0x00 +} + // disableAlarm disable alarm func (d *Device) disableAlarm(alarm_num uint8) error { data := []byte{0} @@ -454,31 +479,6 @@ func (d *Device) isAlarmFired(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } -// Disable32K disables the 32KHz output -func (d *Device) Disable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] &^= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - return nil -} - -// IsEnabled32K get status of 32KHz output -func (d *Device) IsEnabled32K() bool { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return false - } - return (data[0] & (1 << EN32KHZ)) != 0x00 -} - // milliCelsius converts the raw temperature bytes (msb and lsb) from the DS3231 // into a 32-bit signed integer in units of milli Celsius (1/1000 deg C). // From ca3b73ae94913bf034f7e9bde6ac182ef36930a2 Mon Sep 17 00:00:00 2001 From: gkits Date: Thu, 30 Oct 2025 16:44:46 +0100 Subject: [PATCH 17/20] chore(ds3231): add missing error handling --- ds3231/ds3231.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 426fe176b..86c74e04d 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -469,11 +469,12 @@ func (d *Device) clearAlarm(alarm_num uint8) error { // IsAlarmFired get status of alarm func (d *Device) isAlarmFired(alarm_num uint8) bool { dataCtrl := []byte{0} - legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl) + if err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl); err != nil { + return false + } dataCtrl[0] &^= (1 << (alarm_num - 1)) data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { + if err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data); err != nil { return false } return (data[0] & (1 << (alarm_num - 1))) != 0x00 From 4b0b841ddc4044e935496379141e9cdc78a1a6fb Mon Sep 17 00:00:00 2001 From: gkits Date: Fri, 7 Nov 2025 15:50:06 +0100 Subject: [PATCH 18/20] feat(ds3231): use setter funcs for en/disabling instead of separate funcs --- ds3231/ds3231.go | 95 +++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 86c74e04d..008c05c28 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -326,31 +326,27 @@ func (d *Device) IsEnabledAlarm1() bool { return d.isEnabledAlarm(1) } -// DisableAlarm1 disables alarm1 -func (d *Device) DisableAlarm1() error { +// SetEnabledAlarm1 sets the enabled status of alarm1 +func (d *Device) SetEnabledAlarm1(enable bool) error { + if enable { + return d.enableAlarm(1) + } return d.disableAlarm(1) } -// EnableAlarm1 enables alarm1 -func (d *Device) EnableAlarm1() error { - return d.enableAlarm(1) -} - // IsEnabledAlarm2 returns true when alarm2 is enabled func (d *Device) IsEnabledAlarm2() bool { return d.isEnabledAlarm(2) } -// DisableAlarm2 disables alarm2 -func (d *Device) DisableAlarm2() error { +// SetEnabledAlarm2 sets the enabled status of alarm2 +func (d *Device) SetEnabledAlarm2(enable bool) error { + if enable { + return d.enableAlarm(2) + } return d.disableAlarm(2) } -// EnableAlarm2 enables alarm2 -func (d *Device) EnableAlarm2() error { - return d.enableAlarm(2) -} - // ClearAlarm1 clears status of alarm1 func (d *Device) ClearAlarm1() error { return d.clearAlarm(1) @@ -361,47 +357,25 @@ func (d *Device) ClearAlarm2() error { return d.clearAlarm(2) } -// IsAlarm1Fired returns true if alarm1 is firing +// IsAlarm1Fired returns true when alarm1 is firing func (d *Device) IsAlarm1Fired() bool { return d.isAlarmFired(1) } -// IsAlarm2Fired returns true if alarm2 is firing +// IsAlarm2Fired returns true when alarm2 is firing func (d *Device) IsAlarm2Fired() bool { return d.isAlarmFired(2) } -// Enable32K enables the 32KHz output -func (d *Device) Enable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] |= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err +// SetEnable32K sets the enabled status of the 32KHz output +func (d *Device) SetEnable32K(enable bool) error { + if enable { + return d.enable32K() } - return nil + return d.disable32K() } -// Disable32K disables the 32KHz output -func (d *Device) Disable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] &^= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - return nil -} - -// IsEnabled32K get status of 32KHz output +// IsEnabled32K returns true when the 32KHz output is enabled func (d *Device) IsEnabled32K() bool { data := []byte{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) @@ -411,7 +385,6 @@ func (d *Device) IsEnabled32K() bool { return (data[0] & (1 << EN32KHZ)) != 0x00 } -// disableAlarm disable alarm func (d *Device) disableAlarm(alarm_num uint8) error { data := []byte{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) @@ -426,7 +399,6 @@ func (d *Device) disableAlarm(alarm_num uint8) error { return nil } -// enableAlarm enable alarm func (d *Device) enableAlarm(alarm_num uint8) error { data := []byte{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) @@ -441,7 +413,6 @@ func (d *Device) enableAlarm(alarm_num uint8) error { return nil } -// isEnabledAlarm check if alarm is enabled for interrupt func (d *Device) isEnabledAlarm(alarm_num uint8) bool { data := []byte{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, data) @@ -451,7 +422,6 @@ func (d *Device) isEnabledAlarm(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } -// clearAlarm clear status of alarm func (d *Device) clearAlarm(alarm_num uint8) error { data := []byte{0} err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) @@ -466,7 +436,6 @@ func (d *Device) clearAlarm(alarm_num uint8) error { return nil } -// IsAlarmFired get status of alarm func (d *Device) isAlarmFired(alarm_num uint8) bool { dataCtrl := []byte{0} if err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_CONTROL, dataCtrl); err != nil { @@ -480,6 +449,34 @@ func (d *Device) isAlarmFired(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } +func (d *Device) enable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] |= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + +func (d *Device) disable32K() error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + data[0] &^= 1 << EN32KHZ + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil +} + // milliCelsius converts the raw temperature bytes (msb and lsb) from the DS3231 // into a 32-bit signed integer in units of milli Celsius (1/1000 deg C). // From fc1b8481f64ec5f4384828785f0ae2005cdb2d9d Mon Sep 17 00:00:00 2001 From: gkits Date: Fri, 7 Nov 2025 15:51:49 +0100 Subject: [PATCH 19/20] fix(ds3231): correctly enable alarms in example --- examples/ds3231/alarms/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ds3231/alarms/main.go b/examples/ds3231/alarms/main.go index 0fa83b79b..08b516694 100644 --- a/examples/ds3231/alarms/main.go +++ b/examples/ds3231/alarms/main.go @@ -27,7 +27,7 @@ func main() { if err := rtc.SetAlarm1(time.Date(0, 0, 0, 0, 0, 59, 0, time.UTC), ds3231.A1_SECOND); err != nil { fmt.Println("Error while setting Alarm1") } - if err := rtc.EnableAlarm1(); err != nil { + if err := rtc.SetEnabledAlarm1(true); err != nil { fmt.Println("Error while enabling Alarm1") } @@ -35,7 +35,7 @@ func main() { if err := rtc.SetAlarm2(time.Date(0, 0, 0, 0, 35, 0, 0, time.UTC), ds3231.A2_MINUTE); err != nil { fmt.Println("Error while setting Alarm2") } - if err := rtc.EnableAlarm2(); err != nil { + if err := rtc.SetEnabledAlarm2(true); err != nil { fmt.Println("Error while enabling Alarm2") } From 2be99cce936fe66c584c053c0e996196e21ef806 Mon Sep 17 00:00:00 2001 From: gkits Date: Fri, 7 Nov 2025 15:57:12 +0100 Subject: [PATCH 20/20] style(ds3231): rename SetEnable32K to SetEnabled32K for consistency --- ds3231/ds3231.go | 49 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/ds3231/ds3231.go b/ds3231/ds3231.go index 008c05c28..b6ec59433 100644 --- a/ds3231/ds3231.go +++ b/ds3231/ds3231.go @@ -367,12 +367,25 @@ func (d *Device) IsAlarm2Fired() bool { return d.isAlarmFired(2) } -// SetEnable32K sets the enabled status of the 32KHz output -func (d *Device) SetEnable32K(enable bool) error { +// SetEnabled32K sets the enabled status of the 32KHz output +func (d *Device) SetEnabled32K(enable bool) error { + data := []byte{0} + err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + if enable { - return d.enable32K() + data[0] |= 1 << EN32KHZ + } else { + data[0] &^= 1 << EN32KHZ } - return d.disable32K() + + err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) + if err != nil { + return err + } + return nil } // IsEnabled32K returns true when the 32KHz output is enabled @@ -449,34 +462,6 @@ func (d *Device) isAlarmFired(alarm_num uint8) bool { return (data[0] & (1 << (alarm_num - 1))) != 0x00 } -func (d *Device) enable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] |= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - return nil -} - -func (d *Device) disable32K() error { - data := []byte{0} - err := legacy.ReadRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - data[0] &^= 1 << EN32KHZ - err = legacy.WriteRegister(d.bus, uint8(d.Address), REG_STATUS, data) - if err != nil { - return err - } - return nil -} - // milliCelsius converts the raw temperature bytes (msb and lsb) from the DS3231 // into a 32-bit signed integer in units of milli Celsius (1/1000 deg C). //