Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
François Revol
firmware
Commits
c3ca9d22
Commit
c3ca9d22
authored
Sep 21, 2019
by
Rahix
Browse files
Merge 'Add monotonic clock'
See merge request
card10/firmware!285
and
card10/firmware#146
parents
5773e2e1
f1251d66
Changes
4
Hide whitespace changes
Inline
Side-by-side
epicardium/epicardium.h
View file @
c3ca9d22
...
...
@@ -81,6 +81,8 @@ typedef _Bool bool;
#define API_RTC_SCHEDULE_ALARM 0x51
#define API_RTC_SET_MILLISECONDS 0x52
#define API_RTC_GET_MILLISECONDS 0x53
#define API_RTC_GET_MONOTONIC_SECONDS 0x54
#define API_RTC_GET_MONOTONIC_MILLISECONDS 0x55
#define API_LEDS_SET 0x60
#define API_LEDS_SET_HSV 0x61
...
...
@@ -1733,6 +1735,24 @@ API(API_FILE_MKDIR, int epic_file_mkdir(const char *dirname));
* ===
*/
/**
* Get the monotonic time in seconds.
*
* :return: monotonic time in seconds
*/
API
(
API_RTC_GET_MONOTONIC_SECONDS
,
uint32_t
epic_rtc_get_monotonic_seconds
(
void
)
);
/**
* Get the monotonic time in ms.
*
* :return: monotonic time in milliseconds
*/
API
(
API_RTC_GET_MONOTONIC_MILLISECONDS
,
uint64_t
epic_rtc_get_monotonic_milliseconds
(
void
)
);
/**
* Read the current RTC value.
*
...
...
epicardium/modules/rtc.c
View file @
c3ca9d22
...
...
@@ -9,6 +9,18 @@
#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
;
...
...
@@ -32,12 +44,31 @@ uint64_t epic_rtc_get_milliseconds(void)
while
(
RTC_GetTime
(
&
sec
,
&
subsec
)
==
E_BUSY
)
{
vTaskDelay
(
pdMS_TO_TICKS
(
4
));
}
return
subsec
*
1000ULL
/
4096
+
sec
*
1000ULL
;
// 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
;
old_milliseconds
=
epic_rtc_get_milliseconds
();
sec
=
milliseconds
/
1000
;
subsec
=
(
milliseconds
%
1000
);
...
...
@@ -48,6 +79,9 @@ void epic_rtc_set_milliseconds(uint64_t milliseconds)
;
while
(
RTC_EnableRTCE
(
MXC_RTC
)
==
E_BUSY
)
;
diff
=
old_milliseconds
-
milliseconds
;
monotonic_offset
+=
diff
;
}
void
RTC_IRQHandler
(
void
)
...
...
pycardium/modules/qstrdefs.h
View file @
c3ca9d22
...
...
@@ -48,6 +48,8 @@ Q(ticks_add)
Q
(
ticks_diff
)
Q
(
localtime
)
Q
(
mktime
)
Q
(
monotonic
)
Q
(
monotonic_ms
)
Q
(
time
)
Q
(
time_ms
)
Q
(
set_time
)
...
...
pycardium/modules/utime.c
View file @
c3ca9d22
...
...
@@ -51,6 +51,22 @@ static mp_obj_t time_time_ms(void)
}
MP_DEFINE_CONST_FUN_OBJ_0
(
time_time_ms_obj
,
time_time_ms
);
static
mp_obj_t
time_monotonic
(
void
)
{
mp_int_t
seconds
;
seconds
=
epic_rtc_get_monotonic_seconds
();
return
mp_obj_new_int
(
seconds
);
}
MP_DEFINE_CONST_FUN_OBJ_0
(
time_monotonic_obj
,
time_monotonic
);
static
mp_obj_t
time_monotonic_ms
(
void
)
{
uint64_t
milliseconds
;
milliseconds
=
epic_rtc_get_monotonic_milliseconds
();
return
mp_obj_new_int_from_ull
(
milliseconds
);
}
MP_DEFINE_CONST_FUN_OBJ_0
(
time_monotonic_ms_obj
,
time_monotonic_ms
);
static
mp_obj_t
time_localtime
(
size_t
n_args
,
const
mp_obj_t
*
args
)
{
mp_int_t
seconds
;
...
...
@@ -130,6 +146,9 @@ static const mp_rom_map_elem_t time_module_globals_table[] = {
{
MP_ROM_QSTR
(
MP_QSTR___name__
),
MP_ROM_QSTR
(
MP_QSTR_utime
)
},
{
MP_ROM_QSTR
(
MP_QSTR_time
),
MP_ROM_PTR
(
&
time_time_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_time_ms
),
MP_ROM_PTR
(
&
time_time_ms_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_monotonic
),
MP_ROM_PTR
(
&
time_monotonic_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_monotonic_ms
),
MP_ROM_PTR
(
&
time_monotonic_ms_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_set_time
),
MP_ROM_PTR
(
&
time_set_time_obj
)
},
{
MP_ROM_QSTR
(
MP_QSTR_set_unix_time
),
MP_ROM_PTR
(
&
time_set_unix_time_obj
)
},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment