summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml3
-rw-r--r--drivers/wiznet5k/internet/dns/dns.c4
-rw-r--r--locale/zh_Latn_pinyin.po6
-rw-r--r--ports/atmel-samd/Makefile9
-rw-r--r--ports/atmel-samd/background.c26
-rw-r--r--ports/atmel-samd/boards/pewpew10/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pyruler/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c9
-rw-r--r--ports/atmel-samd/common-hal/time/__init__.c4
-rw-r--r--ports/atmel-samd/mphalport.c6
-rw-r--r--ports/atmel-samd/mphalport.h6
-rw-r--r--ports/atmel-samd/tick.c36
-rw-r--r--ports/atmel-samd/tick.h2
-rw-r--r--ports/cxd56/common-hal/time/__init__.c4
-rw-r--r--ports/cxd56/mphalport.c6
-rw-r--r--ports/cxd56/mphalport.h2
-rw-r--r--ports/cxd56/tick.c15
-rw-r--r--ports/cxd56/tick.h2
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c3
-rw-r--r--ports/nrf/common-hal/_bleio/CharacteristicBuffer.c5
-rw-r--r--ports/nrf/common-hal/busio/UART.c4
-rw-r--r--ports/nrf/common-hal/time/__init__.c2
-rw-r--r--ports/nrf/mphalport.c5
-rw-r--r--ports/nrf/mphalport.h5
-rw-r--r--ports/nrf/tick.c33
-rw-r--r--ports/nrf/tick.h2
-rw-r--r--ports/stm32f4/common-hal/busio/UART.c4
-rw-r--r--ports/stm32f4/common-hal/microcontroller/__init__.c4
-rw-r--r--ports/stm32f4/common-hal/time/__init__.c2
-rw-r--r--ports/stm32f4/mphalport.c6
-rw-r--r--ports/stm32f4/mphalport.h4
-rw-r--r--ports/stm32f4/tick.c32
-rw-r--r--ports/stm32f4/tick.h2
-rw-r--r--py/circuitpy_mpconfig.h13
-rw-r--r--py/makeqstrdata.py39
-rw-r--r--shared-module/displayio/Display.c11
-rw-r--r--shared-module/displayio/EPaperDisplay.c5
-rw-r--r--shared-module/displayio/display_core.c5
-rw-r--r--shared-module/network/__init__.c4
-rw-r--r--shared-module/usb_hid/Device.c5
-rw-r--r--supervisor/shared/rgb_led_status.c9
-rw-r--r--supervisor/shared/safe_mode.c5
-rw-r--r--supervisor/shared/tick.c94
-rw-r--r--supervisor/shared/tick.h67
-rw-r--r--supervisor/shared/translate.c20
-rw-r--r--supervisor/supervisor.mk1
48 files changed, 349 insertions, 195 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bc22361bd..7fd816b30 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -169,7 +169,8 @@ jobs:
run: |
sudo apt-get install -y gettext
pip install requests sh click setuptools awscli
- wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~xenial1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb
+ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
+ sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2
- name: Versions
run: |
gcc --version
diff --git a/drivers/wiznet5k/internet/dns/dns.c b/drivers/wiznet5k/internet/dns/dns.c
index daf4db123..8b9e96670 100644
--- a/drivers/wiznet5k/internet/dns/dns.c
+++ b/drivers/wiznet5k/internet/dns/dns.c
@@ -52,7 +52,7 @@
#include <string.h>
#include <stdlib.h>
-#include "tick.h"
+#include "supervisor/shared/tick.h"
//#include "Ethernet/socket.h"
//#include "Internet/DNS/dns.h"
@@ -125,7 +125,7 @@ uint16_t DNS_MSGID; // DNS message ID
uint32_t HAL_GetTick(void) {
- return ticks_ms;
+ return supervisor_ticks_ms32();
}
uint32_t hal_sys_tick;
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index b45650d87..de78d35b5 100644
--- a/locale/zh_Latn_pinyin.po
+++ b/locale/zh_Latn_pinyin.po
@@ -673,11 +673,11 @@ msgstr "Shūrù/shūchū cuòwù"
#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Insufficient authentication"
-msgstr ""
+msgstr "Rènzhèng bùzú"
#: ports/nrf/common-hal/_bleio/__init__.c
msgid "Insufficient encryption"
-msgstr ""
+msgstr "Jiāmì bùzú"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
@@ -2465,7 +2465,7 @@ msgstr "time.struct_time() xūyào 9 xùliè"
#: shared-bindings/busio/UART.c
msgid "timeout must be 0.0-100.0 seconds"
-msgstr ""
+msgstr "Chāo shí shíjiān bìxū wèi 0.0 Dào 100.0 Miǎo"
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "timeout must be >= 0.0"
diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile
index 11e6874ed..5d47fd087 100644
--- a/ports/atmel-samd/Makefile
+++ b/ports/atmel-samd/Makefile
@@ -122,7 +122,16 @@ else
ifdef CFLAGS_INLINE_LIMIT
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
endif
+
CFLAGS += -flto -flto-partition=none
+
+ ifeq ($(CIRCUITPY_SMALL_BUILD),1)
+ CFLAGS += --param inline-unit-growth=15 --param max-inline-insns-auto=20
+ endif
+
+ ifdef CFLAGS_BOARD
+ CFLAGS += $(CFLAGS_BOARD)
+ endif
endif
CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c
index 386ba0715..ca91a31de 100644
--- a/ports/atmel-samd/background.c
+++ b/ports/atmel-samd/background.c
@@ -28,6 +28,7 @@
#include "audio_dma.h"
#include "tick.h"
#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "py/runtime.h"
@@ -44,6 +45,23 @@ bool stack_ok_so_far = true;
static bool running_background_tasks = false;
+#ifdef MONITOR_BACKGROUND_TASKS
+// PB03 is physical pin "SCL" on the Metro M4 express
+// so you can't use this code AND an i2c peripheral
+// at the same time unless you change this
+STATIC void start_background_task(void) {
+ REG_PORT_DIRSET1 = (1<<3);
+ REG_PORT_OUTSET1 = (1<<3);
+}
+
+STATIC void finish_background_task(void) {
+ REG_PORT_OUTCLR1 = (1<<3);
+}
+#else
+STATIC void start_background_task(void) {}
+STATIC void finish_background_task(void) {}
+#endif
+
void background_tasks_reset(void) {
running_background_tasks = false;
}
@@ -53,6 +71,9 @@ void run_background_tasks(void) {
if (running_background_tasks) {
return;
}
+
+ start_background_task();
+
assert_heap_ok();
running_background_tasks = true;
@@ -71,9 +92,10 @@ void run_background_tasks(void) {
running_background_tasks = false;
assert_heap_ok();
- last_finished_tick = ticks_ms;
+ last_finished_tick = supervisor_ticks_ms64();
+ finish_background_task();
}
bool background_tasks_ok(void) {
- return ticks_ms - last_finished_tick < 1000;
+ return supervisor_ticks_ms64() - last_finished_tick < 1000;
}
diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
index e24a29051..8a1d6b16a 100644
--- a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk
@@ -23,3 +23,5 @@ CIRCUITPY_USB_MIDI = 0
SUPEROPT_GC = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
index 6ce25cf69..8b82f0a09 100644
--- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk
@@ -29,3 +29,5 @@ SUPEROPT_GC = 0
# FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote
+
+CFLAGS_BOARD = --param max-inline-insns-auto=12
diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
index 9d9e4ba34..63d4cfed7 100644
--- a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk
@@ -13,6 +13,7 @@ CIRCUITPY_SMALL_BUILD = 1
SUPEROPT_GC = 0
+CFLAGS_BOARD = --param max-inline-insns-auto=15
ifeq ($(TRANSLATION), zh_Latn_pinyin)
CFLAGS_INLINE_LIMIT = 35
-endif
+endif \ No newline at end of file
diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
index b4a00b654..af8b561a2 100644
--- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk
@@ -12,3 +12,9 @@ LONGINT_IMPL = NONE
CIRCUITPY_SMALL_BUILD = 1
SUPEROPT_GC = 0
+
+CFLAGS_BOARD = --param max-inline-insns-auto=15
+ifeq ($(TRANSLATION), zh_Latn_pinyin)
+CFLAGS_INLINE_LIMIT = 35
+endif
+
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index d869f70ff..4ad47a58d 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -34,8 +34,7 @@
#include "py/runtime.h"
#include "py/stream.h"
#include "supervisor/shared/translate.h"
-
-#include "tick.h"
+#include "supervisor/shared/tick.h"
#include "hpl_sercom_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);
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.
- 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.
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) {
// Reset the timeout on every character read.
- start_ticks = ticks_ms;
+ start_ticks = supervisor_ticks_ms64();
}
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
diff --git a/ports/atmel-samd/common-hal/time/__init__.c b/ports/atmel-samd/common-hal/time/__init__.c
index 0d60adef2..2d82b3d1a 100644
--- a/ports/atmel-samd/common-hal/time/__init__.c
+++ b/ports/atmel-samd/common-hal/time/__init__.c
@@ -28,10 +28,10 @@
#include "shared-bindings/time/__init__.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
inline uint64_t common_hal_time_monotonic() {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/atmel-samd/mphalport.c b/ports/atmel-samd/mphalport.c
index 957bf6073..96433d729 100644
--- a/ports/atmel-samd/mphalport.c
+++ b/ports/atmel-samd/mphalport.c
@@ -45,12 +45,12 @@
#include "mpconfigboard.h"
#include "mphalport.h"
#include "reset.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
extern uint32_t common_hal_mcu_processor_get_frequency(void);
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;
while (duration < delay) {
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))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/atmel-samd/mphalport.h b/ports/atmel-samd/mphalport.h
index 64269b201..8a762e258 100644
--- a/ports/atmel-samd/mphalport.h
+++ b/ports/atmel-samd/mphalport.h
@@ -31,11 +31,11 @@
#include "lib/oofatfs/ff.h"
-// Global millisecond tick count (driven by SysTick interrupt).
-extern volatile uint64_t ticks_ms;
+#include "supervisor/shared/tick.h"
+// Global millisecond tick count (driven by SysTick interrupt).
static inline mp_uint_t mp_hal_ticks_ms(void) {
- return ticks_ms;
+ return supervisor_ticks_ms32();
}
// Number of bytes in receive buffer
volatile uint8_t usb_rx_count;
diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c
index 4d7bb9dca..f996440ae 100644
--- a/ports/atmel-samd/tick.c
+++ b/ports/atmel-samd/tick.c
@@ -28,47 +28,21 @@
#include "peripheral_clk_config.h"
-#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "shared-bindings/microcontroller/__init__.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) {
// SysTick interrupt handler called when the SysTick timer reaches zero
// (every millisecond).
common_hal_mcu_disable_interrupts();
- ticks_ms += 1;
// Read the control register to reset the COUNTFLAG.
(void) SysTick->CTRL;
common_hal_mcu_enable_interrupts();
-#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
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
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 current_us = SysTick->VAL;
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 VAL read and CTRL read.
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) {
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) {}
}
diff --git a/ports/atmel-samd/tick.h b/ports/atmel-samd/tick.h
index c8c8d739a..334352df2 100644
--- a/ports/atmel-samd/tick.h
+++ b/ports/atmel-samd/tick.h
@@ -28,8 +28,6 @@
#include "py/mpconfig.h"
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/ports/cxd56/common-hal/time/__init__.c b/ports/cxd56/common-hal/time/__init__.c
index 8f7326b62..6f5eedd41 100644
--- a/ports/cxd56/common-hal/time/__init__.c
+++ b/ports/cxd56/common-hal/time/__init__.c
@@ -26,10 +26,10 @@
#include "py/mphal.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/cxd56/mphalport.c b/ports/cxd56/mphalport.c
index 79d93f975..1305706ca 100644
--- a/ports/cxd56/mphalport.c
+++ b/ports/cxd56/mphalport.c
@@ -31,7 +31,7 @@
#include "py/mpstate.h"
-#include "tick.h"
+#include "supervisor/shared/tick.h"
#define DELAY_CORRECTION (700)
#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) {
- uint64_t start_tick = ticks_ms;
+ uint64_t start_tick = supervisor_ticks_ms64();
uint64_t duration = 0;
while (duration < delay) {
#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))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/cxd56/mphalport.h b/ports/cxd56/mphalport.h
index 25bca97ad..a2be10b8d 100644
--- a/ports/cxd56/mphalport.h
+++ b/ports/cxd56/mphalport.h
@@ -31,6 +31,4 @@
#include "lib/utils/interrupt_char.h"
-extern volatile uint64_t ticks_ms;
-
#endif // MICROPY_INCLUDED_CXD56_MPHALPORT_H
diff --git a/ports/cxd56/tick.c b/ports/cxd56/tick.c
index 6529db790..671b82b74 100644
--- a/ports/cxd56/tick.c
+++ b/ports/cxd56/tick.c
@@ -27,19 +27,10 @@
#include "tick.h"
#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
-
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
+#include "supervisor/shared/tick.h"
void board_timerhook(void)
{
- ticks_ms += 1;
-
-#if CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS > 0
- filesystem_tick();
-#endif
-#ifdef CIRCUITPY_AUTORELOAD_DELAY_MS
- autoreload_tick();
-#endif
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
diff --git a/ports/cxd56/tick.h b/ports/cxd56/tick.h
index a0d9ee526..d641d9cd4 100644
--- a/ports/cxd56/tick.h
+++ b/ports/cxd56/tick.h
@@ -29,6 +29,4 @@
#include "py/mpconfig.h"
-extern volatile uint64_t ticks_ms;
-
#endif // MICROPY_INCLUDED_CXD56_TICK_H
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index ec8d36111..85c159c6d 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -40,6 +40,7 @@
#include "py/objstr.h"
#include "py/runtime.h"
#include "supervisor/shared/safe_mode.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
@@ -343,7 +344,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;
shared_module_bleio_scanresults_append(scan_results,
- ticks_ms,
+ supervisor_ticks_ms64(),
report->type.connectable,
report->type.scan_response,
report->rssi,
diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
index 5f280e121..9f9b453de 100644
--- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
@@ -39,6 +39,7 @@
#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Connection.h"
+#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
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) {
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
// 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;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index a0ae8af00..9cdc197e7 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -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;
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
// 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;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
diff --git a/ports/nrf/common-hal/time/__init__.c b/ports/nrf/common-hal/time/__init__.c
index e3cb481ef..976f519db 100644
--- a/ports/nrf/common-hal/time/__init__.c
+++ b/ports/nrf/common-hal/time/__init__.c
@@ -29,7 +29,7 @@
#include "tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index bcd9fb114..3885d5a82 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -31,12 +31,13 @@
#include "py/mphal.h"
#include "py/mpstate.h"
#include "py/gc.h"
+#include "supervisor/shared/tick.h"
/*------------------------------------------------------------------*/
/* 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;
while (duration < delay) {
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))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h
index a1929a4ac..8bb351401 100644
--- a/ports/nrf/mphalport.h
+++ b/ports/nrf/mphalport.h
@@ -33,12 +33,11 @@
#include "lib/utils/interrupt_char.h"
#include "nrfx_uarte.h"
#include "py/mpconfig.h"
+#include "supervisor/shared/tick.h"
extern nrfx_uarte_t serial_instance;
-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))
bool mp_hal_stdin_any(void);
diff --git a/ports/nrf/tick.c b/ports/nrf/tick.c
index 6d8fd13e0..ac825a7f1 100644
--- a/ports/nrf/tick.c
+++ b/ports/nrf/tick.c
@@ -26,31 +26,14 @@
#include "tick.h"
-#include "supervisor/shared/autoreload.h"
-#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
#include "shared-module/gamepad/__init__.h"
#include "shared-bindings/microcontroller/Processor.h"
#include "nrf.h"
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
-
void SysTick_Handler(void) {
- // SysTick interrupt handler called when the SysTick timer reaches zero
- // (every millisecond).
- 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
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
void tick_init() {
@@ -61,11 +44,11 @@ void tick_init() {
void tick_delay(uint32_t us) {
uint32_t ticks_per_us = common_hal_mcu_processor_get_frequency() / 1000 / 1000;
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 (ticks_ms == start_ms) {}
+ while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks;
- start_ms = ticks_ms;
+ start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000;
}
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@@ -74,11 +57,11 @@ void tick_delay(uint32_t us) {
// us counts down!
void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
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;
}
void wait_until(uint64_t ms, uint32_t us_until_ms) {
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) {}
}
diff --git a/ports/nrf/tick.h b/ports/nrf/tick.h
index 838e9fbea..d638ad025 100644
--- a/ports/nrf/tick.h
+++ b/ports/nrf/tick.h
@@ -30,8 +30,6 @@
#include <stdint.h>
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c
index f0e0cc9eb..aa792dae1 100644
--- a/ports/stm32f4/common-hal/busio/UART.c
+++ b/ports/stm32f4/common-hal/busio/UART.c
@@ -250,10 +250,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
}
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, same as nrf
- 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;
//restart if it failed in the callback
if (errflag != HAL_OK) {
diff --git a/ports/stm32f4/common-hal/microcontroller/__init__.c b/ports/stm32f4/common-hal/microcontroller/__init__.c
index c7493a4d6..ffab5d1e5 100644
--- a/ports/stm32f4/common-hal/microcontroller/__init__.c
+++ b/ports/stm32f4/common-hal/microcontroller/__init__.c
@@ -48,9 +48,9 @@ STATIC uint32_t get_us(void) {
uint32_t ticks_per_us = HAL_RCC_GetSysClockFreq()/1000000;
uint32_t micros, sys_cycles;
do {
- micros = ticks_ms;
+ micros = supervisor_ticks_ms32();
sys_cycles = SysTick->VAL; //counts backwards
- } while (micros != ticks_ms); //try again if ticks_ms rolled over
+ } while (micros != supervisor_ticks_ms32()); //try again if ticks_ms rolled over
return (micros * 1000) + (ticks_per_us * 1000 - sys_cycles) / ticks_per_us;
}
diff --git a/ports/stm32f4/common-hal/time/__init__.c b/ports/stm32f4/common-hal/time/__init__.c
index e3cb481ef..976f519db 100644
--- a/ports/stm32f4/common-hal/time/__init__.c
+++ b/ports/stm32f4/common-hal/time/__init__.c
@@ -29,7 +29,7 @@
#include "tick.h"
uint64_t common_hal_time_monotonic(void) {
- return ticks_ms;
+ return supervisor_ticks_ms64();
}
void common_hal_time_delay_ms(uint32_t delay) {
diff --git a/ports/stm32f4/mphalport.c b/ports/stm32f4/mphalport.c
index ea864e7ce..f78e9c750 100644
--- a/ports/stm32f4/mphalport.c
+++ b/ports/stm32f4/mphalport.c
@@ -31,11 +31,13 @@
#include "py/mpstate.h"
#include "py/gc.h"
+#include "supervisor/shared/tick.h"
+
/*------------------------------------------------------------------*/
/* 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;
while (duration < delay) {
#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))) {
break;
}
- duration = (ticks_ms - start_tick);
+ duration = (supervisor_ticks_ms64() - start_tick);
// TODO(tannewt): Go to sleep for a little while while we wait.
}
}
diff --git a/ports/stm32f4/mphalport.h b/ports/stm32f4/mphalport.h
index d184138f7..df2f0ca65 100644
--- a/ports/stm32f4/mphalport.h
+++ b/ports/stm32f4/mphalport.h
@@ -32,10 +32,10 @@
#include "lib/utils/interrupt_char.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))
bool mp_hal_stdin_any(void);
diff --git a/ports/stm32f4/tick.c b/ports/stm32f4/tick.c
index 688f71dbd..f4adf183a 100644
--- a/ports/stm32f4/tick.c
+++ b/ports/stm32f4/tick.c
@@ -26,37 +26,23 @@
#include "tick.h"
-#include "supervisor/shared/autoreload.h"
#include "supervisor/filesystem.h"
-#include "shared-module/gamepad/__init__.h"
+#include "supervisor/shared/tick.h"
#include "shared-bindings/microcontroller/Processor.h"
#include "stm32f4xx.h"
-// Global millisecond tick count
-volatile uint64_t ticks_ms = 0;
-
void SysTick_Handler(void) {
// SysTick interrupt handler called when the SysTick timer reaches zero
// (every millisecond).
- 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
+ // Do things common to all ports when the tick occurs
+ supervisor_tick();
}
uint32_t HAL_GetTick(void) //override ST HAL
{
- return (uint32_t)ticks_ms;
+ return (uint32_t)supervisor_ticks_ms32();
}
void tick_init() {
@@ -72,11 +58,11 @@ void tick_init() {
void tick_delay(uint32_t us) {
uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
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 (ticks_ms == start_ms) {}
+ while (supervisor_ticks_ms64() == start_ms) {}
us -= us_between_ticks;
- start_ms = ticks_ms;
+ start_ms = supervisor_ticks_ms64();
us_between_ticks = 1000;
}
while (SysTick->VAL > ((us_between_ticks - us) * ticks_per_us)) {}
@@ -85,11 +71,11 @@ void tick_delay(uint32_t us) {
// us counts down!
void current_tick(uint64_t* ms, uint32_t* us_until_ms) {
uint32_t ticks_per_us = SystemCoreClock / 1000 / 1000;
- *ms = ticks_ms;
+ *ms = supervisor_ticks_ms32();
*us_until_ms = SysTick->VAL / ticks_per_us;
}
void wait_until(uint64_t ms, uint32_t us_until_ms) {
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) {}
}
diff --git a/ports/stm32f4/tick.h b/ports/stm32f4/tick.h
index e4772fa2c..999acc7a3 100644
--- a/ports/stm32f4/tick.h
+++ b/ports/stm32f4/tick.h
@@ -30,8 +30,6 @@
#include <stdint.h>
-extern volatile uint64_t ticks_ms;
-
extern struct timer_descriptor ms_timer;
void tick_init(void);
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index b1e7bc05a..3e83d0c51 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -28,11 +28,12 @@
// sure that the same feature set and settings are used, such as in atmel-samd
// and nrf.
-#include <stdint.h>
-
#ifndef __INCLUDED_MPCONFIG_CIRCUITPY_H
#define __INCLUDED_MPCONFIG_CIRCUITPY_H
+#include <stdint.h>
+#include <stdatomic.h>
+
// This is CircuitPython.
#define CIRCUITPY 1
@@ -652,14 +653,14 @@ extern const struct _mp_obj_module_t ustack_module;
FLASH_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
-void run_background_tasks(void);
-#define RUN_BACKGROUND_TASKS (run_background_tasks())
+void supervisor_run_background_tasks_if_tick(void);
+#define RUN_BACKGROUND_TASKS (supervisor_run_background_tasks_if_tick())
// TODO: Used in wiznet5k driver, but may not be needed in the long run.
#define MICROPY_THREAD_YIELD()
-#define MICROPY_VM_HOOK_LOOP run_background_tasks();
-#define MICROPY_VM_HOOK_RETURN run_background_tasks();
+#define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS;
+#define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS;
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS 1000
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 8e3835d86..0d667959d 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -103,14 +103,10 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
# go through each qstr and print it out
for _, _, qstr in qstrs.values():
all_strings.append(qstr)
- all_strings_concat = "".join(all_strings).encode("utf-8")
+ all_strings_concat = "".join(all_strings)
counts = collections.Counter(all_strings_concat)
- # add other values
- for i in range(256):
- if i not in counts:
- counts[i] = 0
cb = huffman.codebook(counts.items())
- values = bytearray()
+ values = []
length_count = {}
renumbered = 0
last_l = None
@@ -124,26 +120,27 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
if last_l:
renumbered <<= (l - last_l)
canonical[ch] = '{0:0{width}b}'.format(renumbered, width=l)
- if chr(ch) in C_ESCAPES:
- s = C_ESCAPES[chr(ch)]
- else:
- s = chr(ch)
- print("//", ch, s, counts[ch], canonical[ch], renumbered)
+ s = C_ESCAPES.get(ch, ch)
+ print("//", ord(ch), s, counts[ch], canonical[ch], renumbered)
renumbered += 1
last_l = l
lengths = bytearray()
- for i in range(1, max(length_count) + 1):
+ print("// length count", length_count)
+ for i in range(1, max(length_count) + 2):
lengths.append(length_count.get(i, 0))
+ print("// values", values, "lengths", len(lengths), lengths)
+ print("// estimated total memory size", len(lengths) + 2*len(values) + sum(len(cb[u]) for u in all_strings_concat))
print("//", values, lengths)
+ values_type = "uint16_t" if max(ord(u) for u in values) > 255 else "uint8_t"
with open(compression_filename, "w") as f:
f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths))))
- f.write("const uint8_t values[256] = {{ {} }};\n".format(", ".join(map(str, values))))
+ f.write("const {} values[] = {{ {} }};\n".format(values_type, ", ".join(str(ord(u)) for u in values)))
return values, lengths
def decompress(encoding_table, length, encoded):
values, lengths = encoding_table
#print(l, encoded)
- dec = bytearray(length)
+ dec = []
this_byte = 0
this_bit = 7
b = encoded[this_byte]
@@ -173,14 +170,14 @@ def decompress(encoding_table, length, encoded):
searched_length += lengths[bit_length]
v = values[searched_length + bits - max_code]
- dec[i] = v
- return dec
+ dec.append(v)
+ return ''.join(dec)
def compress(encoding_table, decompressed):
- if not isinstance(decompressed, bytes):
+ if not isinstance(decompressed, str):
raise TypeError()
values, lengths = encoding_table
- enc = bytearray(len(decompressed) * 2)
+ enc = bytearray(len(decompressed) * 3)
#print(decompressed)
#print(lengths)
current_bit = 7
@@ -228,7 +225,7 @@ def compress(encoding_table, decompressed):
if current_bit != 7:
current_byte += 1
if current_byte > len(decompressed):
- print("Note: compression increased length", repr(decompressed.decode('utf-8')), len(decompressed), current_byte, file=sys.stderr)
+ print("Note: compression increased length", repr(decompressed), len(decompressed), current_byte, file=sys.stderr)
return enc[:current_byte]
def qstr_escape(qst):
@@ -347,9 +344,9 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns):
total_text_compressed_size = 0
for original, translation in i18ns:
translation_encoded = translation.encode("utf-8")
- compressed = compress(encoding_table, translation_encoded)
+ compressed = compress(encoding_table, translation)
total_text_compressed_size += len(compressed)
- decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8")
+ decompressed = decompress(encoding_table, len(translation_encoded), compressed)
for c in C_ESCAPES:
decompressed = decompressed.replace(c, C_ESCAPES[c])
print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed))
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 862d2cf59..11db0f8ff 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -35,6 +35,7 @@
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.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) {
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;
// Test to see if the real frame time is below our minimum.
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);
// 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;
}
}
@@ -350,20 +351,20 @@ STATIC void _update_backlight(displayio_display_obj_t* self) {
if (!self->auto_brightness || self->updating_backlight) {
return;
}
- if (ticks_ms - self->last_backlight_refresh < 100) {
+ if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) {
return;
}
// TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
// should account for ambient light when possible.
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) {
_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);
}
}
diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c
index 252b39eb7..91d4bb7f9 100644
--- a/shared-module/displayio/EPaperDisplay.c
+++ b/shared-module/displayio/EPaperDisplay.c
@@ -36,6 +36,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include <stdint.h>
@@ -176,7 +177,7 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper
return 0;
}
// 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) {
return 0;
}
@@ -340,7 +341,7 @@ void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy);
refresh_done = busy != self->busy_state;
} 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) {
self->refreshing = false;
diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c
index a73ea81d1..658daa8d6 100644
--- a/shared-module/displayio/display_core.c
+++ b/shared-module/displayio/display_core.c
@@ -35,6 +35,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include <stdint.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) {
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
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);
}
self->full_refresh = false;
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
void release_display_core(displayio_display_core_t* self) {
diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c
index 96648b260..925e9a2a3 100644
--- a/shared-module/network/__init__.c
+++ b/shared-module/network/__init__.c
@@ -31,6 +31,8 @@
#include "py/mphal.h"
#include "py/mperrno.h"
+#include "supervisor/shared/tick.h"
+
#include "shared-bindings/random/__init__.h"
#include "shared-module/network/__init__.h"
@@ -53,7 +55,7 @@ void network_module_deinit(void) {
void network_module_background(void) {
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;
next_tick = this_tick + 1000;
diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c
index bed7d163f..8744f2ed3 100644
--- a/shared-module/usb_hid/Device.c
+++ b/shared-module/usb_hid/Device.c
@@ -30,6 +30,7 @@
#include "shared-bindings/usb_hid/Device.h"
#include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
#include "tusb.h"
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
- uint64_t end_ticks = ticks_ms + 2000;
- while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) {
+ uint64_t end_ticks = supervisor_ticks_ms64() + 2000;
+ while ( (supervisor_ticks_ms64() < end_ticks) && !tud_hid_ready() ) {
RUN_BACKGROUND_TASKS;
}
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
index 940cbf1f2..f751a7ffd 100644
--- a/supervisor/shared/rgb_led_status.c
+++ b/supervisor/shared/rgb_led_status.c
@@ -27,6 +27,7 @@
#include "mphalport.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "rgb_led_status.h"
+#include "supervisor/shared/tick.h"
#ifdef MICROPY_HW_NEOPIXEL
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) {
#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);
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
status->safe_mode = safe_mode;
status->found_main = found_main;
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) {
#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) {
// All is good. Ramp ALL_DONE up and down.
if (tick_diff > ALL_GOOD_CYCLE_MS) {
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0;
}
@@ -424,7 +425,7 @@ void tick_rgb_status_animation(rgb_status_animation_t* status) {
}
} else {
if (tick_diff > status->total_exception_cycle) {
- status->pattern_start = ticks_ms;
+ status->pattern_start = supervisor_ticks_ms32();
tick_diff = 0;
}
// First flash the file color.
diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c
index d8d3ab379..363181da0 100644
--- a/supervisor/shared/safe_mode.c
+++ b/supervisor/shared/safe_mode.c
@@ -34,6 +34,7 @@
#include "supervisor/shared/rgb_led_colors.h"
#include "supervisor/shared/rgb_led_status.h"
#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
#define SAFE_MODE_DATA_GUARD 0xad0000af
#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_switch_to_output(&status_led, true, DRIVE_MODE_PUSH_PULL);
#endif
- uint64_t start_ticks = ticks_ms;
+ uint64_t start_ticks = supervisor_ticks_ms64();
uint64_t diff = 0;
while (diff < 700) {
#ifdef MICROPY_HW_LED_STATUS
// 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);
#endif
- diff = ticks_ms - start_ticks;
+ diff = supervisor_ticks_ms64() - start_ticks;
}
#ifdef MICROPY_HW_LED_STATUS
common_hal_digitalio_digitalinout_deinit(&status_led);
diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c
new file mode 100644
index 000000000..69256081c
--- /dev/null
+++ b/supervisor/shared/tick.c
@@ -0,0 +1,94 @@
+/*
+ * 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;
+static volatile uint32_t background_ticks_ms32;
+
+#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;
+}
+
+extern void run_background_tasks(void);
+
+void supervisor_run_background_tasks_if_tick() {
+ uint32_t now32 = ticks_ms;
+
+ if (now32 == background_ticks_ms32) {
+ return;
+ }
+ background_ticks_ms32 = now32;
+
+ run_background_tasks();
+}
+
+void supervisor_fake_tick() {
+ uint32_t now32 = ticks_ms;
+ background_ticks_ms32 = (now32 - 1);
+}
diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h
new file mode 100644
index 000000000..7ce8281ba
--- /dev/null
+++ b/supervisor/shared/tick.h
@@ -0,0 +1,67 @@
+/*
+ * 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>
+
+/** @brief To be called once every ms
+ *
+ * The port must call supervisor_tick once per millisecond to perform regular tasks.
+ * This is called from the SysTick interrupt or similar, and is safe to call in an
+ * interrupt context.
+ */
+extern void supervisor_tick(void);
+/** @brief Cause background tasks to be called soon
+ *
+ * Normally, background tasks are only run once per tick. For other cases where
+ * an event noticed from an interrupt context needs to be completed by a background
+ * task activity, the interrupt can call supervisor_fake_tick.
+ */
+extern void supervisor_fake_tick(void);
+/** @brief Get the lower 32 bits of the time in milliseconds
+ *
+ * This can be more efficient than supervisor_ticks_ms64, for sites where a wraparound
+ * of ~49.5 days is not harmful.
+ */
+extern uint32_t supervisor_ticks_ms32(void);
+/** @brief Get the full time in milliseconds
+ *
+ * Because common ARM mcus cannot atomically work with 64-bit quantities, this
+ * function must briefly disable interrupts in order to return the value. If
+ * only relative durations of less than about ~49.5 days need to be considered,
+ * then it may be possible to use supervisor_ticks_ms64 instead.
+ */
+extern uint64_t supervisor_ticks_ms64(void);
+/** @brief Run background ticks, but only about every millisecond.
+ *
+ * Normally, this is not called directly. Instead use the RUN_BACKGROUND_TASKS
+ * macro.
+ */
+extern void supervisor_run_background_if_tick(void);
+
+#endif
diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c
index aa5e4517c..187d5ff8a 100644
--- a/supervisor/shared/translate.c
+++ b/supervisor/shared/translate.c
@@ -42,12 +42,28 @@ void serial_write_compressed(const compressed_string_t* compressed) {
serial_write(decompressed);
}
+STATIC int put_utf8(char *buf, int u) {
+ if(u <= 0x7f) {
+ *buf = u;
+ return 1;
+ } else if(u <= 0x07ff) {
+ *buf++ = 0b11000000 | (u >> 6);
+ *buf = 0b10000000 | (u & 0b00111111);
+ return 2;
+ } else { // u <= 0xffff)
+ *buf++ = 0b11000000 | (u >> 12);
+ *buf = 0b10000000 | ((u >> 6) & 0b00111111);
+ *buf = 0b10000000 | (u & 0b00111111);
+ return 3;
+ }
+}
+
char* decompress(const compressed_string_t* compressed, char* decompressed) {
uint8_t this_byte = 0;
uint8_t this_bit = 7;
uint8_t b = compressed->data[this_byte];
// Stop one early because the last byte is always NULL.
- for (uint16_t i = 0; i < compressed->length - 1; i++) {
+ for (uint16_t i = 0; i < compressed->length - 1;) {
uint32_t bits = 0;
uint8_t bit_length = 0;
uint32_t max_code = lengths[0];
@@ -72,7 +88,7 @@ char* decompress(const compressed_string_t* compressed, char* decompressed) {
max_code = (max_code << 1) + lengths[bit_length];
searched_length += lengths[bit_length];
}
- decompressed[i] = values[searched_length + bits - max_code];
+ i += put_utf8(decompressed + i, values[searched_length + bits - max_code]);
}
decompressed[compressed->length-1] = '\0';
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index b2e4eb1dc..5e997ee78 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -10,6 +10,7 @@ SRC_SUPERVISOR = \
supervisor/shared/safe_mode.c \
supervisor/shared/stack.c \
supervisor/shared/status_leds.c \
+ supervisor/shared/tick.c \
supervisor/shared/translate.c
ifndef $(NO_USB)