hw/mcu/nrf54lxx: enable GRTC SYSCOUNTER auto_mode with WAKETIME/TIMEOUT#3614
Open
nemethhh wants to merge 1 commit intoapache:masterfrom
Open
hw/mcu/nrf54lxx: enable GRTC SYSCOUNTER auto_mode with WAKETIME/TIMEOUT#3614nemethhh wants to merge 1 commit intoapache:masterfrom
nemethhh wants to merge 1 commit intoapache:masterfrom
Conversation
…MEOUT Without these settings, os_tick_idle() can freeze the CPU. The per-CPU SYSCOUNTER[].ACTIVE register is at its reset value (NotActive, "Allow SYSCOUNTER to go to sleep" per the MDK), so the SYSCOUNTER subdomain is permitted to sleep during idle. nrf54l_os_tick_counter() is called from os_tick_idle() inside a critical section (PRIMASK=1) and contains a spin loop on SYSCOUNTERH.BUSY. When the subdomain is asleep on entry, the clock-domain handshake required to clear BUSY cannot complete, the loop spins indefinitely with interrupts globally disabled, and the device becomes unresponsive. Captured frozen-state PCs resolved to the spin in nrf_grtc_sys_counter_high_get and the while-condition in nrf54l_os_tick_counter; recovery required external bus activity to wake the power domain. Setting MODE.AUTOEN = CpuActive replaces the implicit-sleep default with "any local CPU that is not sleeping keeps the SYSCOUNTER active" (MDK). This guarantees the subdomain is awake whenever the CPU is executing, including during the spin loop itself, so BUSY can clear. WAKETIME = 4 (4 LFCLK cycles, ~122 us) tells the hardware to begin waking the subdomain that many cycles before any programmed compare event. The GRTC compare-event ISR therefore runs with the subdomain already awake and the spin loop exits immediately. TIMEOUT = 5 (5 LFCLK cycles, ~152 us) is the delay after all CPUs enter WFI before the subdomain actually goes to sleep, providing hysteresis against short WFI windows. Sleep registers are configured before enabling SYSCOUNTEREN: the hardware requires TIMEOUT and WAKETIME to be set while the SYSCOUNTER is disabled.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Enable auto_mode on the GRTC SYSCOUNTER domain so it sleeps during WFI
(tickless idle) and wakes when the CPU is active, reducing power
consumption during idle periods.
Without these settings, os_tick_idle() can freeze the CPU. The per-CPU SYSCOUNTER[].ACTIVE register is at its reset value (NotActive, "Allow SYSCOUNTER to go to sleep" per the MDK), so the SYSCOUNTER subdomain is permitted to sleep during idle. nrf54l_os_tick_counter() is called from os_tick_idle() inside a critical section (PRIMASK=1) and contains a spin loop on SYSCOUNTERH.BUSY. When the subdomain is asleep on entry, the clock-domain handshake required to clear BUSY cannot complete, the loop spins indefinitely with interrupts globally disabled, and the device becomes unresponsive. Captured frozen-state PCs resolved to the spin in nrf_grtc_sys_counter_high_get and the while-condition in nrf54l_os_tick_counter; recovery required external bus activity to wake the power domain.
Setting MODE.AUTOEN = CpuActive replaces the implicit-sleep default with "any local CPU that is not sleeping keeps the SYSCOUNTER active" (MDK). This guarantees the subdomain is awake whenever the CPU is executing, including during the spin loop itself, so BUSY can clear.
WAKETIME = 4 (4 LFCLK cycles, ~122 us) tells the hardware to begin waking the subdomain that many cycles before any programmed compare event. The GRTC compare-event ISR therefore runs with the subdomain already awake and the spin loop exits immediately.
TIMEOUT = 5 (5 LFCLK cycles, ~152 us) is the delay after all CPUs enter WFI before the subdomain actually goes to sleep, providing hysteresis against short WFI windows.
Sleep registers are configured before enabling SYSCOUNTEREN: the hardware requires TIMEOUT and WAKETIME to be set while the SYSCOUNTER is disabled.
Assisted-by: Claude:claude-4.7-opus