Select Git revision
Forked from
card10 / firmware
Source project has a limited visibility.
-
Squashed commits: e94f7bf9 epicardium/rtc: add monotonic time e0691c6d pycardium/modules/utime.c: add bindings for monotonic time 756c13df epicardium/rtc: fix numerically unstable subsecond decoding the subsecond encoding function from epic_rtc_set_milliseconds and the corresponding decoding function from epic_rtc_get_milliseconds are not numerically stable. i.e., encoding 5 milliseconds to 20 subsecs and immediately afterwards decoding that yields 4 milliseconds. Adding a bias of 999 (0.24 milliseconds) to the decoding function makes it numerically stable, while never decoding any subsecond value to more than 999 milliseconds. e99e278b epicardium/rtc: only poll time once for calculating monotonic_offset 18936b7e pycardium/modules/utime.c: run clang-format 869ac617 epicardium/rtc: add explanation comment for numerically stable subsecond decode
Squashed commits: e94f7bf9 epicardium/rtc: add monotonic time e0691c6d pycardium/modules/utime.c: add bindings for monotonic time 756c13df epicardium/rtc: fix numerically unstable subsecond decoding the subsecond encoding function from epic_rtc_set_milliseconds and the corresponding decoding function from epic_rtc_get_milliseconds are not numerically stable. i.e., encoding 5 milliseconds to 20 subsecs and immediately afterwards decoding that yields 4 milliseconds. Adding a bias of 999 (0.24 milliseconds) to the decoding function makes it numerically stable, while never decoding any subsecond value to more than 999 milliseconds. e99e278b epicardium/rtc: only poll time once for calculating monotonic_offset 18936b7e pycardium/modules/utime.c: run clang-format 869ac617 epicardium/rtc: add explanation comment for numerically stable subsecond decode
rtc.c 2.69 KiB
#include "epicardium.h"
#include "modules/log.h"
#include "api/interrupt-sender.h"
#include "FreeRTOS.h"
#include "task.h"
#include "rtc.h"
#include <stdint.h>
uint64_t monotonic_offset = 0;
uint32_t epic_rtc_get_monotonic_seconds(void)
{
return epic_rtc_get_seconds() + monotonic_offset / 1000ULL;
}
uint64_t epic_rtc_get_monotonic_milliseconds(void)
{
return epic_rtc_get_milliseconds() + monotonic_offset;
}
uint32_t epic_rtc_get_seconds(void)
{
uint32_t sec, subsec;
/*
* TODO: Find out what causes the weird behavior of this function. The
* time needed for this call seems to depend on the frequency at
* which it is called.
*/
while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
vTaskDelay(pdMS_TO_TICKS(4));
}
return sec;
}
uint64_t epic_rtc_get_milliseconds(void)
{
uint32_t sec, subsec;
while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
vTaskDelay(pdMS_TO_TICKS(4));
}
// Without the bias of 999 (0.24 milliseconds), this decoding function is
// numerically unstable:
//
// Encoding 5 milliseconds into 20 subsecs (using the encoding function in
// epic_rtc_set_milliseconds) and decoding it without the bias of 999 yields
// 4 milliseconds.
//
// The following invariants should hold when encoding / decoding from and to
// milliseconds / subseconds:
//
// - 0 <= encode(ms) < 4096 for 0 <= ms < 1000
// - decode(encode(ms)) == ms for 0 <= ms < 1000
// - 0 <= decode(subsec) < 1000 for 0 <= subsec < 4096
//
// These invariants were proven experimentally.
return (subsec * 1000ULL + 999ULL) / 4096 + sec * 1000ULL;
}
void epic_rtc_set_milliseconds(uint64_t milliseconds)
{
uint32_t sec, subsec;
uint64_t old_milliseconds, diff;