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