Browse Source
Under some circumstances, after a hard reset, the low-frequency clock would not be running. This caused time.ticks_ms() to return 0, time.sleep_ms() to get stuck, and other misbehavior. A soft reboot would return it to a working state. The cause was a race condition that was hit when the bootloader would itself turn LFCLK on, but turn it off again shortly before launching the main application (this apparently happens with the Adafruit bootloader from https://github.com/fanoush/ds-d6/tree/master/micropython). Stopping the clock is an asynchronous operation and it continues running for a short time after the stop command is given. When MicroPython checked whether to start it by looking at the LFCLKSTAT register (nrf_clock_lf_is_running) during that time, it would mistakenly not be started again. What MicroPython should be looking at is not whether the clock is running at this time, but whether a start/stop command has been given, which is indicated by the LFCLKRUN register (nrf_clock_lf_start_task_status_get). It is not clearly documented, but empirically LFCLKRUN is not just set when the LFCLKSTART task is triggered, but also cleared when the LFCLKSTOP task is triggered, which is exactly what we need. The matter is complicated by the fact that the nRF52832 has an anomaly (see [errata](https://infocenter.nordicsemi.com/topic/errata_nRF52832_Rev3/ERR/nRF52832/Rev3/latest/anomaly_832_132.html?cp=5_2_1_0_1_33)) where starting the LFCLK will not work between 66µs and 138µs after it last stopped. Apply a workaround for that. See nrfx_clock_lfclk_start() in micropython/lib/nrfx/drivers/src/nrfx_clock.c for reference, but we are not using that because it also does other things and makes the code larger. Signed-off-by: Christian Walther <cwalther@gmx.ch>pull/13497/head
Christian Walther
10 months ago
committed by
Damien George
3 changed files with 35 additions and 6 deletions
Loading…
Reference in new issue