github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_rp2040_watchdog.go (about) 1 //go:build rp2040 2 3 package machine 4 5 import ( 6 "device/rp" 7 ) 8 9 // Watchdog provides access to the hardware watchdog available 10 // in the RP2040. 11 var Watchdog = &watchdogImpl{} 12 13 const ( 14 // WatchdogMaxTimeout in milliseconds (approx 8.3s). 15 // 16 // Nominal 1us per watchdog tick, 24-bit counter, 17 // but due to errata two ticks consumed per 1us. 18 // See: Errata RP2040-E1 19 WatchdogMaxTimeout = (rp.WATCHDOG_LOAD_LOAD_Msk / 1000) / 2 20 ) 21 22 type watchdogImpl struct { 23 // The value to reset the counter to on each Update 24 loadValue uint32 25 } 26 27 // Configure the watchdog. 28 // 29 // This method should not be called after the watchdog is started and on 30 // some platforms attempting to reconfigure after starting the watchdog 31 // is explicitly forbidden / will not work. 32 func (wd *watchdogImpl) Configure(config WatchdogConfig) error { 33 // x2 due to errata RP2040-E1 34 wd.loadValue = config.TimeoutMillis * 1000 * 2 35 if wd.loadValue > rp.WATCHDOG_LOAD_LOAD_Msk { 36 wd.loadValue = rp.WATCHDOG_LOAD_LOAD_Msk 37 } 38 39 rp.WATCHDOG.CTRL.ClearBits(rp.WATCHDOG_CTRL_ENABLE) 40 41 // Reset everything apart from ROSC and XOSC 42 rp.PSM.WDSEL.Set(0x0001ffff &^ (rp.PSM_WDSEL_ROSC | rp.PSM_WDSEL_XOSC)) 43 44 // Pause watchdog during debug 45 rp.WATCHDOG.CTRL.SetBits(rp.WATCHDOG_CTRL_PAUSE_DBG0 | rp.WATCHDOG_CTRL_PAUSE_DBG1 | rp.WATCHDOG_CTRL_PAUSE_JTAG) 46 47 // Load initial counter 48 rp.WATCHDOG.LOAD.Set(wd.loadValue) 49 50 return nil 51 } 52 53 // Starts the watchdog. 54 func (wd *watchdogImpl) Start() error { 55 rp.WATCHDOG.CTRL.SetBits(rp.WATCHDOG_CTRL_ENABLE) 56 return nil 57 } 58 59 // Update the watchdog, indicating that the app is healthy. 60 func (wd *watchdogImpl) Update() { 61 rp.WATCHDOG.LOAD.Set(wd.loadValue) 62 } 63 64 // startTick starts the watchdog tick. 65 // cycles needs to be a divider that when applied to the xosc input, 66 // produces a 1MHz clock. So if the xosc frequency is 12MHz, 67 // this will need to be 12. 68 func (wd *watchdogImpl) startTick(cycles uint32) { 69 rp.WATCHDOG.TICK.Set(cycles | rp.WATCHDOG_TICK_ENABLE) 70 }