circuitpython/ports/atmel-samd/supervisor
Jeff Epler 372306411a
samd: Don't rely on RTC interrupt
I instrumented RTC_Handler and determined that on SAMD51 it was possible
for the interrupt to be delivered well before the actual overflow of the
RTC COUNT register (e.g., a value as small as 0xffff_fffd could be seen
at the time of overflow)

Rather than depending on the overflow interrupt coming in at the same time
as COUNT overflows (exactly), rely only on observed values of COUNT in
_get_count, overflowing when it wraps around from a high value to a low
one.

With this change, PLUS a second change so that it is possible to warp
the RTC counter close to an overflow and test in 20ms instead of 3 days,
there was no problem detected over 20000+ overflows. Before, a substantial
fraction (much greater than 10%) of overflows failed.

Fixes #5985

Change to common-hal/rtc/RTC.c for time warping (plus make rtc_old_count non-static):
```patch
 void common_hal_rtc_set_calibration(int calibration) {
+
+    common_hal_mcu_disable_interrupts();
+
+        RTC->MODE0.COUNT.reg = 0xffffff00;
+        rtc_old_count = 0;
+        do {
+        while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) { }
+    }
+    while(RTC->MODE0.COUNT.reg < 0xffffff00);
+    common_hal_mcu_enable_interrupts();
+
+    mp_printf(&mp_plat_print, "Warping RTC in calibration setter count=%08x rtc_old_count=%08x\n", RTC->MODE0.COUNT.reg, rtc_old_count);
```

Test program:
```python
import time
from rtc import RTC

i = 0
while True:
    RTC().calibration = 1 # Warps to ~16ms before overflow, with patch to RTC code
    t0 = time.monotonic_ns()
    et = t0 + 20_000_000 # 20ms
    while (t1 := time.monotonic_ns()) < et: pass
    i += 1
    print(f"{i:6d}: duration {t1-t0}")
    if t1-t0 > 200_000_000: break
    print()
```
2022-03-25 14:48:03 -05:00
..
internal_flash.c more missing-prototypes fixes 2021-11-10 21:00:17 -06:00
internal_flash.h Add license to some obvious files. 2020-07-06 19:16:25 +01:00
internal_flash_root_pointers.h Move atmel-samd to tinyusb and support nRF flash. 2018-11-08 17:25:30 -08:00
port.c samd: Don't rely on RTC interrupt 2022-03-25 14:48:03 -05:00
qspi_flash.c fix QSPI_SINGLE pin definitions 2021-10-24 12:37:30 -07:00
samd21_cpu.s Mark pointers in cpu registers as in use. 2018-07-03 05:45:50 -07:00
samd51_cpu.s Mark pointers in cpu registers as in use. 2018-07-03 05:45:50 -07:00
same51_cpu.s atmel-samd: add same51, feather_m4_can 2020-09-08 13:06:45 -05:00
same54_cpu.s atmel-samd: Add support for SAM E54 family MCUs 2020-06-23 10:41:48 -05:00
usb.c Start of USB host API 2022-03-07 18:07:25 -08:00