diff --git a/drivers/clock_control/nrf_power_clock.c b/drivers/clock_control/nrf_power_clock.c index 8a1befbe4df..df45a9430cb 100644 --- a/drivers/clock_control/nrf_power_clock.c +++ b/drivers/clock_control/nrf_power_clock.c @@ -228,6 +228,18 @@ static struct clock_control_async_data *list_get(sys_slist_t *list) return async_data; } +static inline void anomaly_132_workaround(void) +{ +#if (CONFIG_NRF52_ANOMALY_132_DELAY_US - 0) + static bool once; + + if (!once) { + k_busy_wait(CONFIG_NRF52_ANOMALY_132_DELAY_US); + once = true; + } +#endif +} + static int clock_async_start(struct device *dev, clock_control_subsys_t subsys, struct clock_control_async_data *data) @@ -280,6 +292,12 @@ static int clock_async_start(struct device *dev, config->start_handler(dev) : true; if (do_start) { DBG(dev, subsys, "Triggering start task"); + + if (IS_ENABLED(CONFIG_NRF52_ANOMALY_132_WORKAROUND) && + (subsys == CLOCK_CONTROL_NRF_SUBSYS_LF)) { + anomaly_132_workaround(); + } + nrf_clock_task_trigger(NRF_CLOCK, config->start_tsk); } else { diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA index 72e192f9007..4060453badc 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_CIAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA index 94c103267fd..cc48aaeaccb 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_QFAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB index 67abf704346..2b9491cae3b 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_QFAB diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index 56ace7ed89f..ce9c3abda1e 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -361,3 +361,21 @@ config NRF_ENABLE_ICACHE bool "Enable the instruction cache (I-Cache)" depends on SOC_NRF52832 || SOC_NRF52833 || SOC_NRF52840 default y + +config NRF52_ANOMALY_132_DELAY_US + int "Anomaly 132 workaround delay (microseconds)" + default 330 + range 0 330 + depends on NRF52_ANOMALY_132_WORKAROUND + help + Due to Anomaly 132 LF RC source may not start if restarted in certain + window after stopping (230 us to 330 us). Software reset also stops the + clock so if clock is initiated in certain window, the clock may also fail + to start at reboot. A delay is added before starting LF clock to ensure + that anomaly conditions are not met. Delay should be long enough to ensure + that clock is started later than 330 us after reset. If crystal oscillator + (XO) is used then low frequency clock initially starts with RC and then + seamlessly switches to XO which has much longer startup time thus, + depending on application, workaround may also need to be applied. + Additional drivers initialization increases initialization time and delay + may be shortened. Workaround is disabled by setting delay to 0.