summaryrefslogtreecommitdiff
path: root/supervisor
diff options
context:
space:
mode:
authorKalbeAbbas <kalbeabbas142@gmail.com>2019-12-16 13:25:44 +0500
committerGitHub <noreply@github.com>2019-12-16 13:25:44 +0500
commit89ed64157dfdff0f673f38f098f7c5380fac0347 (patch)
tree666df6d170c13f08e892b79b46bb52d88ce3c1a6 /supervisor
parent87dc9bee8b33c40aa2e342ee42ced71ed757b142 (diff)
parent8384e4676b5f7e4c06fd8f1db53382b6f3e6d175 (diff)
Merge branch 'master' into master
Diffstat (limited to 'supervisor')
-rw-r--r--supervisor/shared/bluetooth.c12
-rw-r--r--supervisor/shared/external_flash/external_flash.c8
-rw-r--r--supervisor/shared/filesystem.c15
-rw-r--r--supervisor/shared/rgb_led_status.c19
-rw-r--r--supervisor/shared/safe_mode.c89
-rw-r--r--supervisor/shared/safe_mode.h3
-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.mk79
10 files changed, 323 insertions, 83 deletions
diff --git a/supervisor/shared/bluetooth.c b/supervisor/shared/bluetooth.c
index 02258de74..18caa2eb4 100644
--- a/supervisor/shared/bluetooth.c
+++ b/supervisor/shared/bluetooth.c
@@ -51,8 +51,12 @@ bleio_characteristic_obj_t supervisor_ble_length_characteristic;
bleio_uuid_obj_t supervisor_ble_length_uuid;
bleio_characteristic_obj_t supervisor_ble_contents_characteristic;
bleio_uuid_obj_t supervisor_ble_contents_uuid;
+
+// This is the base UUID for CircuitPython services and characteristics.
const uint8_t circuitpython_base_uuid[16] = {0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x00, 0xaf, 0xad };
-uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
+// This standard advertisement advertises the CircuitPython editing service and a CIRCUITPY short name.
+uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
+// This scan response advertises the full CIRCUITPYXXXX device name.
uint8_t circuitpython_scan_response_data[15] = {0x0e, 0x09, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00};
mp_obj_list_t service_list;
mp_obj_t service_list_items[1];
@@ -86,7 +90,7 @@ void supervisor_start_bluetooth(void) {
characteristic_list.len = 0;
characteristic_list.items = characteristic_list_items;
mp_seq_clear(characteristic_list.items, 0, characteristic_list.alloc, sizeof(*characteristic_list.items));
-
+
_common_hal_bleio_service_construct(&supervisor_ble_service, &supervisor_ble_service_uuid, false /* is secondary */, &characteristic_list);
// File length
@@ -225,7 +229,7 @@ void supervisor_bluetooth_background(void) {
uint16_t current_length = ((uint16_t*) current_command)[0];
if (current_length > 0 && current_length == current_offset) {
uint16_t command = ((uint16_t *) current_command)[1];
-
+
if (command == 1) {
uint16_t max_len = 20; //supervisor_ble_contents_characteristic.max_length;
uint8_t buf[max_len];
@@ -274,7 +278,7 @@ void supervisor_bluetooth_background(void) {
f_write(&active_file, &data, 1, &actual);
}
}
-
+
f_lseek(&active_file, offset);
uint8_t* data = (uint8_t *) (current_command + 4);
UINT written;
diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c
index 99df553e1..9d38c07d8 100644
--- a/supervisor/shared/external_flash/external_flash.c
+++ b/supervisor/shared/external_flash/external_flash.c
@@ -324,6 +324,10 @@ static bool allocate_ram_cache(void) {
return true;
}
+ if (MP_STATE_MEM(gc_pool_start) == 0) {
+ return false;
+ }
+
MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t), false);
if (MP_STATE_VM(flash_ram_cache) == NULL) {
return false;
@@ -367,7 +371,7 @@ static void release_ram_cache(void) {
if (supervisor_cache != NULL) {
free_memory(supervisor_cache);
supervisor_cache = NULL;
- } else {
+ } else if (MP_STATE_MEM(gc_pool_start)) {
m_free(MP_STATE_VM(flash_ram_cache));
}
MP_STATE_VM(flash_ram_cache) = NULL;
@@ -415,7 +419,7 @@ static bool flush_ram_cache(bool keep_cache) {
write_flash(current_sector + (i * pages_per_block + j) * SPI_FLASH_PAGE_SIZE,
MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j],
SPI_FLASH_PAGE_SIZE);
- if (!keep_cache && supervisor_cache == NULL) {
+ if (!keep_cache && supervisor_cache == NULL && MP_STATE_MEM(gc_pool_start)) {
m_free(MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j]);
}
}
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index c50d7f4ee..92727f6fb 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -69,6 +69,19 @@ static void make_empty_file(FATFS *fatfs, const char *path) {
f_close(&fp);
}
+
+static void make_sample_code_file(FATFS *fatfs) {
+ #if CIRCUITPY_FULL_BUILD
+ FIL fs;
+ UINT char_written = 0;
+ const byte buffer[] = "print('Hello World!')\n";
+ //Create or modify existing code.py file
+ f_open(fatfs, &fs, "/code.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
+ f_close(&fs);
+ #endif
+}
+
// we don't make this function static because it needs a lot of stack and we
// want it to be executed without using stack within main() function
void filesystem_init(bool create_allowed, bool force_create) {
@@ -98,6 +111,8 @@ void filesystem_init(bool create_allowed, bool force_create) {
make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index");
make_empty_file(&vfs_fat->fatfs, "/.Trashes");
make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log");
+ // make a sample code.py file
+ make_sample_code_file(&vfs_fat->fatfs);
// create empty lib directory
f_mkdir(&vfs_fat->fatfs, "/lib");
diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c
index 05df4c628..f751a7ffd 100644
--- a/supervisor/shared/rgb_led_status.c
+++ b/supervisor/shared/rgb_led_status.c
@@ -25,8 +25,9 @@
*/
#include "mphalport.h"
-#include "common-hal/microcontroller/Pin.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;
@@ -117,7 +118,7 @@ void rgb_led_status_init() {
mp_const_none);
#else
if (!common_hal_busio_spi_deinited(&status_apa102)) {
- // This may call us recursively if reset_pin_number() is called,
+ // This may call us recursively if common_hal_reset_pin() is called,
// The rgb_led_status_init_in_progress guard will prevent further recursion.
common_hal_busio_spi_deinit(&status_apa102);
}
@@ -181,11 +182,11 @@ void rgb_led_status_init() {
void reset_status_led() {
#ifdef MICROPY_HW_NEOPIXEL
- reset_pin_number(MICROPY_HW_NEOPIXEL->number);
+ common_hal_reset_pin(MICROPY_HW_NEOPIXEL);
#endif
#if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)
- reset_pin_number(MICROPY_HW_APA102_MOSI->number);
- reset_pin_number(MICROPY_HW_APA102_SCK->number);
+ common_hal_reset_pin(MICROPY_HW_APA102_MOSI);
+ common_hal_reset_pin(MICROPY_HW_APA102_SCK);
#endif
#if defined(CP_RGB_STATUS_LED)
// TODO: Support sharing status LED with user.
@@ -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..aba31e9c9 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);
@@ -93,44 +94,72 @@ void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) {
reset_cpu();
}
+
+
+#define FILE_AN_ISSUE translate("\nPlease file an issue with the contents of your CIRCUITPY drive at \nhttps://github.com/adafruit/circuitpython/issues\n")
+
void print_safe_mode_message(safe_mode_t reason) {
if (reason == NO_SAFE_MODE) {
return;
}
- serial_write("\r\n");
- // Output a user safe mode string if its set.
+ serial_write("\n");
+ // Output a user safe mode string if it's set.
#ifdef BOARD_USER_SAFE_MODE
if (reason == USER_SAFE_MODE) {
serial_write_compressed(translate("You requested starting safe mode by "));
serial_write(BOARD_USER_SAFE_MODE_ACTION);
- serial_write("\r\n");
- serial_write_compressed(translate("To exit, please reset the board without "));
+ serial_write_compressed(translate("\nTo exit, please reset the board without "));
serial_write(BOARD_USER_SAFE_MODE_ACTION);
- serial_write("\r\n");
+ serial_write("\n");
} else
#endif
- if (reason == MANUAL_SAFE_MODE) {
- serial_write_compressed(translate("The reset button was pressed while booting CircuitPython. Press again to exit safe mode.\n"));
- } else if (reason == PROGRAMMATIC_SAFE_MODE) {
- serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n"));
- } else {
- serial_write_compressed(translate("You are running in safe mode which means something unanticipated happened.\n"));
- if (reason == HARD_CRASH || reason == MICROPY_NLR_JUMP_FAIL || reason == MICROPY_FATAL_ERROR || reason == GC_ALLOC_OUTSIDE_VM) {
- serial_write_compressed(translate("Looks like our core CircuitPython code crashed hard. Whoops!\nPlease file an issue at https://github.com/adafruit/circuitpython/issues\n with the contents of your CIRCUITPY drive and this message:\n"));
- if (reason == HARD_CRASH) {
- serial_write_compressed(translate("Crash into the HardFault_Handler.\n"));
- } else if (reason == MICROPY_NLR_JUMP_FAIL) {
- serial_write_compressed(translate("MicroPython NLR jump failed. Likely memory corruption.\n"));
- } else if (reason == MICROPY_FATAL_ERROR) {
- serial_write_compressed(translate("MicroPython fatal error.\n"));
- } else if (reason == GC_ALLOC_OUTSIDE_VM) {
- serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.\n"));
- }
- } else if (reason == BROWNOUT) {
- serial_write_compressed(translate("The microcontroller's power dipped. Please make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n"));
- } else if (reason == HEAP_OVERWRITTEN) {
- serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase stack size limits and press reset (after ejecting CIRCUITPY).\nIf you didn't change the stack, then file an issue here with the contents of your CIRCUITPY drive:\n"));
- serial_write("https://github.com/adafruit/circuitpython/issues\r\n");
+ switch (reason) {
+ case MANUAL_SAFE_MODE:
+ serial_write_compressed(translate("CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.\n"));
+ return;
+ case PROGRAMMATIC_SAFE_MODE:
+ serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n"));
+ return;
+ default:
+ break;
}
- }
+
+ serial_write_compressed(translate("You are in safe mode: something unanticipated happened.\n"));
+ switch (reason) {
+ case BROWNOUT:
+ serial_write_compressed(translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n"));
+ return;
+ case HEAP_OVERWRITTEN:
+ serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase the stack size if you know how, or if not:"));
+ serial_write_compressed(FILE_AN_ISSUE);
+ return;
+ default:
+ break;
+ }
+
+ serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n"));
+ switch (reason) {
+ case HARD_CRASH:
+ serial_write_compressed(translate("Crash into the HardFault_Handler."));
+ return;
+ case MICROPY_NLR_JUMP_FAIL:
+ serial_write_compressed(translate("MicroPython NLR jump failed. Likely memory corruption."));
+ return;
+ case MICROPY_FATAL_ERROR:
+ serial_write_compressed(translate("MicroPython fatal error."));
+ break;
+ case GC_ALLOC_OUTSIDE_VM:
+ serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running."));
+ break;
+ case NORDIC_SOFT_DEVICE_ASSERT:
+ serial_write_compressed(translate("Nordic Soft Device failure assertion."));
+ break;
+ case FLASH_WRITE_FAIL:
+ serial_write_compressed(translate("Failed to write internal flash."));
+ break;
+ default:
+ serial_write_compressed(translate("Unknown reason."));
+ break;
+ }
+ serial_write_compressed(FILE_AN_ISSUE);
}
diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h
index 8c5dcd9c5..e05fca0e4 100644
--- a/supervisor/shared/safe_mode.h
+++ b/supervisor/shared/safe_mode.h
@@ -38,7 +38,8 @@ typedef enum {
MICROPY_FATAL_ERROR,
GC_ALLOC_OUTSIDE_VM,
PROGRAMMATIC_SAFE_MODE,
- NORDIC_SOFT_DEVICE_ASSERT
+ NORDIC_SOFT_DEVICE_ASSERT,
+ FLASH_WRITE_FAIL,
} safe_mode_t;
safe_mode_t wait_for_safe_mode_reset(void);
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 ad0f716fb..96a14c25b 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -10,31 +10,34 @@ 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)
NO_USB = $(wildcard supervisor/usb.c)
endif
-ifneq ($(INTERNAL_FLASH_FILESYSTEM),)
- CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
+ifndef INTERNAL_FLASH_FILESYSTEM
+INTERNAL_FLASH_FILESYSTEM = 0
endif
-ifneq ($(QSPI_FLASH_FILESYSTEM),)
-# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated.
- CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
-endif
-ifneq ($(SPI_FLASH_FILESYSTEM),)
-# EXPRESS_BOARD is obsolete and should be removed when samd-peripherals is updated.
- CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
+CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
+
+ifndef QSPI_FLASH_FILESYSTEM
+QSPI_FLASH_FILESYSTEM = 0
endif
+CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM)
+ifndef SPI_FLASH_FILESYSTEM
+SPI_FLASH_FILESYSTEM = 0
+endif
+CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM)
ifeq ($(CIRCUITPY_BLEIO),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth.c
endif
# Choose which flash filesystem impl to use.
-# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive.
+# (Right now INTERNAL_FLASH_FILESYSTEM and (Q)SPI_FLASH_FILESYSTEM are mutually exclusive.
# But that might not be true in the future.)
ifdef EXTERNAL_FLASH_DEVICES
CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \
@@ -51,7 +54,7 @@ ifdef EXTERNAL_FLASH_DEVICES
else
ifeq ($(DISABLE_FILESYSTEM),1)
SRC_SUPERVISOR += supervisor/stub/internal_flash.c
- else
+ else
SRC_SUPERVISOR += supervisor/internal_flash.c
endif
endif
@@ -63,34 +66,39 @@ ifeq ($(USB),FALSE)
SRC_SUPERVISOR += supervisor/serial.c
endif
else
- SRC_SUPERVISOR += lib/tinyusb/src/common/tusb_fifo.c \
- lib/tinyusb/src/device/usbd.c \
- lib/tinyusb/src/device/usbd_control.c \
- lib/tinyusb/src/class/msc/msc_device.c \
- lib/tinyusb/src/class/cdc/cdc_device.c \
- lib/tinyusb/src/class/hid/hid_device.c \
- lib/tinyusb/src/class/midi/midi_device.c \
- lib/tinyusb/src/tusb.c \
- supervisor/shared/serial.c \
- supervisor/usb.c \
- supervisor/shared/usb/usb_desc.c \
- supervisor/shared/usb/usb.c \
- supervisor/shared/usb/usb_msc_flash.c \
- shared-bindings/usb_hid/__init__.c \
- shared-bindings/usb_hid/Device.c \
- shared-bindings/usb_midi/__init__.c \
- shared-bindings/usb_midi/PortIn.c \
- shared-bindings/usb_midi/PortOut.c \
- shared-module/usb_hid/__init__.c \
- shared-module/usb_hid/Device.c \
- shared-module/usb_midi/__init__.c \
- shared-module/usb_midi/PortIn.c \
- shared-module/usb_midi/PortOut.c \
- $(BUILD)/autogen_usb_descriptor.c
+ SRC_SUPERVISOR += \
+ lib/tinyusb/src/common/tusb_fifo.c \
+ lib/tinyusb/src/device/usbd.c \
+ lib/tinyusb/src/device/usbd_control.c \
+ lib/tinyusb/src/class/msc/msc_device.c \
+ lib/tinyusb/src/class/cdc/cdc_device.c \
+ lib/tinyusb/src/class/hid/hid_device.c \
+ lib/tinyusb/src/class/midi/midi_device.c \
+ lib/tinyusb/src/tusb.c \
+ supervisor/shared/serial.c \
+ supervisor/usb.c \
+ supervisor/shared/usb/usb_desc.c \
+ supervisor/shared/usb/usb.c \
+ supervisor/shared/usb/usb_msc_flash.c \
+ shared-bindings/usb_hid/__init__.c \
+ shared-bindings/usb_hid/Device.c \
+ shared-bindings/usb_midi/__init__.c \
+ shared-bindings/usb_midi/PortIn.c \
+ shared-bindings/usb_midi/PortOut.c \
+ shared-module/usb_hid/__init__.c \
+ shared-module/usb_hid/Device.c \
+ shared-module/usb_midi/__init__.c \
+ shared-module/usb_midi/PortIn.c \
+ shared-module/usb_midi/PortOut.c \
+ $(BUILD)/autogen_usb_descriptor.c
CFLAGS += -DUSB_AVAILABLE
endif
+ifndef USB_INTERFACE_NAME
+USB_INTERFACE_NAME = "CircuitPython"
+endif
+
ifndef USB_DEVICES
USB_DEVICES = "CDC,MSC,AUDIO,HID"
endif
@@ -145,6 +153,7 @@ USB_DESCRIPTOR_ARGS = \
--vid $(USB_VID)\
--pid $(USB_PID)\
--serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
+ --interface_name $(USB_INTERFACE_NAME)\
--devices $(USB_DEVICES)\
--hid_devices $(USB_HID_DEVICES)\
--msc_max_packet_size $(USB_MSC_MAX_PACKET_SIZE)\