Supervisor: move most of systick to the supervisor

This code is shared by most parts, except where not all the #ifdefs
inside the tick function were present in all ports.  This mostly would
have broken gamepad tick support on non-samd ports.

The "ms32" and "ms64" variants of the tick functions are introduced
because there is no 64-bit atomic read.  Disabling interrupts avoids
a low probability bug where milliseconds could be off by ~49.5 days
once every ~49.5 days (2^32 ms).

Avoiding disabling interrupts when only the low 32 bits are needed is a minor
optimization.

Testing performed: on metro m4 express, USB still works and
time.monotonic_ns() still counts up
This commit is contained in:
Jeff Epler 2019-11-18 08:22:41 -06:00
parent 45d1b290ee
commit 7f744a2369
37 changed files with 214 additions and 163 deletions

View File

@ -52,7 +52,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "tick.h" #include "supervisor/shared/tick.h"
//#include "Ethernet/socket.h" //#include "Ethernet/socket.h"
//#include "Internet/DNS/dns.h" //#include "Internet/DNS/dns.h"
@ -125,7 +125,7 @@ uint16_t DNS_MSGID; // DNS message ID
uint32_t HAL_GetTick(void) { uint32_t HAL_GetTick(void) {
return ticks_ms; return supervisor_ticks_ms32();
} }
uint32_t hal_sys_tick; uint32_t hal_sys_tick;

View File

@ -28,6 +28,7 @@
#include "audio_dma.h" #include "audio_dma.h"
#include "tick.h" #include "tick.h"
#include "supervisor/filesystem.h" #include "supervisor/filesystem.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include "py/runtime.h" #include "py/runtime.h"
@ -71,9 +72,9 @@ void run_background_tasks(void) {
running_background_tasks = false; running_background_tasks = false;
assert_heap_ok(); assert_heap_ok();
last_finished_tick = ticks_ms; last_finished_tick = supervisor_ticks_ms64();
} }
bool background_tasks_ok(void) { bool background_tasks_ok(void) {
return ticks_ms - last_finished_tick < 1000; return supervisor_ticks_ms64() - last_finished_tick < 1000;
} }

View File

