Extend nRF52 radio profile timing across RTC wraps
This commit is contained in:
1 parent
ca67494f8c
commit
8038715ffe
5 files changed
+65
-27
No files matched your search
@@ -18,6 +18,7 @@ HARNESS = r'''
|
||||
#define MESH_ENABLE_MORSE_RX 1
|
||||
struct Rtc { uint32_t COUNTER = 200; } rtc;
|
||||
#define NRF_RTC2 (&rtc)
|
||||
uint32_t profile_clock_raw=0, profile_clock_ticks=0;
|
||||
struct NRF52Board {
|
||||
static bool ready;
|
||||
static bool canIdleRadioProfile() { return ready; }
|
||||
@@ -54,6 +55,13 @@ int main() {
|
||||
assert(!w.getProfileIdleDelay(delay) && delay==0);
|
||||
#else
|
||||
assert(w.getProfileIdleDelay(delay) && delay==26);
|
||||
// Identical raw RTC values after a full hardware wrap must not resurrect
|
||||
// an old idle proof. Both stamps use the software-extended tick domain.
|
||||
profile_clock_ticks=0x01000000UL;
|
||||
assert(!w.getProfileIdleDelay(delay));
|
||||
w._profile_visit_stamp=w._profile_idle_stamp=0x01000064UL;
|
||||
assert(w.getProfileIdleDelay(delay) && delay==26);
|
||||
profile_clock_ticks=0;w=RadioLibWrapper();
|
||||
// Exact early-wake boundary, rounding, already expired, and RTC wrap.
|
||||
for (uint32_t remaining=0; remaining<=48; ++remaining) {
|
||||
rtc.COUNTER=100+1000-remaining;
|
||||
@@ -63,7 +71,7 @@ int main() {
|
||||
assert(w.getProfileIdleDelay(delay) && delay==1);
|
||||
rtc.COUNTER=1101;
|
||||
assert(!w.getProfileIdleDelay(delay));
|
||||
w._profile_visit_stamp=w._profile_idle_stamp=0x00fffff0;
|
||||
w._profile_visit_stamp=w._profile_idle_stamp=0xfffffff0;
|
||||
rtc.COUNTER=0x10;
|
||||
assert(w.getProfileIdleDelay(delay) && delay==29);
|
||||
w=RadioLibWrapper(); rtc.COUNTER=200;
|
||||
|
||||
@@ -8,9 +8,8 @@ import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SOURCE = (ROOT / "src/helpers/radiolib/RadioLibWrappers.cpp").read_text()
|
||||
CLOCK = "static void syncProfileClock(bool dual_profile) {" + SOURCE.split(
|
||||
"static void syncProfileClock(bool dual_profile) {", 1
|
||||
)[1].split("\nstatic\n#if defined(ESP8266)", 1)[0]
|
||||
CLOCK = SOURCE[SOURCE.index("// Extend the 24-bit RTC counter"):].split(
|
||||
"\nstatic\n#if defined(ESP8266)", 1)[0]
|
||||
|
||||
HARNESS = r'''
|
||||
#include <cassert>
|
||||
@@ -28,22 +27,40 @@ int main() {
|
||||
assert(profileElapsedUs(12, 42, false) == 30);
|
||||
#if defined(NRF52_PLATFORM)
|
||||
rtc.COUNTER = 100;
|
||||
assert(profileTimestamp(true) == 100);
|
||||
assert(profileTimestamp(true) == 0);
|
||||
assert(rtc.TASKS_STOP == 1 && rtc.PRESCALER == 0);
|
||||
assert(rtc.TASKS_CLEAR == 1 && rtc.TASKS_START == 1);
|
||||
assert(rtc.TASKS_CLEAR == 0 && rtc.TASKS_START == 1);
|
||||
rtc.TASKS_CLEAR = rtc.TASKS_START = rtc.TASKS_STOP = 0;
|
||||
assert(profileTimestamp(true) == 100);
|
||||
assert(profileTimestamp(true) == 0);
|
||||
assert(rtc.TASKS_CLEAR == 0 && rtc.TASKS_START == 0 && rtc.TASKS_STOP == 0);
|
||||
assert(profileElapsedUs(0, 32768, true) == 1000000);
|
||||
assert(profileElapsedUs(0x00fffff0, 0x10, true) == 977);
|
||||
assert(profileElapsedUs(0xfffffff0, 0x10, true) == 977);
|
||||
uint32_t stamp=0;
|
||||
for(unsigned second=1;second<=532;++second) {
|
||||
rtc.COUNTER=(rtc.COUNTER+32768)&0x00ffffffUL;
|
||||
stamp=profileTimestamp(true);
|
||||
assert(stamp==second*32768UL);
|
||||
assert(profileElapsedUs(0,stamp,true)==second*1000000UL);
|
||||
}
|
||||
assert(stamp>0x00ffffffUL); // A valid visit can exceed the hardware period.
|
||||
assert(profileElapsedUs(0,UINT32_MAX,true)==UINT32_MAX);
|
||||
syncProfileClock(false);
|
||||
assert(rtc.TASKS_STOP == 1 && profileTimestamp(false) == 1234);
|
||||
rtc.TASKS_CLEAR = rtc.TASKS_START = rtc.TASKS_STOP = 0;
|
||||
syncProfileClock(false);
|
||||
assert(rtc.TASKS_CLEAR == 0 && rtc.TASKS_START == 0 && rtc.TASKS_STOP == 0);
|
||||
rtc.COUNTER = 200;
|
||||
assert(profileTimestamp(true) == 200);
|
||||
assert(rtc.TASKS_CLEAR == 1 && rtc.TASKS_START == 1);
|
||||
assert(profileTimestamp(true) == 0);
|
||||
assert(rtc.TASKS_CLEAR == 0 && rtc.TASKS_START == 1);
|
||||
for(unsigned chunk=0;chunk<511;++chunk) {
|
||||
rtc.COUNTER=(rtc.COUNTER+256UL*32768)&0x00ffffffUL;
|
||||
profileTimestamp(true);
|
||||
}
|
||||
rtc.COUNTER=(rtc.COUNTER+255UL*32768)&0x00ffffffUL;
|
||||
const auto before=profileTimestamp(true);assert(before==0xffff8000UL);
|
||||
rtc.COUNTER=(rtc.COUNTER+32768)&0x00ffffffUL;
|
||||
const auto wrapped=profileTimestamp(true);assert(wrapped==0);
|
||||
assert(profileElapsedUs(before,wrapped,true)==1000000UL);
|
||||
#else
|
||||
assert(profileTimestamp(true) == 1234);
|
||||
assert(profileElapsedUs(12, 42, true) == 30);
|
||||
|
||||
@@ -26,7 +26,7 @@ static uint64_t elapsed_us;
|
||||
uint32_t micros() { return (uint32_t)elapsed_us; }
|
||||
static bool profile_clock_active=false;
|
||||
void syncProfileClock(bool dual_profile) { profile_clock_active=dual_profile; }
|
||||
uint32_t profileTimestamp(bool) { return micros(); }
|
||||
uint32_t profileTimestamp(bool dual) { syncProfileClock(dual); return micros(); }
|
||||
uint32_t profileElapsedUs(uint32_t since, uint32_t now, bool) { return now - since; }
|
||||
uint32_t millis() { return (uint32_t)(elapsed_us / 1000); }
|
||||
struct Chip { bool standbyXOSC=false; int standby() { return 0; } };
|
||||
|
||||
Reference in new issue
Block a user