Skip to content

Commit a6f0ee3

Browse files
machine/samd21: implement watchdog
1 parent cb5f7ad commit a6f0ee3

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

src/machine/machine_atsamd21.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,3 +2027,62 @@ func checkFlashError() error {
20272027

20282028
return nil
20292029
}
2030+
2031+
// Watchdog provides access to the hardware watchdog available
2032+
// in the SAMD21.
2033+
var Watchdog = &watchdogImpl{}
2034+
2035+
const (
2036+
// WatchdogMaxTimeout in milliseconds (16s)
2037+
WatchdogMaxTimeout = (16384 * 1000) / 1024
2038+
)
2039+
2040+
type watchdogImpl struct{}
2041+
2042+
// Configure the watchdog.
2043+
//
2044+
// This method should not be called after the watchdog is started and on
2045+
// some platforms attempting to reconfigure after starting the watchdog
2046+
// is explicitly forbidden / will not work.
2047+
func (wd *watchdogImpl) Configure(config WatchdogConfig) error {
2048+
// Use OSCULP32K as source for Generic Clock Generator 8, divided by 32 to get 1.024kHz
2049+
sam.GCLK.GENDIV.Set(sam.GCLK_CLKCTRL_GEN_GCLK8 | (32 << sam.GCLK_GENDIV_DIV_Pos))
2050+
sam.GCLK.GENCTRL.Set(sam.GCLK_CLKCTRL_GEN_GCLK8 | (sam.GCLK_GENCTRL_SRC_OSCULP32K << sam.GCLK_GENCTRL_SRC_Pos) | sam.GCLK_GENCTRL_GENEN)
2051+
waitForSync()
2052+
2053+
// Use GCLK8 for watchdog
2054+
sam.GCLK.CLKCTRL.Set(sam.GCLK_CLKCTRL_ID_WDT | (sam.GCLK_CLKCTRL_GEN_GCLK8 << sam.GCLK_CLKCTRL_GEN_Pos) | sam.GCLK_CLKCTRL_CLKEN)
2055+
2056+
// Power on the watchdog peripheral
2057+
sam.PM.APBAMASK.SetBits(sam.PM_APBAMASK_WDT_)
2058+
2059+
// 1.024kHz clock
2060+
cycles := int((int64(config.TimeoutMillis) * 1024) / 1000)
2061+
2062+
// period is expressed as a power-of-two, starting at 8 / 1024ths of a second
2063+
period := uint8(0)
2064+
cfgCycles := 8
2065+
for cfgCycles < cycles {
2066+
period++
2067+
cfgCycles <<= 1
2068+
2069+
if period >= 0xB {
2070+
break
2071+
}
2072+
}
2073+
2074+
sam.WDT.CONFIG.Set(period << sam.WDT_CONFIG_PER_Pos)
2075+
2076+
return nil
2077+
}
2078+
2079+
// Starts the watchdog.
2080+
func (wd *watchdogImpl) Start() error {
2081+
sam.WDT.CTRL.SetBits(sam.WDT_CTRL_ENABLE)
2082+
return nil
2083+
}
2084+
2085+
// Update the watchdog, indicating that `source` is healthy.
2086+
func (wd *watchdogImpl) Update() {
2087+
sam.WDT.CLEAR.Set(sam.WDT_CLEAR_CLEAR_KEY)
2088+
}

src/machine/machine_atsamd51.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,6 +2357,5 @@ func (wd *watchdogImpl) Start() error {
23572357

23582358
// Update the watchdog, indicating that `source` is healthy.
23592359
func (wd *watchdogImpl) Update() {
2360-
// 0xA5 = magic value (see datasheet)
2361-
sam.WDT.CLEAR.Set(0xA5)
2360+
sam.WDT.CLEAR.Set(sam.WDT_CLEAR_CLEAR_KEY)
23622361
}

src/machine/watchdog.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build nrf52840 || nrf52833 || rp2040 || rp2350 || atsamd51 || atsame5x || stm32
1+
//go:build nrf52840 || nrf52833 || rp2040 || rp2350 || atsamd21 || atsamd51 || atsame5x || stm32
22

33
package machine
44

0 commit comments

Comments
 (0)