summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/nrf/modules/machine/rtcounter.c5
-rw-r--r--ports/nrf/mphalport.c34
-rw-r--r--ports/nrf/mphalport.h2
3 files changed, 35 insertions, 6 deletions
diff --git a/ports/nrf/modules/machine/rtcounter.c b/ports/nrf/modules/machine/rtcounter.c
index 08d31f61d..c1ef1b4dd 100644
--- a/ports/nrf/modules/machine/rtcounter.c
+++ b/ports/nrf/modules/machine/rtcounter.c
@@ -27,6 +27,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
+#include "mphalport.h"
#include "rtcounter.h"
#include "nrfx_rtc.h"
#include "nrf_clock.h"
@@ -182,9 +183,7 @@ static mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, s
}
// Start the low-frequency clock (if it hasn't been started already)
- if (!nrf_clock_lf_is_running(NRF_CLOCK)) {
- nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
- }
+ mp_nrf_start_lfclk();
// Make sure it's uninitialized.
nrfx_rtc_uninit(self->p_rtc);
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index 2a1a4cb13..06c6ba5cc 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -40,6 +40,36 @@
#include "nrf_clock.h"
#endif
+#if !defined(USE_WORKAROUND_FOR_ANOMALY_132) && \
+ (defined(NRF52832_XXAA) || defined(NRF52832_XXAB))
+// ANOMALY 132 - LFCLK needs to avoid frame from 66us to 138us after LFCLK stop.
+#define USE_WORKAROUND_FOR_ANOMALY_132 1
+#endif
+
+#if USE_WORKAROUND_FOR_ANOMALY_132
+#include "soc/nrfx_coredep.h"
+#endif
+
+void mp_nrf_start_lfclk(void) {
+ if (!nrf_clock_lf_start_task_status_get(NRF_CLOCK)) {
+ // Check if the clock was recently stopped but is still running.
+ #if USE_WORKAROUND_FOR_ANOMALY_132
+ bool was_running = nrf_clock_lf_is_running(NRF_CLOCK);
+ // If so, wait for it to stop. This ensures that the delay for anomaly 132 workaround does
+ // not land us in the middle of the forbidden interval.
+ while (nrf_clock_lf_is_running(NRF_CLOCK)) {
+ }
+ // If the clock just stopped, we can start it again right away as we are certainly before
+ // the forbidden 66-138us interval. Otherwise, apply a delay of 138us to make sure we are
+ // after the interval.
+ if (!was_running) {
+ nrfx_coredep_delay_us(138);
+ }
+ #endif
+ nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
+ }
+}
+
#if MICROPY_PY_TIME_TICKS
// Use RTC1 for time ticks generation (ms and us) with 32kHz tick resolution
@@ -99,9 +129,7 @@ static void rtc_irq_time(nrfx_rtc_int_type_t event) {
void rtc1_init_time_ticks(void) {
// Start the low-frequency clock (if it hasn't been started already)
- if (!nrf_clock_lf_is_running(NRF_CLOCK)) {
- nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
- }
+ mp_nrf_start_lfclk();
// Uninitialize first, then set overflow IRQ and first CC event
nrfx_rtc_uninit(&rtc1);
nrfx_rtc_init(&rtc1, &rtc_config_time_ticks, rtc_irq_time);
diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h
index 1ba4b6e70..7efe05a15 100644
--- a/ports/nrf/mphalport.h
+++ b/ports/nrf/mphalport.h
@@ -54,6 +54,8 @@ void mp_hal_delay_us(mp_uint_t us);
const char *nrfx_error_code_lookup(uint32_t err_code);
+void mp_nrf_start_lfclk(void);
+
#define MP_HAL_PIN_FMT "%q"
#define mp_hal_pin_obj_t const pin_obj_t *
#define mp_hal_get_pin_obj(o) pin_find(o)