Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,10 @@ msgstr ""
msgid "Display rotation must be in 90 degree increments"
msgstr ""

#: main.c
msgid "Done"
msgstr ""

#: shared-bindings/digitalio/DigitalInOut.c
msgid "Drive mode not used when direction is input."
msgstr ""
Expand Down Expand Up @@ -1535,6 +1539,14 @@ msgstr ""
msgid "Odd parity is not supported"
msgstr ""

#: supervisor/shared/bluetooth/bluetooth.c
msgid "Off"
msgstr ""

#: supervisor/shared/bluetooth/bluetooth.c
msgid "Ok"
msgstr ""

#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c
msgid "Only 8 or 16 bit mono with "
Expand Down Expand Up @@ -1787,6 +1799,10 @@ msgstr ""
msgid "Received response was invalid"
msgstr ""

#: supervisor/shared/bluetooth/bluetooth.c
msgid "Reconnecting"
msgstr ""

#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
Expand Down
93 changes: 65 additions & 28 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,22 @@ STATIC void stop_mp(void) {
gc_deinit();
}

STATIC const char *_current_executing_filename = NULL;

STATIC pyexec_result_t _exec_result = {0, MP_OBJ_NULL, 0};

void supervisor_execution_status(void) {
mp_obj_exception_t *exception = MP_OBJ_TO_PTR(_exec_result.exception);
if (_current_executing_filename != NULL) {
serial_write(_current_executing_filename);
} else if ((_exec_result.return_code & PYEXEC_EXCEPTION) != 0 &&
exception != NULL) {
mp_printf(&mp_plat_print, "@%d %q", _exec_result.exception_line, exception->base.type->name);
} else {
serial_write_compressed(translate("Done"));
}
}

#define STRING_LIST(...) {__VA_ARGS__, ""}

// Look for the first file that exists in the list of filenames, using mp_import_stat().
Expand All @@ -218,17 +234,23 @@ STATIC const char *first_existing_file_in_list(const char *const *filenames) {
return NULL;
}