@ -34,8 +34,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stream.h" #include "py/stream.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
#include "supervisor/shared/tick.h"
#include "tick.h"
#include "hpl_sercom_config.h" #include "hpl_sercom_config.h"
#include "peripheral_clk_config.h" #include "peripheral_clk_config.h"
@ -272,10 +271,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
usart_async_get_io_descriptor(usart_desc_p, &io); usart_async_get_io_descriptor(usart_desc_p, &io);
size_t total_read = 0; size_t total_read = 0;
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
// Busy-wait until timeout or until we've read enough chars. // Busy-wait until timeout or until we've read enough chars.
while (ticks_ms - start_ticks <= self->timeout_ms) { while (supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) {
// Read as many chars as we can right now, up to len. // Read as many chars as we can right now, up to len.
size_t num_read = io_read(io, data, len); size_t num_read = io_read(io, data, len);
@ -289,7 +288,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
} }
if (num_read > 0) { if (num_read > 0) {
// Reset the timeout on every character read. // Reset the timeout on every character read.
start_ticks = ticks_ms; start_ticks = supervisor_ticks_ms64();
} }
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt. // Allow user to break out of a timeout with a KeyboardInterrupt.
@ -330,9 +329,9 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
// Wait until write is complete or timeout. // Wait until write is complete or timeout.
bool done = false; bool done = false;
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
// Busy-wait for timeout. // Busy-wait for timeout.
while (ticks_ms - start_ticks < self->timeout_ms) { while (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) {
if (usart_async_is_tx_empty(usart_desc_p)) { if (usart_async_is_tx_empty(usart_desc_p)) {
done = true; done = true;
break; break;

View File

@ -28,10 +28,10 @@
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "tick.h" #include "supervisor/shared/tick.h"
inline uint64_t common_hal_time_monotonic() { inline uint64_t common_hal_time_monotonic() {
return ticks_ms; return supervisor_ticks_ms64();
} }
void common_hal_time_delay_ms(uint32_t delay) { void common_hal_time_delay_ms(uint32_t delay) {

View File

@ -45,12 +45,12 @@
#include "mpconfigboard.h" #include "mpconfigboard.h"
#include "mphalport.h" #include "mphalport.h"
#include "reset.h" #include "reset.h"
#include "tick.h" #include "supervisor/shared/tick.h"
extern uint32_t common_hal_mcu_processor_get_frequency(void); extern uint32_t common_hal_mcu_processor_get_frequency(void);
void mp_hal_delay_ms(mp_uint_t delay) { void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = ticks_ms; uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0; uint64_t duration = 0;
while (duration < delay) { while (duration < delay) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
@ -59,7 +59,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break; break;
} }
duration = (ticks_ms - start_tick); duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait. // TODO(tannewt): Go to sleep for a little while while we wait.
} }
} }

View File

@ -31,11 +31,11 @@
#include "lib/oofatfs/ff.h" #include "lib/oofatfs/ff.h"
// Global millisecond tick count (driven by SysTick interrupt). #include "supervisor/shared/tick.h"
extern volatile uint64_t ticks_ms;
// Global millisecond tick count (driven by SysTick interrupt).
static inline mp_uint_t mp_hal_ticks_ms(void) { static inline mp_uint_t mp_hal_ticks_ms(void) {
return ticks_ms; return supervisor_ticks_ms32();
} }
// Number of bytes in receive buffer // Number of bytes in receive buffer
volatile uint8_t usb_rx_count; volatile uint8_t usb_rx_count;

View File

@ -28,47 +28,21 @@
#include "peripheral_clk_config.h" #include "peripheral_clk_config.h"
#include "supervisor/shared/autoreload.h" #include "supervisor/shared/tick.h"
#include "supervisor/filesystem.h"
#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/Processor.h"
#if CIRCUITPY_GAMEPAD
#include "shared-module/gamepad/__init__.h"
#endif
#if CIRCUITPY_GAMEPADSHIFT
#include "shared-module/gamepadshift/__init__.h"
#endif
// Global millisecond tick count
volatile uint64_t ticks_ms = 0;
void SysTick_Handler(void) { void SysTick_Handler(void) {
// SysTick interrupt handler called when the SysTick timer reaches zero // SysTick interrupt handler called when the SysTick timer reaches zero
// (every millisecond). // (every millisecond).
common_hal_mcu_disable_interrupts(); common_hal_mcu_disable_interrupts();
ticks_ms += 1;
// Read the control register to reset the COUNTFLAG. // Read the control register to reset the COUNTFLAG.
(void) SysTick->CTRL; (void) SysTick->CTRL;
common_hal_mcu_enable_interrupts(); common_hal_mcu_enable_interrupts();
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0 // Do things common to all ports when the tick occurs
filesystem_tick(); supervisor_tick();
#endif
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
autoreload_tick();
#endif
#ifdef CIRCUITPY_GAMEPAD_TICKS
if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
#if CIRCUITPY_GAMEPAD
gamepad_tick();
#endif
#if CIRCUITPY_GAMEPADSHIFT
gamepadshift_tick();
#endif
}
#endif
} }
void tick_init() { void tick_init() {
@ -115,7 +89,7 @@ void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t tick_status = SysTick->CTRL; uint32_t tick_status = SysTick->CTRL;
uint32_t current_us = SysTick->VAL; uint32_t current_us = SysTick->VAL;
uint32_t tick_status2 = SysTick->CTRL; uint32_t tick_status2 = SysTick->CTRL;
uint64_t current_ms = ticks_ms; uint64_t current_ms = supervisor_ticks_ms64();
// The second clause ensures our value actually rolled over. Its possible it hit zero between // The second clause ensures our value actually rolled over. Its possible it hit zero between
// the VAL read and CTRL read. // the VAL read and CTRL read.
if ((tick_status & SysTick_CTRL_COUNTFLAG_Msk) != 0 || if ((tick_status & SysTick_CTRL_COUNTFLAG_Msk) != 0 ||
@ -129,5 +103,5 @@ void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
void wait_until(uint64_t ms, uint32_t us_until_ms) { void wait_until(uint64_t ms, uint32_t us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
while (ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} while (supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
} }

View File

@ -28,8 +28,6 @@
#include "py/mpconfig.h" #include "py/mpconfig.h"
extern volatile uint64_t ticks_ms;
extern struct timer_descriptor ms_timer; extern struct timer_descriptor ms_timer;
void tick_init(void); void tick_init(void);

View File

@ -26,10 +26,10 @@
#include "py/mphal.h" #include "py/mphal.h"
#include "tick.h" #include "supervisor/shared/tick.h"
uint64_t common_hal_time_monotonic(void) { uint64_t common_hal_time_monotonic(void) {
return ticks_ms; return supervisor_ticks_ms64();
} }
void common_hal_time_delay_ms(uint32_t delay) { void common_hal_time_delay_ms(uint32_t delay) {

View File

@ -31,7 +31,7 @@
#include "py/mpstate.h" #include "py/mpstate.h"
#include "tick.h" #include "supervisor/shared/tick.h"
#define DELAY_CORRECTION (700) #define DELAY_CORRECTION (700)
#define DELAY_INTERVAL (50) #define DELAY_INTERVAL (50)
@ -57,7 +57,7 @@ mp_uint_t mp_hal_ticks_cpu(void) {
} }
void mp_hal_delay_ms(mp_uint_t delay) { void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = ticks_ms; uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0; uint64_t duration = 0;
while (duration < delay) { while (duration < delay) {
#ifdef MICROPY_VM_HOOK_LOOP #ifdef MICROPY_VM_HOOK_LOOP
@ -68,7 +68,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break; break;
} }
duration = (ticks_ms - start_tick); duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait. // TODO(tannewt): Go to sleep for a little while while we wait.
} }
} }

View File

@ -31,6 +31,4 @@
#include "lib/utils/interrupt_char.h" #include "lib/utils/interrupt_char.h"
extern volatile uint64_t ticks_ms;
#endif // MICROPY_INCLUDED_CXD56_MPHALPORT_H #endif // MICROPY_INCLUDED_CXD56_MPHALPORT_H

View File

@ -27,19 +27,10 @@
#include "tick.h" #include "tick.h"
#include "supervisor/shared/autoreload.h" #include "supervisor/shared/autoreload.h"
#include "supervisor/filesystem.h" #include "supervisor/shared/tick.h"
// Global millisecond tick count
volatile uint64_t ticks_ms = 0;
void board_timerhook(void) void board_timerhook(void)
{ {
ticks_ms += 1; // Do things common to all ports when the tick occurs
supervisor_tick();
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
filesystem_tick();
#endif
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
autoreload_tick();
#endif
} }

View File

@ -29,6 +29,4 @@
#include "py/mpconfig.h" #include "py/mpconfig.h"
extern volatile uint64_t ticks_ms;
#endif // MICROPY_INCLUDED_CXD56_TICK_H #endif // MICROPY_INCLUDED_CXD56_TICK_H

View File

@ -40,6 +40,7 @@
#include "py/objstr.h" #include "py/objstr.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "supervisor/shared/safe_mode.h" #include "supervisor/shared/safe_mode.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Adapter.h"
@ -353,7 +354,7 @@ STATIC bool scan_on_ble_evt(ble_evt_t *ble_evt, void *scan_results_in) {
ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report; ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
shared_module_bleio_scanresults_append(scan_results, shared_module_bleio_scanresults_append(scan_results,
ticks_ms, supervisor_ticks_ms64(),
report->type.connectable, report->type.connectable,
report->type.scan_response, report->type.scan_response,
report->rssi, report->rssi,

View File

@ -39,6 +39,7 @@
#include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Connection.h" #include "shared-bindings/_bleio/Connection.h"
#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h" #include "common-hal/_bleio/CharacteristicBuffer.h"
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) { STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
@ -100,10 +101,10 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
} }
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) { int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout // Wait for all bytes received or timeout
while ( (ringbuf_count(&self->ringbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { while ( (ringbuf_count(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt. // Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) { if ( mp_hal_is_interrupted() ) {

View File

@ -231,10 +231,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
} }
size_t rx_bytes = 0; size_t rx_bytes = 0;
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout // Wait for all bytes received or timeout
while ( (ringbuf_count(&self->rbuf) < len) && (ticks_ms - start_ticks < self->timeout_ms) ) { while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt. // Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) { if ( mp_hal_is_interrupted() ) {
@ -265,15 +265,15 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
if ( len == 0 ) return 0; if ( len == 0 ) return 0;
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for on-going transfer to complete // Wait for on-going transfer to complete
while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { while ( nrfx_uarte_tx_in_progress(self->uarte) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
// Time up // Time up
if ( !(ticks_ms - start_ticks < self->timeout_ms) ) { if ( !(supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
*errcode = MP_EAGAIN; *errcode = MP_EAGAIN;
return MP_STREAM_ERROR; return MP_STREAM_ERROR;
} }
@ -290,7 +290,7 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data,
_VERIFY_ERR(*errcode); _VERIFY_ERR(*errcode);
(*errcode) = 0; (*errcode) = 0;
while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { while ( nrfx_uarte_tx_in_progress(self->uarte) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }

View File

@ -29,7 +29,7 @@
#include "tick.h" #include "tick.h"
uint64_t common_hal_time_monotonic(void) { uint64_t common_hal_time_monotonic(void) {
return ticks_ms; return supervisor_ticks_ms64();
} }
void common_hal_time_delay_ms(uint32_t delay) { void common_hal_time_delay_ms(uint32_t delay) {

View File

@ -31,12 +31,13 @@
#include "py/mphal.h" #include "py/mphal.h"
#include "py/mpstate.h" #include "py/mpstate.h"
#include "py/gc.h" #include "py/gc.h"
#include "supervisor/shared/tick.h"
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* delay /* delay
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
void mp_hal_delay_ms(mp_uint_t delay) { void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = ticks_ms; uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0; uint64_t duration = 0;
while (duration < delay) { while (duration < delay) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
@ -45,7 +46,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break; break;
} }
duration = (ticks_ms - start_tick); duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait. // TODO(tannewt): Go to sleep for a little while while we wait.
} }
} }

View File

@ -33,12 +33,11 @@
#include "lib/utils/interrupt_char.h" #include "lib/utils/interrupt_char.h"
#include "nrfx_uarte.h" #include "nrfx_uarte.h"
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "supervisor/shared/tick.h"
extern nrfx_uarte_t serial_instance; extern nrfx_uarte_t serial_instance;
extern volatile uint64_t ticks_ms; #define mp_hal_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms)
#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) #define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
bool mp_hal_stdin_any(void); bool mp_hal_stdin_any(void);

View File

@ -26,31 +26,14 @@
#include "tick.h" #include "tick.h"
#include "supervisor/shared/autoreload.h" #include "supervisor/shared/tick.h"
#include "supervisor/filesystem.h"
#include "shared-module/gamepad/__init__.h" #include "shared-module/gamepad/__init__.h"
#include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/Processor.h"
#include "nrf.h" #include "nrf.h"
// Global millisecond tick count
volatile uint64_t ticks_ms = 0;
void SysTick_Handler(void) { void SysTick_Handler(void) {
// SysTick interrupt handler called when the SysTick timer reaches zero // Do things common to all ports when the tick occurs
// (every millisecond). supervisor_tick();
ticks_ms += 1;
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
filesystem_tick();
#endif
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
autoreload_tick();
#endif
#ifdef CIRCUITPY_GAMEPAD_TICKS
if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
gamepad_tick();
}
#endif
} }
void tick_init() { void tick_init() {
@ -61,11 +44,11 @@ void tick_init() {
void tick_delay(uint32_t us) { void tick_delay(uint32_t us) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; uint32_t us_between_ticks = SysTick->VAL / ticks_per_us;
uint64_t start_ms = ticks_ms; uint64_t start_ms = supervisor_ticks_ms64();
while (us > 1000) { while (us > 1000) {
while (ticks_ms == start_ms) {} while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks; us -= us_between_ticks;
start_ms = ticks_ms; start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000; us_between_ticks = 1000;
} }
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {} while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@ -74,11 +57,11 @@ void tick_delay(uint32_t us) {
// us counts down! // us counts down!
void current_tick(uint64_t* ms, uint32_t* us_until_ms) { void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
*ms = ticks_ms; *ms = supervisor_ticks_ms64();
*us_until_ms = SysTick->VAL / ticks_per_us; *us_until_ms = SysTick->VAL / ticks_per_us;
} }
void wait_until(uint64_t ms, uint32_t us_until_ms) { void wait_until(uint64_t ms, uint32_t us_until_ms) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000; uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} while(supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
} }

View File

@ -30,8 +30,6 @@
#include <stdint.h> #include <stdint.h>
extern volatile uint64_t ticks_ms;
extern struct timer_descriptor ms_timer; extern struct timer_descriptor ms_timer;
void tick_init(void); void tick_init(void);

View File

@ -29,7 +29,7 @@
#include "tick.h" #include "tick.h"
uint64_t common_hal_time_monotonic(void) { uint64_t common_hal_time_monotonic(void) {
return ticks_ms; return supervisor_ticks_ms64();
} }
void common_hal_time_delay_ms(uint32_t delay) { void common_hal_time_delay_ms(uint32_t delay) {

View File

@ -31,11 +31,13 @@
#include "py/mpstate.h" #include "py/mpstate.h"
#include "py/gc.h" #include "py/gc.h"
#include "supervisor/shared/tick.h"
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* delay /* delay
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
void mp_hal_delay_ms(mp_uint_t delay) { void mp_hal_delay_ms(mp_uint_t delay) {
uint64_t start_tick = ticks_ms; uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0; uint64_t duration = 0;
while (duration < delay) { while (duration < delay) {
#ifdef MICROPY_VM_HOOK_LOOP #ifdef MICROPY_VM_HOOK_LOOP
@ -46,7 +48,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
break; break;
} }
duration = (ticks_ms - start_tick); duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait. // TODO(tannewt): Go to sleep for a little while while we wait.
} }
} }

View File

@ -32,10 +32,10 @@
#include "lib/utils/interrupt_char.h" #include "lib/utils/interrupt_char.h"
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "supervisor/shared/tick.h"
extern volatile uint64_t ticks_ms;
#define mp_hal_ticks_ms() ((mp_uint_t) ticks_ms) #define mp_hal_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us)) //#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
bool mp_hal_stdin_any(void); bool mp_hal_stdin_any(void);

View File

@ -26,37 +26,23 @@
#include "tick.h" #include "tick.h"
#include "supervisor/shared/autoreload.h"
#include "supervisor/filesystem.h" #include "supervisor/filesystem.h"
#include "shared-module/gamepad/__init__.h" #include "supervisor/shared/tick.h"
#include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/Processor.h"
#include "stm32f4xx.h" #include "stm32f4xx.h"
// Global millisecond tick count
volatile uint64_t ticks_ms = 0;
void SysTick_Handler(void) { void SysTick_Handler(void) {
// SysTick interrupt handler called when the SysTick timer reaches zero // SysTick interrupt handler called when the SysTick timer reaches zero
// (every millisecond). // (every millisecond).
ticks_ms += 1;
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0 // Do things common to all ports when the tick occurs
filesystem_tick(); supervisor_tick();
#endif
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
autoreload_tick();
#endif
#ifdef CIRCUITPY_GAMEPAD_TICKS
if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
gamepad_tick();
}
#endif
} }
uint32_t HAL_GetTick(void) //override ST HAL uint32_t HAL_GetTick(void) //override ST HAL
{ {
return (uint32_t)ticks_ms; return (uint32_t)supervisor_ticks_ms32();
} }
void tick_init() { void tick_init() {
@ -72,11 +58,11 @@ void tick_init() {
void tick_delay(uint32_t us) { void tick_delay(uint32_t us) {
uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
uint32_t us_between_ticks = SysTick->VAL / ticks_per_us; uint32_t us_between_ticks = SysTick->VAL / ticks_per_us;
uint64_t start_ms = ticks_ms; uint64_t start_ms = supervisor_ticks_ms64();
while (us > 1000) { while (us > 1000) {
while (ticks_ms == start_ms) {} while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks; us -= us_between_ticks;
start_ms = ticks_ms; start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000; us_between_ticks = 1000;
} }
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {} while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@ -85,11 +71,11 @@ void tick_delay(uint32_t us) {
// us counts down! // us counts down!
void current_tick(uint64_t* ms, uint32_t* us_until_ms) { void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
*ms = ticks_ms; *ms = supervisor_ticks_ms32();
*us_until_ms = SysTick->VAL / ticks_per_us; *us_until_ms = SysTick->VAL / ticks_per_us;
} }
void wait_until(uint64_t ms, uint32_t us_until_ms) { void wait_until(uint64_t ms, uint32_t us_until_ms) {
uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000; uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
while(ticks_ms <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {} while(supervisor_ticks_ms64() <= ms && SysTick->VAL / ticks_per_us >= us_until_ms) {}
} }

View File

@ -30,8 +30,6 @@
#include <stdint.h> #include <stdint.h>
extern volatile uint64_t ticks_ms;
extern struct timer_descriptor ms_timer; extern struct timer_descriptor ms_timer;
void tick_init(void); void tick_init(void);

View File

@ -32,6 +32,7 @@
#define __INCLUDED_MPCONFIG_CIRCUITPY_H #define __INCLUDED_MPCONFIG_CIRCUITPY_H
#include <stdint.h> #include <stdint.h>
#include <stdatomic.h>
// This is CircuitPython. // This is CircuitPython.
#define CIRCUITPY 1 #define CIRCUITPY 1

View File

@ -35,6 +35,7 @@
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/display_core.h" #include "shared-module/displayio/display_core.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include <stdint.h> #include <stdint.h>
@ -313,7 +314,7 @@ uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self
bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
if (!self->auto_refresh && !self->first_manual_refresh) { if (!self->auto_refresh && !self->first_manual_refresh) {
uint64_t current_time = ticks_ms; uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum. // Test to see if the real frame time is below our minimum.
if (current_ms_since_real_refresh > maximum_ms_per_real_frame) { if (current_ms_since_real_refresh > maximum_ms_per_real_frame) {
@ -327,7 +328,7 @@ bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_
} }
uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame); uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame);
// We're ahead of the game so wait until we align with the frame rate. // We're ahead of the game so wait until we align with the frame rate.
while (ticks_ms - self->last_refresh_call < remaining_time) { while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
} }
@ -350,20 +351,20 @@ STATIC void _update_backlight(displayio_display_obj_t* self) {
if (!self->auto_brightness || self->updating_backlight) { if (!self->auto_brightness || self->updating_backlight) {
return; return;
} }
if (ticks_ms - self->last_backlight_refresh < 100) { if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) {
return; return;
} }
// TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
// should account for ambient light when possible. // should account for ambient light when possible.
common_hal_displayio_display_set_brightness(self, 1.0); common_hal_displayio_display_set_brightness(self, 1.0);
self->last_backlight_refresh = ticks_ms; self->last_backlight_refresh = supervisor_ticks_ms64();
} }
void displayio_display_background(displayio_display_obj_t* self) { void displayio_display_background(displayio_display_obj_t* self) {
_update_backlight(self); _update_backlight(self);
if (self->auto_refresh && (ticks_ms - self->core.last_refresh) > self->native_ms_per_frame) { if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) {
_refresh_display(self); _refresh_display(self);
} }
} }

View File

@ -35,6 +35,7 @@
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include <stdint.h> #include <stdint.h>
@ -175,7 +176,7 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper
return 0; return 0;
} }
// Refresh at seconds per frame rate. // Refresh at seconds per frame rate.
uint32_t elapsed_time = ticks_ms - self->core.last_refresh; uint32_t elapsed_time = supervisor_ticks_ms64() - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) { if (elapsed_time > self->milliseconds_per_frame) {
return 0; return 0;
} }
@ -339,7 +340,7 @@ void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy); bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy);
refresh_done = busy != self->busy_state; refresh_done = busy != self->busy_state;
} else { } else {
refresh_done = ticks_ms - self->core.last_refresh > self->refresh_time; refresh_done = supervisor_ticks_ms64() - self->core.last_refresh > self->refresh_time;
} }
if (refresh_done) { if (refresh_done) {
self->refreshing = false; self->refreshing = false;

View File

@ -35,6 +35,7 @@
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/shared/tick.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -281,7 +282,7 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
} }
void displayio_display_core_start_refresh(displayio_display_core_t* self) { void displayio_display_core_start_refresh(displayio_display_core_t* self) {
self->last_refresh = ticks_ms; self->last_refresh = supervisor_ticks_ms64();
} }
void displayio_display_core_finish_refresh(displayio_display_core_t* self) { void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
@ -289,7 +290,7 @@ void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
displayio_group_finish_refresh(self->current_group); displayio_group_finish_refresh(self->current_group);
} }
self->full_refresh = false; self->full_refresh = false;
self->last_refresh = ticks_ms; self->last_refresh = supervisor_ticks_ms64();
} }
void release_display_core(displayio_display_core_t* self) { void release_display_core(displayio_display_core_t* self) {

View File

@ -31,6 +31,8 @@
#include "py/mphal.h" #include "py/mphal.h"
#include "py/mperrno.h" #include "py/mperrno.h"
#include "supervisor/shared/tick.h"
#include "shared-bindings/random/__init__.h" #include "shared-bindings/random/__init__.h"
#include "shared-module/network/__init__.h" #include "shared-module/network/__init__.h"
@ -53,7 +55,7 @@ void network_module_deinit(void) {
void network_module_background(void) { void network_module_background(void) {
static uint32_t next_tick = 0; static uint32_t next_tick = 0;
uint32_t this_tick = ticks_ms; uint32_t this_tick = supervisor_ticks_ms32();
if (this_tick < next_tick) return; if (this_tick < next_tick) return;
next_tick = this_tick + 1000; next_tick = this_tick + 1000;

View File

@ -30,6 +30,7 @@
#include "shared-bindings/usb_hid/Device.h" #include "shared-bindings/usb_hid/Device.h"
#include "shared-module/usb_hid/Device.h" #include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
#include "supervisor/shared/tick.h"
#include "tusb.h" #include "tusb.h"
uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
@ -46,8 +47,8 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t*
} }
// Wait until interface is ready, timeout = 2 seconds // Wait until interface is ready, timeout = 2 seconds
uint64_t end_ticks = ticks_ms + 2000; uint64_t end_ticks = supervisor_ticks_ms64() + 2000;
while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) { while ( (supervisor_ticks_ms64() < end_ticks) && !tud_hid_ready() ) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }

View File

@ -27,6 +27,7 @@
#include "mphalport.h" #include "mphalport.h"
#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h"
#include "rgb_led_status.h" #include "rgb_led_status.h"
#include "supervisor/shared/tick.h"
#ifdef MICROPY_HW_NEOPIXEL #ifdef MICROPY_HW_NEOPIXEL
uint8_t rgb_status_brightness = 63; uint8_t rgb_status_brightness = 63;
@ -360,7 +361,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
rgb_status_animation_t* status) { rgb_status_animation_t* status) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
new_status_color(ALL_DONE); new_status_color(ALL_DONE);
status->pattern_start = ticks_ms; status->pattern_start = supervisor_ticks_ms32();
status->safe_mode = safe_mode; status->safe_mode = safe_mode;
status->found_main = found_main; status->found_main = found_main;
status->total_exception_cycle = 0; status->total_exception_cycle = 0;
@ -405,11 +406,11 @@ void prep_rgb_status_animation(const pyexec_result_t* result,
void tick_rgb_status_animation(rgb_status_animation_t* status) { void tick_rgb_status_animation(rgb_status_animation_t* status) {
#if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED))
uint32_t tick_diff = ticks_ms - status->pattern_start; uint32_t tick_diff = supervisor_ticks_ms32() - status->pattern_start;
if (status->ok) { if (status->ok) {
// All is good. Ramp ALL_DONE up and down. // All is good. Ramp ALL_DONE up and down.
if (tick_diff > ALL_GOOD_CYCLE_MS) { if (tick_diff > ALL_GOOD_CYCLE_MS) {
status->pattern_start = ticks_ms; status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0; tick_diff = 0;
} }
@ -424,7 +425,7 @@ void tick_rgb_status_animation(rgb_status_animation_t* status) {
} }
} else { } else {
if (tick_diff > status->total_exception_cycle) { if (tick_diff > status->total_exception_cycle) {
status->pattern_start = ticks_ms; status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0; tick_diff = 0;
} }
// First flash the file color. // First flash the file color.

View File

@ -34,6 +34,7 @@
#include "supervisor/shared/rgb_led_colors.h" #include "supervisor/shared/rgb_led_colors.h"
#include "supervisor/shared/rgb_led_status.h" #include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
#include "supervisor/shared/tick.h"
#define SAFE_MODE_DATA_GUARD 0xad0000af #define SAFE_MODE_DATA_GUARD 0xad0000af
#define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff #define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff
@ -59,14 +60,14 @@ safe_mode_t wait_for_safe_mode_reset(void) {
common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS); common_hal_digitalio_digitalinout_construct(&status_led, MICROPY_HW_LED_STATUS);
common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL);
#endif #endif
uint64_t start_ticks = ticks_ms; uint64_t start_ticks = supervisor_ticks_ms64();
uint64_t diff = 0; uint64_t diff = 0;
while (diff < 700) { while (diff < 700) {
#ifdef MICROPY_HW_LED_STATUS #ifdef MICROPY_HW_LED_STATUS
// Blink on for 100, off for 100, on for 100, off for 100 and on for 200 // Blink on for 100, off for 100, on for 100, off for 100 and on for 200
common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4); common_hal_digitalio_digitalinout_set_value(&status_led, diff > 100 && diff / 100 != 2 && diff / 100 != 4);
#endif #endif
diff = ticks_ms - start_ticks; diff = supervisor_ticks_ms64() - start_ticks;
} }
#ifdef MICROPY_HW_LED_STATUS #ifdef MICROPY_HW_LED_STATUS
common_hal_digitalio_digitalinout_deinit(&status_led); common_hal_digitalio_digitalinout_deinit(&status_led);

76
supervisor/shared/tick.c Normal file
View File

@ -0,0 +1,76 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Jeff Epler for Adafruit Industries
*
* 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 "supervisor/shared/tick.h"
#include "supervisor/filesystem.h"
#include "supervisor/shared/autoreload.h"
static volatile uint64_t ticks_ms;
#if CIRCUITPY_GAMEPAD
#include "shared-module/gamepad/__init__.h"
#endif
#if CIRCUITPY_GAMEPADSHIFT
#include "shared-module/gamepadshift/__init__.h"
#endif
#include "shared-bindings/microcontroller/__init__.h"
void supervisor_tick(void) {
ticks_ms ++;
#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
filesystem_tick();
#endif
#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
autoreload_tick();
#endif
#ifdef CIRCUITPY_GAMEPAD_TICKS
if (!(ticks_ms & CIRCUITPY_GAMEPAD_TICKS)) {
#if CIRCUITPY_GAMEPAD
gamepad_tick();
#endif
#if CIRCUITPY_GAMEPADSHIFT
gamepadshift_tick();
#endif
}
#endif
}
uint64_t supervisor_ticks_ms64() {
uint64_t result;
common_hal_mcu_disable_interrupts();
result = ticks_ms;
common_hal_mcu_enable_interrupts();
return result;
}
uint32_t supervisor_ticks_ms32() {
return ticks_ms;
}

37
supervisor/shared/tick.h Normal file
View File

@ -0,0 +1,37 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Jeff Epler for Adafruit Industries
*
* 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 __INCLUDED_SUPERVISOR_TICK_H
#define __INCLUDED_SUPERVISOR_TICK_H
#include <stdint.h>
#include <stdatomic.h>
extern void supervisor_tick(void);
extern uint32_t supervisor_ticks_ms32(void);
extern uint64_t supervisor_ticks_ms64(void);
#endif

View File

@ -10,6 +10,7 @@ SRC_SUPERVISOR = \
supervisor/shared/safe_mode.c \ supervisor/shared/safe_mode.c \
supervisor/shared/stack.c \ supervisor/shared/stack.c \
supervisor/shared/status_leds.c \ supervisor/shared/status_leds.c \
supervisor/shared/tick.c \
supervisor/shared/translate.c supervisor/shared/translate.c
ifndef $(NO_USB) ifndef $(NO_USB)