| --- | |
| title: "AON Timer Technical Specification" | |
| --- | |
| # Overview | |
| 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. | |
| ## Features | |
| - Two 32-bit upcounting timers: one timer functions as a wakeup timer, one as a watchdog timer | |
| - The watchdog timer has two thresholds: bark (generates an interrupt) and bite (resets core) | |
| - There is 12 bit pre-scaler for the wakeup timer to enable very long timeouts | |
| ## Description | |
| ### AON Wakeup timer | |
| 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 count, 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 (software must write zero to the {{<regref "WKUP_CAUSE">}} register to clear it). | |
| 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** | |
| ### AON Watchdog timer | |
| 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 two additional functions not present in the always-on wakeup timer: | |
| * Watchdog configuration lock | |
| * Watchdog pause in sleep | |
| 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. | |
| # Theory of Operations | |
| ## Block Diagram | |
|  | |
| 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. | |
| ## Hardware Interfaces | |
| {{< incGenFromIpDesc "../data/aon_timer.hjson" "hwcfg" >}} | |
| ## Design Details | |
| 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). | |
| # Programmers Guide | |
| ## Initialization | |
| 1. Write the timer values {{<regref"WKUP_COUNT">}} and {{<regref"WDOG_COUNT">}} to zero. | |
| 2. Program the desired wakeup pre-scaler value in {{<regref"WKUP_CTRL">}}. | |
| 3. Program the desired thresholds in {{<regref"WKUP_THOLD">}}, {{<regref"WDOG_BARK_THOLD">}} and {{<regref"WDOG_BITE_THOLD">}}. | |
| 4. Set the enable bit to 1 in the {{<regref"WKUP_CTRL">}} / {{<regref"WDOG_CTRL">}} registers. | |
| 5. If desired, lock the watchdog configuration by writing 1 to the `regwen` bit in {{<regref"WDOG_REGWEN">}}. | |
| ## Watchdog pet | |
| Pet the watchdog by writing zero to the {{<regref"WDOG_COUNT">}} register. | |
| ## Interrupt Handling | |
| 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">}}. | |
| ## Device Interface Functions (DIFs) | |
| TODO | |
| ## Register Table | |
| {{< incGenFromIpDesc "../data/aon_timer.hjson" "registers" >}} |