This document specifies the Always-On (“AON”) Timer IP functionality. This module conforms to the [Comportable guideline for peripheral functionality.]({{< relref “doc/rm/comportability_specification” >}}) See that document for an overview of how it is integrated into the top level system.
The always-on wakeup timer operation is straightforward. A count starts at 0 and slowly ticks upwards (one tick every N + 1
clock cycles, where N
is the pre-scaler value). When it reaches / exceeds the wake threshold, a level wakeup signal is sent to the power manager and a level IRQ is sent to the processor. This wakeup signal stays high until it is explicitly acknowledged by software. To clear the wakeup write 0 to the {{<regref “WKUP_CAUSE”>}} register. To clear the interrupt write 1 to {{<regref “INTR_STATE.wkup_timer_expired”>}}. Note that if {{<regref “WKUP_COUNT”>}} is not zeroed and remains at or above the wake threshold and the wakeup timer isn't disabled, the wakeup and interrupt will trigger again at the next clock tick. The wakeup timer can be used like a real-time clock for long periods in a low-power mode (though it does not give any guarantees of time-accuracy). TODO: specify accuracy
The always-on watchdog timer behaves similarly to the wakeup timer. It has an independent count starting at 0 which slowly ticks upwards. When the first threshold is met or exceeded, a level wakeup signal (if enabled) is sent to the power manager. Simultaneously, a level IRQ signal is also generated to the processor.
If the system is in a low power state, the wakeup signal asks the power manager to wake the system so that the IRQ can be serviced. If the system is not in a low power mode, the IRQ is immediately serviced. Both the wakeup and the IRQ signals remain asserted until system reset or explicit acknowledgement by software. This first threshold is known as the watchdog bark.
An extra interrupt output is available to connect the watchdog bark output to a non-maskable interrupt pin if required.
When the second threshold is met (this is known as the watchdog bite), a reset request is sent to the power manager which will trigger a system reset. This is independent of the IRQ sent as part of the watchdog bark. The system reset also resets the always-on timer, so software is not required to directly acknowledge anything after a watchdog reset.
To prevent the watchdog bark or bite, software is expected to periodically reset the count when operating normally. This is referred to as petting the watchdog, and is achieved by resetting the count to zero.
Since this timer functions as a watchdog, it has three additional functions not present in the always-on wakeup timer:
Unlike the wakeup timer, the watchdog timer configuration can be locked by firmware until the next system reset. This allows the option of preventing firmware from accidentally or maliciously disabling the watchdog.
The “pause in sleep” option controls whether the watchdog timer continues to count in low-power modes. This allows configurations where the watchdog timer can remain programmed and locked while the device is put to sleep for relatively long periods, controlled by the wakeup timer. Without this feature, the watchdog timer might wake up the core prematurely by triggering a watchdog bark.
The “pause during escalation” feature ensures that watchdog bites and barks do not interfere with system escalation behavior. If during escalation software configures the system to hang instead of reset, the watchdog bite cannot supersede that decision.
See the block diagram for high level function and connectivity. The timer interacts with the CPU core and the power manager and reset manager to drive wakeup / reset events and interrupts. There is also an extra input to tell the counter whether to run (“counter-run”). This is used to stop the watchdog timer running when in debugging mode or when the alert handler has put the system in a “killed” state.
{{< incGenFromIpDesc “../data/aon_timer.hjson” “hwcfg” >}}
The always-on timer will run on a ~200KHz clock. The timers themselves are 32b wide, giving a maximum timeout window of roughly ~6 hours. For the wakeup timer, the pre-scaler extends the maximum timeout to ~1000 days.
Register reads via the TLUL interface are synchronized to the slow clock using the “async” register generation feature. This means that writes can complete before the data has reached its underlying register in the slow clock domain. If software needs to guarantee completion of a register write, it can read back the register value (which will guarantee the completion of all previous writes to the peripheral).
regwen
bit in {{<regref“WDOG_REGWEN”>}}.Pet the watchdog by writing zero to the {{<regref“WDOG_COUNT”>}} register.
If either timer reaches the programmed threshold, interrupts are generated from the AON_TIMER module. Disable or reinitialize the wakeup timer if required by clearing the enable bit in {{<regref“WKUP_CTRL”>}} or clearing the timer value in {{<regref“WKUP_COUNT”>}}. Clear the interrupt by writing 1 into the Interrupt Status Register {{<regref “INTR_STATE”>}}.
If the timer has caused a wakeup event ({{<regref“WKUP_CAUSE”>}} is set) then clear the wakeup request by writing 0 to {{<regref“WKUP_CAUSE”>}}.
If {{<regref“WKUP_COUNT”>}} remains above the threshold after clearing the interrupt or wakeup event and the timer remains enabled, the interrupt and wakeup event will trigger again at the next clock tick.
{{< dif_listing “sw/device/lib/dif/dif_aon_timer.h” >}}
{{< incGenFromIpDesc “../data/aon_timer.hjson” “registers” >}}