Reset during LFRC calibration can hang clock

Hello,

I'm using nRF52840 and nRF_SDK_17.1.0 to build application and bootloader (slightly modified example) both using Soft Device.
Due to size and time constrains of system we are using RC oscillator as low frequency clock.

I've encountered quite a serious problem with it. It looks like LFRC is getting stuck unusable when soft reset is performed (NVIC_SystemReset) during LFRC calibration.

General steps:

- Wake from system off mode.
- Dash through bootloader (skip crc, dfu etc.), starting app immediately. 
- Enter app and start watchdog.
- Enable SoftDevice with LFRC (my assumption is that SD immediately starts RC calibration)
- App encounters critical error and performs soft reset.
- Enter bootloader (it knows that app crashed)
- Trigger LFRC start, initialize and start RTC to wait some time before restarting app.
- Enter WFI to wait for RTC (end of sleep) interrupt.

At this point system gets completely stuck in WFI. LFRC is not running, so RTC is also not counting time and will never trigger interrupt. What is even more problematic, watchdog, which was configured and functional in application is now also NOT running. Until power reset device is completely stuck, with encapsulated battery it's bricked.

From my tests and observations, software reset happens during LFRC calibration procedure. Looks like clock peripheral is reset (clocks are stopped) but internal state machine of calibration procedure is not reset and peripheral gets stuck in some strange state.

I've found few workarounds, non of them are good for our case.

Main step of every solution is to provide HF clock long enough for calibration internal state machine to finish (probably counting clock cycles). What works:
- Add nrf_delay_ms(20) just at beginning of bootloader main function.
- Request HFCLK start at booltoader start.
- Enable Constant Latency mode (NRF_POWER->TASKS_CONSTLAT).
All those solutions provide HF clock for long enough to finish calibration procedure. After that everything works as expected. LFRC start task can be called even before delay, it will also work.

Unfortunately, in our case none of those solutions are satisfying mainly due to time/power constrains.

Best solution would be somehow checking if calibration is ongoing (before or after restart). I know there is no direct way of doing it, at least not using publicly documented registers.
Are there any other options, for example states represented in not publicly documented registers?

Thanks for help.
Best regards
Tomasz

Related