Make autoreload checking more robust

- Add reset for autoreload. De-request ticks.
- Separate state a little more in autoreload.c
- Rename some routines.
- Remove redundant settings of CIRCUITPY_AUTORELOAD_DELAY_MS.
This commit is contained in:
Dan Halbert 2022-03-04 13:34:20 -05:00
parent aeeb58fd45
commit 9b2e22a6df
21 changed files with 101 additions and 102 deletions

23
main.c
View File

@ -124,7 +124,7 @@ static void reset_devices(void) {
} }
STATIC void start_mp(supervisor_allocation *heap, bool first_run) { STATIC void start_mp(supervisor_allocation *heap, bool first_run) {
autoreload_stop(); autoreload_reset();
supervisor_workflow_reset(); supervisor_workflow_reset();
// Stack limit should be less than real stack size, so we have a chance // Stack limit should be less than real stack size, so we have a chance
@ -329,7 +329,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
result.exception = MP_OBJ_NULL; result.exception = MP_OBJ_NULL;
result.exception_line = 0; result.exception_line = 0;
bool skip_repl; bool skip_repl = false;
bool skip_wait = false; bool skip_wait = false;
bool found_main = false; bool found_main = false;
uint8_t next_code_options = 0; uint8_t next_code_options = 0;
@ -389,13 +389,13 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// Print done before resetting everything so that we get the message over // Print done before resetting everything so that we get the message over
// BLE before it is reset and we have a delay before reconnect. // BLE before it is reset and we have a delay before reconnect.
if (reload_requested && result.return_code == PYEXEC_EXCEPTION) { if (result.return_code == PYEXEC_RELOAD) {
serial_write_compressed(translate("\nCode stopped by auto-reload.\n")); serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
} else { } else {
serial_write_compressed(translate("\nCode done running.\n")); serial_write_compressed(translate("\nCode done running.\n"));
} }
// Finished executing python code. Cleanup includes a board reset. // Finished executing python code. Cleanup includes filesystem flush and a board reset.
cleanup_after_vm(heap, result.exception); cleanup_after_vm(heap, result.exception);
// If a new next code file was set, that is a reason to keep it (obviously). Stuff this into // If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
@ -407,8 +407,10 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET;
} }
if (reload_requested) { if (result.return_code & PYEXEC_RELOAD) {
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
skip_repl = true;
skip_wait = true;
} else if (result.return_code == 0) { } else if (result.return_code == 0) {
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS; next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS;
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) { if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) {
@ -426,7 +428,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
} }
} }
if (result.return_code & PYEXEC_FORCED_EXIT) { if (result.return_code & PYEXEC_FORCED_EXIT) {
skip_repl = reload_requested; skip_repl = false;
skip_wait = true; skip_wait = true;
} }
} }
@ -473,7 +475,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
// If a reload was requested by the supervisor or autoreload, return // If a reload was requested by the supervisor or autoreload, return
if (reload_requested) { if (result.return_code & PYEXEC_RELOAD) {
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
// Should the STICKY_ON_SUCCESS and STICKY_ON_ERROR bits be cleared in // Should the STICKY_ON_SUCCESS and STICKY_ON_ERROR bits be cleared in
// next_code_stickiness_situation? I can see arguments either way, but I'm deciding // next_code_stickiness_situation? I can see arguments either way, but I'm deciding
@ -627,13 +629,14 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
} }
} }
// Done waiting, start the board back up.
// free code allocation if unused // free code allocation if unused
if ((next_code_options & next_code_stickiness_situation) == 0) { if ((next_code_options & next_code_stickiness_situation) == 0) {
free_memory(next_code_allocation); free_memory(next_code_allocation);
next_code_allocation = NULL; next_code_allocation = NULL;
} }
// Done waiting, start the board back up.
#if CIRCUITPY_STATUS_LED #if CIRCUITPY_STATUS_LED
if (led_active) { if (led_active) {
new_status_color(BLACK); new_status_color(BLACK);
@ -757,7 +760,7 @@ STATIC int run_repl(bool first_run) {
usb_setup_with_vm(); usb_setup_with_vm();
#endif #endif
autoreload_suspend(AUTORELOAD_LOCK_REPL); autoreload_suspend(AUTORELOAD_SUSPEND_REPL);
// Set the status LED to the REPL color before running the REPL. For // Set the status LED to the REPL color before running the REPL. For
// NeoPixels and DotStars this will be sticky but for PWM or single LED it // NeoPixels and DotStars this will be sticky but for PWM or single LED it
@ -787,7 +790,7 @@ STATIC int run_repl(bool first_run) {
status_led_deinit(); status_led_deinit();
#endif #endif
autoreload_resume(AUTORELOAD_LOCK_REPL); autoreload_resume(AUTORELOAD_SUSPEND_REPL);
return exit_code; return exit_code;
} }

View File

@ -129,8 +129,9 @@
#include "common-hal/_pew/PewPew.h" #include "common-hal/_pew/PewPew.h"
#endif #endif
static volatile bool sleep_ok = true; static volatile bool sleep_ok = true;
#ifdef SAMD21 #ifdef SAMD21
static uint8_t _tick_event_channel = 0; uint8_t _tick_event_channel;
// Sleeping requires a register write that can stall interrupt handling. Turning // Sleeping requires a register write that can stall interrupt handling. Turning
// off sleeps allows for more accurate interrupt timing. (Python still thinks // off sleeps allows for more accurate interrupt timing. (Python still thinks
@ -142,7 +143,13 @@ void rtc_start_pulse(void) {
void rtc_end_pulse(void) { void rtc_end_pulse(void) {
sleep_ok = true; sleep_ok = true;
} }
#endif #endif // SAMD21
static void reset_ticks(void) {
#ifdef SAMD21
_tick_event_channel = EVSYS_SYNCH_NUM;
#endif
}
extern volatile bool mp_msc_enabled; extern volatile bool mp_msc_enabled;
@ -426,9 +433,7 @@ void reset_port(void) {
#endif #endif
reset_event_system(); reset_event_system();
#ifdef SAMD21 reset_ticks();
_tick_event_channel = EVSYS_SYNCH_NUM;
#endif
reset_all_pins(); reset_all_pins();
@ -498,7 +503,7 @@ uint32_t port_get_saved_word(void) {
static volatile uint64_t overflowed_ticks = 0; static volatile uint64_t overflowed_ticks = 0;
static uint32_t _get_count(uint64_t *overflow_count) { static uint32_t _get_count(uint64_t *overflow_count) {
while(1) { while (1) {
// Disable interrupts so we can grab the count and the overflow atomically. // Disable interrupts so we can grab the count and the overflow atomically.
common_hal_mcu_disable_interrupts(); common_hal_mcu_disable_interrupts();
@ -521,7 +526,7 @@ static uint32_t _get_count(uint64_t *overflow_count) {
return count; return count;
} }
// Try again if overflow hasn't been processed yet. // Try again if overflow hasn't been processed yet.
} }
} }
@ -620,7 +625,7 @@ void port_enable_tick(void) {
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2; RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2;
#endif #endif
#ifdef SAMD21 #ifdef SAMD21
// SAMD21 ticks won't survive port_reset(). This *should* be ok since it'll // SAMD21 ticks won't survive reset_port(). This *should* be ok since it'll
// be triggered by ticks and no Python will be running. // be triggered by ticks and no Python will be running.
if (_tick_event_channel >= EVSYS_SYNCH_NUM) { if (_tick_event_channel >= EVSYS_SYNCH_NUM) {
turn_on_event_system(); turn_on_event_system();
@ -653,6 +658,7 @@ void port_disable_tick(void) {
uint8_t value = 1 << _tick_event_channel; uint8_t value = 1 << _tick_event_channel;
EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVD(value); EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVD(value);
} }
_tick_event_channel = EVSYS_SYNCH_NUM;
#endif #endif
} }

View File

@ -54,8 +54,6 @@
#define BOARD_USER_SAFE_MODE_ACTION translate("pressing the left button at start up\n") #define BOARD_USER_SAFE_MODE_ACTION translate("pressing the left button at start up\n")
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) #define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -3,8 +3,6 @@
#define MICROPY_HW_BOARD_NAME "Arduino Nano 33 BLE" #define MICROPY_HW_BOARD_NAME "Arduino Nano 33 BLE"
#define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_HW_MCU_NAME "nRF52840"
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define DEFAULT_I2C_BUS_SCL (&pin_P0_02) #define DEFAULT_I2C_BUS_SCL (&pin_P0_02)
#define DEFAULT_I2C_BUS_SDA (&pin_P0_31) #define DEFAULT_I2C_BUS_SDA (&pin_P0_31)

View File

@ -3,8 +3,6 @@
#define MICROPY_HW_BOARD_NAME "BastBLE" #define MICROPY_HW_BOARD_NAME "BastBLE"
#define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_HW_MCU_NAME "nRF52840"
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#if QSPI_FLASH_FILESYSTEM #if QSPI_FLASH_FILESYSTEM
#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 30) #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 30)
#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 29) #define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 29)

View File

@ -53,8 +53,6 @@
#define SPI_FLASH_CS_PIN &pin_P0_20 #define SPI_FLASH_CS_PIN &pin_P0_20
#endif #endif
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) #define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -5,8 +5,6 @@
#define MICROPY_HW_LED_STATUS (&pin_P0_27) #define MICROPY_HW_LED_STATUS (&pin_P0_27)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) #define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -24,8 +24,6 @@
#define SPI_FLASH_CS_PIN &pin_P0_23 #define SPI_FLASH_CS_PIN &pin_P0_23
#endif #endif
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) #define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -5,8 +5,6 @@
#define MICROPY_HW_LED_STATUS (&pin_P0_12) #define MICROPY_HW_LED_STATUS (&pin_P0_12)
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_INTERNAL_NVM_SIZE (4096) #define CIRCUITPY_INTERNAL_NVM_SIZE (4096)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

View File

@ -42,8 +42,6 @@
#define SPI_FLASH_SCK_PIN (&pin_PB13) #define SPI_FLASH_SCK_PIN (&pin_PB13)
#define SPI_FLASH_CS_PIN (&pin_PB12) #define SPI_FLASH_CS_PIN (&pin_PB12)
#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
#define AUTORESET_DELAY_MS (500) #define AUTORESET_DELAY_MS (500)

View File

@ -45,8 +45,6 @@
#define DEFAULT_I2C_BUS_SCL (&pin_PB06) #define DEFAULT_I2C_BUS_SCL (&pin_PB06)
#define DEFAULT_I2C_BUS_SDA (&pin_PB07) #define DEFAULT_I2C_BUS_SDA (&pin_PB07)
#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
#define AUTORESET_DELAY_MS (500) #define AUTORESET_DELAY_MS (500)

View File

@ -1,4 +1,4 @@
/* `/*
* This file is part of the MicroPython project, http://micropython.org/ * This file is part of the MicroPython project, http://micropython.org/
* *
* The MIT License (MIT) * The MIT License (MIT)
@ -49,6 +49,4 @@
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000) #define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
#define AUTORESET_DELAY_MS (500)
#define MICROPY_FATFS_EXFAT 0 #define MICROPY_FATFS_EXFAT 0

View File

@ -95,7 +95,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_s
//| ... //| ...
//| //|
STATIC mp_obj_t supervisor_reload(void) { STATIC mp_obj_t supervisor_reload(void) {
reload_requested = true;
supervisor_set_run_reason(RUN_REASON_SUPERVISOR_RELOAD); supervisor_set_run_reason(RUN_REASON_SUPERVISOR_RELOAD);
mp_raise_reload_exception(); mp_raise_reload_exception();
return mp_const_none; return mp_const_none;

View File

@ -174,12 +174,13 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
} else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type((mp_obj_t)nlr.ret_val)), &mp_type_DeepSleepRequest)) { } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type((mp_obj_t)nlr.ret_val)), &mp_type_DeepSleepRequest)) {
ret = PYEXEC_DEEP_SLEEP; ret = PYEXEC_DEEP_SLEEP;
#endif #endif
} else if ((mp_obj_t)nlr.ret_val == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
ret = PYEXEC_RELOAD;
} else { } else {
if ((mp_obj_t)nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
}
ret = PYEXEC_EXCEPTION; ret = PYEXEC_EXCEPTION;
} }
} }
if (result != NULL) { if (result != NULL) {
result->return_code = ret; result->return_code = ret;

View File

@ -49,6 +49,7 @@ extern int pyexec_system_exit;
#define PYEXEC_FORCED_EXIT (0x100) #define PYEXEC_FORCED_EXIT (0x100)
#define PYEXEC_EXCEPTION (0x200) #define PYEXEC_EXCEPTION (0x200)
#define PYEXEC_DEEP_SLEEP (0x400) #define PYEXEC_DEEP_SLEEP (0x400)
#define PYEXEC_RELOAD (0x800)
int pyexec_raw_repl(void); int pyexec_raw_repl(void);
int pyexec_friendly_repl(void); int pyexec_friendly_repl(void);

View File

@ -33,67 +33,76 @@
supervisor_allocation *next_code_allocation; supervisor_allocation *next_code_allocation;
#include "shared-bindings/supervisor/Runtime.h" #include "shared-bindings/supervisor/Runtime.h"
static volatile uint32_t autoreload_delay_ms = 0; static volatile uint32_t autoreload_countdown_ms = 0;
static bool autoreload_enabled = false;
static size_t autoreload_suspended = 0;
// True if user has disabled autoreload.
static bool autoreload_enabled = false;
// Non-zero if autoreload is temporarily off, due to an AUTORELOAD_SUSPEND_... reason.
static uint32_t autoreload_suspended = 0;
// True if autoreload has been triggered. Wait for CIRCUITPY_AUTORELOAD_DELAY_MS before doing the
// autoreload, in case further writes arrive.
static bool autoreload_countdown = false;
// True if something has requested a reload/restart.
volatile bool reload_requested = false; volatile bool reload_requested = false;
void autoreload_reset() {
if (autoreload_countdown) {
supervisor_disable_tick();
autoreload_countdown = false;
}
autoreload_countdown_ms = 0;
reload_requested = false;
}
inline void autoreload_tick() { inline void autoreload_tick() {
if (autoreload_delay_ms == 0) { if (!autoreload_countdown) {
return; return;
} }
if (autoreload_delay_ms == 1 && autoreload_enabled && if (autoreload_countdown_ms > 0) {
autoreload_suspended == 0 && !reload_requested) { autoreload_countdown_ms--;
mp_raise_reload_exception(); }
reload_requested = true; if (autoreload_countdown_ms == 0 && autoreload_enabled &&
supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD); autoreload_suspended == 0 && !reload_requested) {
supervisor_disable_tick(); reload_requested = true;
autoreload_countdown = false;
supervisor_disable_tick();
supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD);
mp_raise_reload_exception();
} }
autoreload_delay_ms--;
} }
void autoreload_enable() { void autoreload_enable() {
autoreload_enabled = true; autoreload_enabled = true;
reload_requested = false; reload_requested = false;
autoreload_countdown = false;
} }
void autoreload_disable() { void autoreload_disable() {
autoreload_enabled = false; autoreload_enabled = false;
autoreload_countdown = false;
} }
void autoreload_suspend(size_t lock_mask) { void autoreload_suspend(uint32_t suspend_reason_mask) {
autoreload_suspended |= lock_mask; autoreload_suspended |= suspend_reason_mask;
} }
void autoreload_resume(size_t lock_mask) { void autoreload_resume(uint32_t suspend_reason_mask) {
autoreload_suspended &= ~lock_mask; autoreload_suspended &= ~suspend_reason_mask;
} }
inline bool autoreload_is_enabled() { inline bool autoreload_is_enabled() {
return autoreload_enabled; return autoreload_enabled;
} }
void autoreload_start() { void autoreload_start_countdown() {
// Enable ticks if we haven't been tracking an autoreload delay. We check // Avoid multiple tick enables.
// our current state so that we only turn ticks on once. Multiple starts if (!autoreload_countdown) {
// can occur before we reload and then turn ticks off.
if (autoreload_delay_ms == 0) {
supervisor_enable_tick(); supervisor_enable_tick();
autoreload_countdown = true;
} }
autoreload_delay_ms = CIRCUITPY_AUTORELOAD_DELAY_MS; // Start or restart the countdown interval.
} autoreload_countdown_ms = CIRCUITPY_AUTORELOAD_DELAY_MS;
void autoreload_stop() {
autoreload_delay_ms = 0;
reload_requested = false;
}
void autoreload_now() {
if (!autoreload_enabled || autoreload_suspended || reload_requested) {
return;
}
mp_raise_reload_exception();
reload_requested = true;
supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD);
} }

View File

@ -41,8 +41,8 @@ enum {
}; };
enum { enum {
AUTORELOAD_LOCK_REPL = 0x1, AUTORELOAD_SUSPEND_REPL = 0x1,
AUTORELOAD_LOCK_BLE = 0x2 AUTORELOAD_SUSPEND_BLE = 0x2
}; };
typedef struct { typedef struct {
@ -56,16 +56,16 @@ extern volatile bool reload_requested;
void autoreload_tick(void); void autoreload_tick(void);
void autoreload_start(void); void autoreload_start_countdown(void);
void autoreload_stop(void); void autoreload_reset(void);
void autoreload_enable(void); void autoreload_enable(void);
void autoreload_disable(void); void autoreload_disable(void);
bool autoreload_is_enabled(void); bool autoreload_is_enabled(void);
// Temporarily turn it off. Used during the REPL. // Temporarily turn autoreload off, for the given reason(s). Used during the REPL or during parts of BLE workflow.
void autoreload_suspend(size_t lock_mask); void autoreload_suspend(uint32_t suspend_reason_mask);
void autoreload_resume(size_t lock_mask); // Allow autoreloads again, for the given reason(s).
void autoreload_resume(uint32_t suspend_reason_mask);
void autoreload_now(void);
#endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H #endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H

View File

@ -326,7 +326,7 @@ STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
// Don't reload until everything is written out of the packet buffer. // Don't reload until everything is written out of the packet buffer.
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer); common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
// Trigger an autoreload // Trigger an autoreload
autoreload_start(); autoreload_start_countdown();
return ANY_COMMAND; return ANY_COMMAND;
} }
@ -384,7 +384,7 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
// Don't reload until everything is written out of the packet buffer. // Don't reload until everything is written out of the packet buffer.
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer); common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
// Trigger an autoreload // Trigger an autoreload
autoreload_start(); autoreload_start_countdown();
return ANY_COMMAND; return ANY_COMMAND;
} }
return WRITE_DATA; return WRITE_DATA;
@ -466,7 +466,7 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) {
// Don't reload until everything is written out of the packet buffer. // Don't reload until everything is written out of the packet buffer.
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer); common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
// Trigger an autoreload // Trigger an autoreload
autoreload_start(); autoreload_start_countdown();
} }
return ANY_COMMAND; return ANY_COMMAND;
} }
@ -521,7 +521,7 @@ STATIC uint8_t _process_mkdir(const uint8_t *raw_buf, size_t command_len) {
// Don't reload until everything is written out of the packet buffer. // Don't reload until everything is written out of the packet buffer.
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer); common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
// Trigger an autoreload // Trigger an autoreload
autoreload_start(); autoreload_start_countdown();
} }
return ANY_COMMAND; return ANY_COMMAND;
} }
@ -669,7 +669,7 @@ STATIC uint8_t _process_move(const uint8_t *raw_buf, size_t command_len) {
// Don't reload until everything is written out of the packet buffer. // Don't reload until everything is written out of the packet buffer.
common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer); common_hal_bleio_packet_buffer_flush(&_transfer_packet_buffer);
// Trigger an autoreload // Trigger an autoreload
autoreload_start(); autoreload_start_countdown();
} }
return ANY_COMMAND; return ANY_COMMAND;
} }
@ -692,7 +692,7 @@ void supervisor_bluetooth_file_transfer_background(void) {
if (size == 0) { if (size == 0) {
break; break;
} }
autoreload_suspend(AUTORELOAD_LOCK_BLE); autoreload_suspend(AUTORELOAD_SUSPEND_BLE);
// TODO: If size < 0 return an error. // TODO: If size < 0 return an error.
current_offset += size; current_offset += size;
#if CIRCUITPY_VERBOSE_BLE #if CIRCUITPY_VERBOSE_BLE
@ -710,7 +710,7 @@ void supervisor_bluetooth_file_transfer_background(void) {
response[0] = next_command; response[0] = next_command;
response[1] = STATUS_ERROR_PROTOCOL; response[1] = STATUS_ERROR_PROTOCOL;
common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, response, 2, NULL, 0); common_hal_bleio_packet_buffer_write(&_transfer_packet_buffer, response, 2, NULL, 0);
autoreload_resume(AUTORELOAD_LOCK_BLE); autoreload_resume(AUTORELOAD_SUSPEND_BLE);
break; break;
} }
switch (current_state) { switch (current_state) {
@ -744,7 +744,7 @@ void supervisor_bluetooth_file_transfer_background(void) {
current_offset = 0; current_offset = 0;
} }
if (next_command == ANY_COMMAND) { if (next_command == ANY_COMMAND) {
autoreload_resume(AUTORELOAD_LOCK_BLE); autoreload_resume(AUTORELOAD_SUSPEND_BLE);
} }
} }
running = false; running = false;
@ -754,5 +754,5 @@ void supervisor_bluetooth_file_transfer_disconnected(void) {
next_command = ANY_COMMAND; next_command = ANY_COMMAND;
current_offset = 0; current_offset = 0;
f_close(&active_file); f_close(&active_file);
autoreload_resume(AUTORELOAD_LOCK_BLE); autoreload_resume(AUTORELOAD_SUSPEND_BLE);
} }

View File

@ -113,7 +113,7 @@ static mp_uint_t flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t n
return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks); return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks);
} }
volatile bool filesystem_dirty = false; static volatile bool filesystem_dirty = false;
static mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { static mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
if (block_num == 0) { if (block_num == 0) {

View File

@ -66,7 +66,9 @@ static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
static background_callback_t tick_callback; static background_callback_t tick_callback;
volatile uint64_t last_finished_tick = 0; static volatile uint64_t last_finished_tick = 0;
static volatile size_t tick_enable_count = 0;
static void supervisor_background_tasks(void *unused) { static void supervisor_background_tasks(void *unused) {
port_start_background_task(); port_start_background_task();
@ -160,8 +162,7 @@ void mp_hal_delay_ms(mp_uint_t delay_ms) {
} }
} }
volatile size_t tick_enable_count = 0; void supervisor_enable_tick(void) {
extern void supervisor_enable_tick(void) {
common_hal_mcu_disable_interrupts(); common_hal_mcu_disable_interrupts();
if (tick_enable_count == 0) { if (tick_enable_count == 0) {
port_enable_tick(); port_enable_tick();
@ -170,7 +171,7 @@ extern void supervisor_enable_tick(void) {
common_hal_mcu_enable_interrupts(); common_hal_mcu_enable_interrupts();
} }
extern void supervisor_disable_tick(void) { void supervisor_disable_tick(void) {
common_hal_mcu_disable_interrupts(); common_hal_mcu_disable_interrupts();
if (tick_enable_count > 0) { if (tick_enable_count > 0) {
tick_enable_count--; tick_enable_count--;

View File

@ -170,7 +170,6 @@ bool tud_msc_is_writable_cb(uint8_t lun) {
// Callback invoked when received READ10 command. // Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes. // Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
(void)lun;
(void)offset; (void)offset;
const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE;
@ -216,7 +215,7 @@ void tud_msc_write10_complete_cb(uint8_t lun) {
(void)lun; (void)lun;
// This write is complete, start the autoreload clock. // This write is complete, start the autoreload clock.
autoreload_start(); autoreload_start_countdown();
} }
// Invoked when received SCSI_CMD_INQUIRY // Invoked when received SCSI_CMD_INQUIRY