Skip to content

Add precise_time module #839

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ Modules
Therefore, code from CircuitPython is runnable on CPython but not
necessarily the reverse.
- tick count is available as
`time.monotonic() <https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.monotonic>`__
`time.monotonic() <https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.monotonic>`__ (returns a float) or `precise_time.monotonic() <https://circuitpython.readthedocs.io/en/latest/shared-bindings/precise_time/__init__.html#precise_time.monotonic>`__ (returns an int).

atmel-samd21 features
~~~~~~~~~~~~~~~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions ports/atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ SRC_COMMON_HAL = \
analogio/AnalogOut.c \
nvm/__init__.c \
nvm/ByteArray.c \
precise_time/__init__.c \
pulseio/__init__.c \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
Expand Down
39 changes: 39 additions & 0 deletions ports/atmel-samd/common-hal/precise_time/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Margaret Sy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "py/mphal.h"

#include "shared-bindings/precise_time/__init__.h"

#include "tick.h"

inline uint64_t common_hal_precise_time_monotonic() {
return ticks_ms;
}

void common_hal_precise_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
2 changes: 2 additions & 0 deletions ports/atmel-samd/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ extern const struct _mp_obj_module_t busio_module;
extern const struct _mp_obj_module_t board_module;
extern const struct _mp_obj_module_t math_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t precise_time_module;
extern const struct _mp_obj_module_t random_module;
extern const struct _mp_obj_module_t rtc_module;
extern const struct _mp_obj_module_t samd_module;
Expand Down Expand Up @@ -243,6 +244,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_precise_time), (mp_obj_t)&precise_time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
EXTRA_BUILTIN_MODULES

Expand Down
1 change: 1 addition & 0 deletions ports/esp8266/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ SRC_COMMON_HAL = \
multiterminal/__init__.c \
neopixel_write/__init__.c \
os/__init__.c \
precise_time/__init__.c \
storage/__init__.c \
time/__init__.c \
board/__init__.c
Expand Down
40 changes: 40 additions & 0 deletions ports/esp8266/common-hal/precise_time/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Margaret Sy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "py/mphal.h"

#include "shared-bindings/precise_time/__init__.h"

#include "ets_alt_task.h"
#include "user_interface.h"

inline uint64_t common_hal_precise_time_monotonic() {
return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_get_time()) / 1000;
}

void common_hal_precise_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
2 changes: 2 additions & 0 deletions ports/esp8266/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ extern const struct _mp_obj_module_t pulseio_module;
extern const struct _mp_obj_module_t busio_module;
extern const struct _mp_obj_module_t bitbangio_module;
extern const struct _mp_obj_module_t time_module;
extern const struct _mp_obj_module_t precise_time_module;
extern const struct _mp_obj_module_t multiterminal_module;
extern const struct _mp_obj_module_t neopixel_write_module;

Expand All @@ -196,6 +197,7 @@ extern const struct _mp_obj_module_t neopixel_write_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_precise_time), (mp_obj_t)&precise_time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal), (mp_obj_t)&multiterminal_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, \

Expand Down
1 change: 1 addition & 0 deletions ports/nrf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ SRC_COMMON_HAL += \
microcontroller/Processor.c \
os/__init__.c \
time/__init__.c \
precise_time/__init__.c \
analogio/__init__.c \
analogio/AnalogIn.c \
analogio/AnalogOut.c \
Expand Down
38 changes: 38 additions & 0 deletions ports/nrf/common-hal/precise_time/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Margaret Sy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "py/mphal.h"

#include "shared-bindings/precise_time/__init__.h"
#include "tick.h"

inline uint64_t common_hal_precise_time_monotonic() {
return ticks_ms;
}