STATIC bool maybe_run_list(const char *const *filenames, pyexec_result_t *exec_result) {
const char *filename = first_existing_file_in_list(filenames);
if (filename == NULL) {
STATIC bool maybe_run_list(const char *const *filenames) {
_exec_result.return_code = 0;
_exec_result.exception = MP_OBJ_NULL;
_exec_result.exception_line = 0;
_current_executing_filename = first_existing_file_in_list(filenames);
if (_current_executing_filename == NULL) {
return false;
}
mp_hal_stdout_tx_str(filename);
mp_hal_stdout_tx_str(_current_executing_filename);
serial_write_compressed(translate(" output:\n"));
pyexec_file(filename, exec_result);
supervisor_title_bar_update();
pyexec_file(_current_executing_filename, &_exec_result);
#if CIRCUITPY_ATEXIT
shared_module_atexit_execute(exec_result);
shared_module_atexit_execute(&_exec_result);
#endif
_current_executing_filename = NULL;
supervisor_title_bar_update();
return true;
}

Expand Down Expand Up @@ -347,12 +369,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
}
#endif

pyexec_result_t result;

result.return_code = 0;
result.exception = MP_OBJ_NULL;
result.exception_line = 0;

bool skip_repl = false;
bool skip_wait = false;
bool found_main = false;
Expand Down Expand Up @@ -391,7 +407,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
if (((next_code_info_t *)next_code_allocation->ptr)->filename[0] != '\0') {
const char *next_list[] = {((next_code_info_t *)next_code_allocation->ptr)->filename, ""};
// This is where the user's python code is actually executed:
found_main = maybe_run_list(next_list, &result);
found_main = maybe_run_list(next_list);
if (!found_main) {
serial_write(((next_code_info_t *)next_code_allocation->ptr)->filename);
serial_write_compressed(translate(" not found.\n"));
Expand All @@ -401,11 +417,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// Otherwise, default to the standard list of filenames
if (!found_main) {
// This is where the user's python code is actually executed:
found_main = maybe_run_list(supported_filenames, &result);
found_main = maybe_run_list(supported_filenames);
// If that didn't work, double check the extensions
#if CIRCUITPY_FULL_BUILD
if (!found_main) {
found_main = maybe_run_list(double_extension_filenames, &result);
found_main = maybe_run_list(double_extension_filenames);
if (found_main) {
serial_write_compressed(translate("WARNING: Your code filename has two extensions\n"));
}
Expand All @@ -417,15 +433,15 @@ 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
// BLE before it is reset and we have a delay before reconnect.
if ((result.return_code & PYEXEC_RELOAD) && supervisor_get_run_reason() == RUN_REASON_AUTO_RELOAD) {
if ((_exec_result.return_code & PYEXEC_RELOAD) && supervisor_get_run_reason() == RUN_REASON_AUTO_RELOAD) {
serial_write_compressed(translate("\nCode stopped by auto-reload. Reloading soon.\n"));
} else {
serial_write_compressed(translate("\nCode done running.\n"));
}


// Finished executing python code. Cleanup includes filesystem flush and a board reset.
cleanup_after_vm(heap, result.exception);
cleanup_after_vm(heap, _exec_result.exception);

// If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
// the options because it can be treated like any other reason-for-stickiness bit. The
Expand All @@ -436,15 +452,15 @@ 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;
}

if (result.return_code & PYEXEC_RELOAD) {
if (_exec_result.return_code & PYEXEC_RELOAD) {
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
// Reload immediately unless the reload is due to autoreload. In that
// case, we wait below to see if any other writes occur.
if (supervisor_get_run_reason() != RUN_REASON_AUTO_RELOAD) {
skip_repl = true;
skip_wait = true;
}
} else if (result.return_code == 0) {
} else if (_exec_result.return_code == 0) {
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS;
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) {
skip_repl = true;
Expand All @@ -455,12 +471,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// Deep sleep cannot be skipped
// TODO: settings in deep sleep should persist, using a new sleep memory API
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR
&& !(result.return_code & PYEXEC_DEEP_SLEEP)) {
&& !(_exec_result.return_code & PYEXEC_DEEP_SLEEP)) {
skip_repl = true;
skip_wait = true;
}
}
if (result.return_code & PYEXEC_FORCED_EXIT) {
if (_exec_result.return_code & PYEXEC_FORCED_EXIT) {
skip_repl = false;
skip_wait = true;
}
Expand All @@ -478,12 +494,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
uint8_t blink_count;
bool led_active = false;
#if CIRCUITPY_ALARM
if (result.return_code & PYEXEC_DEEP_SLEEP) {
if (_exec_result.return_code & PYEXEC_DEEP_SLEEP) {
color = BLACK;
blink_count = 0;
} else
#endif
if (result.return_code != PYEXEC_EXCEPTION) {
if (_exec_result.return_code != PYEXEC_EXCEPTION) {
if (safe_mode == NO_SAFE_MODE) {
color = ALL_DONE;
blink_count = ALL_DONE_BLINKS;
Expand Down Expand Up @@ -568,7 +584,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re

// Sleep until our next interrupt.
#if CIRCUITPY_ALARM
if (result.return_code & PYEXEC_DEEP_SLEEP) {
if (_exec_result.return_code & PYEXEC_DEEP_SLEEP) {
const bool awoke_from_true_deep_sleep =
common_hal_mcu_processor_get_reset_reason() == RESET_REASON_DEEP_SLEEP_ALARM;

Expand Down Expand Up @@ -730,19 +746,28 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
usb_set_defaults();
#endif

pyexec_result_t result = {0, MP_OBJ_NULL, 0};

if (ok_to_run) {
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
// Turn off title bar updates when writing out to boot_out.txt.
supervisor_title_bar_suspend();
vstr_t boot_text;
vstr_init(&boot_text, 512);
boot_output = &boot_text;
#endif

// Write version info
mp_printf(&mp_plat_print, "%s\nBoard ID:%s\n", MICROPY_FULL_VERSION_INFO, CIRCUITPY_BOARD_ID);
#if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH > 0
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
common_hal_mcu_processor_get_uid(raw_id);
mp_printf(&mp_plat_print, "UID:");
for (uint8_t i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
mp_printf(&mp_plat_print, "%02X", raw_id[i]);
}
mp_printf(&mp_plat_print, "\n");
#endif

bool found_boot = maybe_run_list(boot_py_filenames, &result);
bool found_boot = maybe_run_list(boot_py_filenames);
(void)found_boot;


Expand All @@ -752,6 +777,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
FATFS *fs = &vfs->fatfs;

boot_output = NULL;
supervisor_title_bar_resume();
bool write_boot_output = true;
FIL boot_output_file;
if (f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) {
Expand Down Expand Up @@ -794,7 +820,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {

port_post_boot_py(true);

cleanup_after_vm(heap, result.exception);
cleanup_after_vm(heap, _exec_result.exception);

port_post_boot_py(false);

Expand Down Expand Up @@ -831,7 +857,11 @@ STATIC int run_repl(bool first_run) {
exit_code = pyexec_raw_repl();
supervisor_title_bar_resume();
} else {
_current_executing_filename = "REPL";
supervisor_title_bar_update();
exit_code = pyexec_friendly_repl();
_current_executing_filename = NULL;
supervisor_title_bar_update();
}
#if CIRCUITPY_ATEXIT
pyexec_result_t result;
Expand All @@ -841,6 +871,13 @@ STATIC int run_repl(bool first_run) {
}
#endif
cleanup_after_vm(heap, MP_OBJ_SENTINEL);

// Also reset bleio. The above call omits it in case workflows should continue. In this case,
// we're switching straight to another VM so we want to reset.
#if CIRCUITPY_BLEIO
bleio_reset();
#endif

#if CIRCUITPY_STATUS_LED
status_led_init();
new_status_color(BLACK);
Expand Down
4 changes: 3 additions & 1 deletion ports/atmel-samd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ CFLAGS += \
-msoft-float \
-mfloat-abi=soft \
-DSAMD21
LIBS := libs/libgcc-12.1.0-Os-v6-m-nofp.a -lc
else
LIBS := -lgcc -lc
endif
ifeq ($(CHIP_FAMILY), samd51)
CFLAGS += \
Expand Down Expand Up @@ -200,7 +203,6 @@ endif
CFLAGS += -Wno-stringop-overread -Wno-stringop-overflow

LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,[email protected] -Wl,-cref -Wl,-gc-sections -specs=nano.specs
LIBS := -lgcc -lc

# Use toolchain libm if we're not using our own.
ifndef INTERNAL_LIBM
Expand Down
Binary file not shown.
20 changes: 14 additions & 6 deletions ports/nrf/common-hal/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,15 +449,23 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
return sd_ble_gap_addr_set(&local_address) == NRF_SUCCESS;
}

uint16_t bleio_adapter_get_name(char *buf, uint16_t len) {
uint16_t full_len = 0;
sd_ble_gap_device_name_get(NULL, &full_len);

uint32_t err_code = sd_ble_gap_device_name_get((uint8_t *)buf, &len);
if (err_code != NRF_SUCCESS) {
return 0;
}
return full_len;
}

mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
uint16_t len = 0;
sd_ble_gap_device_name_get(NULL, &len);
uint8_t buf[len];
uint32_t err_code = sd_ble_gap_device_name_get(buf, &len);
if (err_code != NRF_SUCCESS) {
return NULL;
}
return mp_obj_new_str((char *)buf, len);
char buf[len];
bleio_adapter_get_name(buf, len);
return mp_obj_new_str(buf, len);
}

void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) {
Expand Down
2 changes: 1 addition & 1 deletion py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ CFLAGS += -DCIRCUITPY_SSL=$(CIRCUITPY_SSL)
CIRCUITPY_STAGE ?= 0
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)

CIRCUITPY_STATUS_BAR ?= $(CIRCUITPY_WEB_WORKFLOW)
CIRCUITPY_STATUS_BAR ?= 1
CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR)

CIRCUITPY_STORAGE ?= 1
Expand Down
4 changes: 2 additions & 2 deletions shared-bindings/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ MP_PROPERTY_GETSET(bleio_adapter_address_obj,
//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
//| to make it easy to distinguish multiple CircuitPython boards."""
//|
STATIC mp_obj_t bleio_adapter_get_name(mp_obj_t self) {
STATIC mp_obj_t _bleio_adapter_get_name(mp_obj_t self) {
return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name);
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, _bleio_adapter_get_name);


STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) {
Expand Down
3 changes: 3 additions & 0 deletions shared-bindings/_bleio/Adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address);

// Copies the adapter name into the given buffer up to len and returns the full length (may be more
// than len if the buffer was too short.)
uint16_t bleio_adapter_get_name(char *buf, uint16_t len);
extern mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name);

Expand Down
Loading