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()
```
To me, it made more sense to track which boards go together in a cluster;
when reviewing a request to actually use a duplicate vid/pid, you want
to know what board(s) it is aliasing.
I also revamped the detection of non-USB boards so that a board .mk file
that couldn't be parsed by the code here would raise a problem instead
of just being skipped for the purposes of checking.
There were some lines with comments on the end, and some variation in
capitalization of the IDs. These are all normalized and a (sometimes
unfriendly!) error printed when it's incorrect.
Before this, here were some ways to trick the duplicate vid/pid checker:
```
USB_PID = 0XABCD
USB_PID = 0xAbCd
USB_PID = 0xABCD # harmless comment?
```
None of these things were ever done on purpose.