void common_hal_precise_time_delay_ms(uint32_t delay) {
mp_hal_delay_ms(delay);
}
4 changes: 3 additions & 1 deletion ports/nrf/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ extern const struct _mp_obj_module_t pulseio_module;
extern const struct _mp_obj_module_t busio_module;
extern const struct _mp_obj_module_t board_module;
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t precise_time_module;
extern const struct _mp_obj_module_t random_module;
extern const struct _mp_obj_module_t storage_module;
extern const struct _mp_obj_module_t struct_module;
Expand Down Expand Up @@ -271,8 +272,9 @@ extern const struct _mp_obj_module_t ble_module;
{ MP_OBJ_NEW_QSTR (MP_QSTR_microcontroller ), (mp_obj_t)&microcontroller_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_bitbangio ), (mp_obj_t)&bitbangio_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_os ), (mp_obj_t)&os_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_precise_time ), (mp_obj_t)&precise_time_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_random ), (mp_obj_t)&random_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_storage ), (mp_obj_t)&storage_module },\
{ MP_OBJ_NEW_QSTR (MP_QSTR_storage ), (mp_obj_t)&storage_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_struct ), (mp_obj_t)&struct_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_supervisor ), (mp_obj_t)&supervisor_module }, \
{ MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \
Expand Down
86 changes: 86 additions & 0 deletions shared-bindings/precise_time/__init__.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Margaret Sy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <string.h>

#include "py/obj.h"
#include "py/runtime.h"
#include "shared-bindings/precise_time/__init__.h"

//| :mod:`precise_time` --- integer time and timing related functions
//| =======================================================================
//|
//| .. module:: precise_time
//| :synopsis: integer time related functions
//| :platform: SAMD21
//|
//| The `precise_time` module. See the `time` module instead for an API that is
//| also available in CPython.
//|
//| .. method:: monotonic()
//|
//| Returns an always increasing value of time with an unknown reference
//| point. Only use it to compare against other values from `monotonic`.
//| Unlike time.monotonic, which is a float, precise_time.monotonic returns an
//| int so precision will not degrade over time.
//|
//| :return: the current monotonic time
//| :rtype: int
//|
STATIC mp_obj_t precise_time_monotonic(void) {
return mp_obj_new_int_from_uint(common_hal_precise_time_monotonic());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I have not been in the loop on this, so @tannewt and @margaret please let me know if you've discussed this already).

mp_obj_new_int_from_uint() will silently truncate the common_hal_precise_time_monotonic() value when it overflows 2^32. 2^32 msecs is about 49.7 days. I could imagine a long-lived sensing program that hits that limit. If the incoming common_hal_precise_time_monotonic() is > 2^32 you could call mp_obj_new_int_from_ull(), which takes a long long (which is 64 bits).

Note that on non-longint builds, py/objint.c is used, and mp_obj_new_int_from_ull() throws OverflowError no matter what it's passed (even the arg would fit in a small int). On longint impls, py/objint_mpz.c is used. So the value needs to be tested and one or the other needs to be called depending on the size.

I think the behavior on non-longint impls should probably be documented: precise_time.time_monotonic() will raise OverflowError when the board has been running for 2^30 msecs or more (about 12.4 days)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We hadn't discussed how to deal with overflow, but these suggestions sound good. I'll work on these items later today.

}
MP_DEFINE_CONST_FUN_OBJ_0(precise_time_monotonic_obj, precise_time_monotonic);

//| .. method:: sleep(milliseconds)
//|
//| Sleep for a given number of milliseconds.
//|
//| :param int seconds: the time to sleep in milliseconds
//|
STATIC mp_obj_t precise_time_sleep(mp_obj_t milliseconds_o) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tannewt @margaret Maybe this should be called precise_time.sleep_ms, since the units are different than time.sleep? If we ever implement microsecond sleeps then we can have a precise_time.sleep_us as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I'll rename it to sleep_ms.

int milliseconds = mp_obj_get_int(milliseconds_o);
if (milliseconds < 0) {
mp_raise_ValueError("sleep length must be non-negative");
}
common_hal_precise_time_delay_ms(milliseconds);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(precise_time_sleep_obj, precise_time_sleep);

STATIC const mp_rom_map_elem_t precise_time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR__name__), MP_ROM_QSTR(MP_QSTR_precise_time) },

{ MP_ROM_QSTR(MP_QSTR_monotonic), MP_ROM_PTR(&precise_time_monotonic_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&precise_time_sleep_obj) }
};

STATIC MP_DEFINE_CONST_DICT(precise_time_module_globals, precise_time_module_globals_table);

const mp_obj_module_t precise_time_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&precise_time_module_globals,
};
35 changes: 35 additions & 0 deletions shared-bindings/precise_time/__init__.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Margaret Sy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PRECISE_TIME__INIT__H
#define MICROPY_INCLUDED_SHARED_BINDINGS_PRECISE_TIME__INIT__H

#include <stdint.h>

extern uint64_t common_hal_precise_time_monotonic(void);
extern void common_hal_precise_time_delay_ms(uint32_t);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PRECISE_TIME__INIT__H