From e6350ff8341510ccaaf0ae74502bea1040dca27b Mon Sep 17 00:00:00 2001 From: jun2sak Date: Wed, 17 Feb 2021 20:53:18 +0900 Subject: [PATCH 01/69] Initial commit. --- main.c | 3 + ports/nrf/Makefile | 8 + ports/nrf/common-hal/alarm/SleepMemory.c | 48 ++++ ports/nrf/common-hal/alarm/SleepMemory.h | 41 +++ ports/nrf/common-hal/alarm/__init__.c | 204 ++++++++++++++ ports/nrf/common-hal/alarm/__init__.h | 45 +++ ports/nrf/common-hal/alarm/pin/PinAlarm.c | 260 ++++++++++++++++++ ports/nrf/common-hal/alarm/pin/PinAlarm.h | 41 +++ ports/nrf/common-hal/alarm/pin/__init__.c | 38 +++ ports/nrf/common-hal/alarm/time/TimeAlarm.c | 101 +++++++ ports/nrf/common-hal/alarm/time/TimeAlarm.h | 40 +++ ports/nrf/common-hal/alarm/touch/TouchAlarm.c | 185 +++++++++++++ ports/nrf/common-hal/alarm/touch/TouchAlarm.h | 46 ++++ ports/nrf/mpconfigport.mk | 3 + ports/nrf/nrfx_config.h | 2 +- ports/nrf/supervisor/port.c | 43 ++- supervisor/serial.h | 3 + supervisor/shared/serial.c | 110 ++++++++ 18 files changed, 1218 insertions(+), 3 deletions(-) create mode 100644 ports/nrf/common-hal/alarm/SleepMemory.c create mode 100644 ports/nrf/common-hal/alarm/SleepMemory.h create mode 100644 ports/nrf/common-hal/alarm/__init__.c create mode 100644 ports/nrf/common-hal/alarm/__init__.h create mode 100644 ports/nrf/common-hal/alarm/pin/PinAlarm.c create mode 100644 ports/nrf/common-hal/alarm/pin/PinAlarm.h create mode 100644 ports/nrf/common-hal/alarm/pin/__init__.c create mode 100644 ports/nrf/common-hal/alarm/time/TimeAlarm.c create mode 100644 ports/nrf/common-hal/alarm/time/TimeAlarm.h create mode 100644 ports/nrf/common-hal/alarm/touch/TouchAlarm.c create mode 100644 ports/nrf/common-hal/alarm/touch/TouchAlarm.h diff --git a/main.c b/main.c index 7bfa565df4..054c6b4f53 100755 --- a/main.c +++ b/main.c @@ -214,6 +214,7 @@ STATIC bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec decompress(compressed, decompressed); mp_hal_stdout_tx_str(decompressed); pyexec_file(filename, exec_result); + dbg_printf("pyexec_file end result=(code=%d, line=%d)\r\n", exec_result->return_code, exec_result->exception_line); return true; } @@ -259,6 +260,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } STATIC bool run_code_py(safe_mode_t safe_mode) { + dbg_printf("run_code_py (%d)\r\n", (int)safe_mode); bool serial_connected_at_start = serial_connected(); #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 serial_write("\n"); @@ -434,6 +436,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { FIL* boot_output_file; STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { + dbg_printf("run_boot_py (%d)\r\n", (int)safe_mode); // If not in safe mode, run boot before initing USB and capture output in a // file. if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 278625e92d..c78a5dc503 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -87,6 +87,7 @@ INC += -I../../supervisor/shared/usb #Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -ggdb3 + CFLAGS += -DNDEBUG OPTIMIZATION_FLAGS = -Og else OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions @@ -94,6 +95,13 @@ else CFLAGS += -flto -flto-partition=none endif +ifeq ($(MY_DBG), 1) + CFLAGS += -DMY_DBG +endif +ifeq ($(MY_DEBUGUART), 1) + CFLAGS += -DMY_DEBUGUART=1 +endif + # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c new file mode 100644 index 0000000000..dd87b31b17 --- /dev/null +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * Copyright (c) 2020 Dan Halbert 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 + +#include "py/runtime.h" +#include "common-hal/alarm/SleepMemory.h" + +//static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; + +void alarm_sleep_memory_reset(void) { +} + +uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { + return 0; +} + +bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t* values, uint32_t len) { + return false; +} + +void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) { + return; +} diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h new file mode 100644 index 0000000000..ea3d40c35a --- /dev/null +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert 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 MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H + +#include "py/obj.h" + +// not implemented yet +#define SLEEP_MEMORY_LENGTH (4) + +typedef struct { + mp_obj_base_t base; +} alarm_sleep_memory_obj_t; + +extern void alarm_sleep_memory_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c new file mode 100644 index 0000000000..d5a4aec3c8 --- /dev/null +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -0,0 +1,204 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Dan Halbert 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 "py/gc.h" +#include "py/obj.h" +#include "py/objtuple.h" +#include "py/runtime.h" +#include +#include + +#include "shared-bindings/alarm/__init__.h" +#include "shared-bindings/alarm/SleepMemory.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/alarm/time/TimeAlarm.h" +#include "shared-bindings/alarm/touch/TouchAlarm.h" + +//#include "shared-bindings/wifi/__init__.h" +//#include "shared-bindings/microcontroller/__init__.h" + +#include "supervisor/port.h" + +#include "nrf.h" +#include "nrf_power.h" +#include "nrfx.h" +#include "nrfx_gpiote.h" + +extern void _debug_print(const char* s); +extern void _xxx_dumpRTC(void);//XXXX + +#define DEBUG_LED_PIN (NRF_GPIO_PIN_MAP(1, 11)) // P1_11 = LED +void _debug_led_init(void) { + nrf_gpio_cfg_output(DEBUG_LED_PIN); +} +void _debug_led_set(int v) { + nrf_gpio_pin_write(DEBUG_LED_PIN, v); +} + + +// Singleton instance of SleepMemory. +const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { + .base = { + .type = &alarm_sleep_memory_type, + }, +}; + +void alarm_reset(void) { + //alarm_sleep_memory_reset(); + alarm_pin_pinalarm_reset(); + alarm_time_timealarm_reset(); + //alarm_touch_touchalarm_reset(); +} + +extern uint32_t reset_reason_saved; +STATIC uint32_t _get_wakeup_cause(void) { + if (alarm_pin_pinalarm_woke_us_up()) { + return NRF_SLEEP_WAKEUP_GPIO; + } + if (alarm_time_timealarm_woke_us_up()) { + return NRF_SLEEP_WAKEUP_TIMER; + } +#if 0 + if (alarm_touch_touchalarm_woke_us_up()) { + return ESP_SLEEP_WAKEUP_TOUCHPAD; + } + return esp_sleep_get_wakeup_cause(); +#endif + if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { + return NRF_SLEEP_WAKEUP_RESETPIN; + } + else if (reset_reason_saved & NRF_POWER_RESETREAS_OFF_MASK) { + return NRF_SLEEP_WAKEUP_GPIO; + } + else if (reset_reason_saved & NRF_POWER_RESETREAS_VBUS_MASK) { + return NRF_SLEEP_WAKEUP_VBUS; + } + return NRF_SLEEP_WAKEUP_UNDEFINED; +} + +bool alarm_woken_from_sleep(void) { + uint32_t cause = _get_wakeup_cause(); + return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER + || cause == NRF_SLEEP_WAKEUP_TOUCHPAD + || cause == NRF_SLEEP_WAKEUP_RESETPIN); +} + +STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { + uint32_t cause = _get_wakeup_cause(); + if (cause & 0x80000000) { + printf("wakeup cause = 0x%08X\r\n", (int)cause); + } + switch (cause) { + case NRF_SLEEP_WAKEUP_TIMER: { + return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); + } + case NRF_SLEEP_WAKEUP_TOUCHPAD: { + return mp_const_none; + } + case NRF_SLEEP_WAKEUP_GPIO: { + return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); + } + } + return mp_const_none; +} + +mp_obj_t common_hal_alarm_get_wake_alarm(void) { + mp_obj_t obj = _get_wake_alarm(0, NULL); + //_xxx_dumpRTC();//XXX + return obj; +} + +// Set up light sleep or deep sleep alarms. +STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); + alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); +#if 0 + alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); +#endif + //_xxx_dumpRTC(); +} + +STATIC void _idle_until_alarm(void) { + int ct = 40; + // Poll for alarms. + while (!mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + // Allow ctrl-C interrupt. + if (alarm_woken_from_sleep()) { + alarm_save_wake_alarm(); + int cause = _get_wakeup_cause(); + printf("wakeup(%d)\r\n", cause); //XXX + return; + } + port_idle_until_interrupt(); + if (ct > 0) { + printf("_"); --ct; + } + } +} + +mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + mp_obj_t r_obj = mp_const_none; + _setup_sleep_alarms(false, n_alarms, alarms); + _debug_print("\r\nsleep..."); + + _idle_until_alarm(); + + if (mp_hal_is_interrupted()) { + _debug_print("mp_hal_is_interrupted\r\n"); + r_obj = mp_const_none; + } + else { + r_obj = _get_wake_alarm(n_alarms, alarms); + alarm_reset(); + } + return r_obj; +} + +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { + _setup_sleep_alarms(true, n_alarms, alarms); +} + +void nrf_deep_sleep_start(void) { + _debug_print("go system off..\r\n"); + sd_power_system_off(); +} + +void NORETURN alarm_enter_deep_sleep(void) { + alarm_pin_pinalarm_prepare_for_deep_sleep(); + //alarm_touch_touchalarm_prepare_for_deep_sleep(); + + nrf_deep_sleep_start(); + + // should not reach here.. + while(1) ; +} + +void common_hal_alarm_gc_collect(void) { + void* p = alarm_get_wake_alarm(); + gc_collect_ptr(p); +} diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h new file mode 100644 index 0000000000..11652ec828 --- /dev/null +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert 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 MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H + +#include "common-hal/alarm/SleepMemory.h" + +typedef enum { + NRF_SLEEP_WAKEUP_UNDEFINED, + NRF_SLEEP_WAKEUP_GPIO, + NRF_SLEEP_WAKEUP_TIMER, + NRF_SLEEP_WAKEUP_TOUCHPAD, + NRF_SLEEP_WAKEUP_VBUS, + NRF_SLEEP_WAKEUP_RESETPIN, +} nrf_sleep_source_t; + +extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; + +extern void alarm_reset(void); + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c new file mode 100644 index 0000000000..0e0f6c4832 --- /dev/null +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -0,0 +1,260 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2020 Scott Shawcroft 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 "py/runtime.h" +#include + +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "nrfx.h" +#include "nrf_gpio.h" +#include "nrfx_gpiote.h" +#include "nrf_soc.h" +#include + +#include "supervisor/serial.h" // dbg_print + +#define WPIN_UNUSED 0xFF +volatile char _pinhandler_gpiote_count; +volatile nrfx_gpiote_pin_t _pinhandler_ev_pin; +#define MYGPIOTE_EV_PIN_UNDEF 0xFF + +void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { +#if 0 + if (edge) { + mp_raise_ValueError(translate("Cannot wake on pin edge. Only level.")); + } + + if (pull && !GPIO_IS_VALID_OUTPUT_GPIO(pin->number)) { + mp_raise_ValueError(translate("Cannot pull on input-only pin.")); + } +#endif + self->pin = pin; + self->value = value; + self->pull = pull; +} + +mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) { + return self->pin; +} + +bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) { + return self->value; +} + +bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self) { + return false; +} + +bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) { + return self->pull; +} + + +static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + ++_pinhandler_gpiote_count; + _pinhandler_ev_pin = pin; +} + +bool alarm_pin_pinalarm_woke_us_up(void) { + return (_pinhandler_gpiote_count > 0 && _pinhandler_ev_pin != MYGPIOTE_EV_PIN_UNDEF); +} + +mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { + // First, check to see if we match any given alarms. + for (size_t i = 0; i < n_alarms; i++) { + if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) { + continue; + } + alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); + if (alarm->pin->number == _pinhandler_ev_pin) { + return alarms[i]; + } + } + + alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); + alarm->base.type = &alarm_pin_pinalarm_type; + alarm->pin = NULL; + // Map the pin number back to a pin object. + for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { + const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); + if ((size_t) pin_obj->number == _pinhandler_ev_pin) { + alarm->pin = mcu_pin_globals.map.table[i].value; + break; + } + } + return alarm; +} + +// These must be static because we need to configure pulls later, right before +// deep sleep. +static uint64_t high_alarms = 0; +static uint64_t low_alarms = 0; +static uint64_t pull_pins = 0; + +void alarm_pin_pinalarm_reset(void) { + for (size_t i = 0; i < 64; i++) { + uint64_t mask = 1ull << i; + bool high = (high_alarms & mask) != 0; + bool low = (low_alarms & mask) != 0; + if (!(high || low)) { + continue; + } + reset_pin_number(i); + nrfx_gpiote_in_event_disable((nrfx_gpiote_pin_t)i); + nrfx_gpiote_in_uninit((nrfx_gpiote_pin_t)i); + } + + high_alarms = 0; + low_alarms = 0; + pull_pins = 0; +} + +void _setup2(void) { + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_PULLUP, + .is_watcher = false, + .hi_accuracy = true, + .skip_gpio_setup = false + }; + for(size_t i = 0; i < 64; ++i) { + uint64_t mask = 1ull << i; + int pull = 0; + int sense = 0; + if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { + continue; + } + if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { + cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; + cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; + pull = -1; sense = 1; + } + else + if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { + cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; + cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; + pull = 1; sense = -1; + } + else { + cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; + cfg.pull = NRF_GPIO_PIN_NOPULL; + sense = 9; + } + nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, pinalarm_gpiote_handler); + nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); + printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); + } +} + +void _setup_pin1_for_lightsleep(void) { + if ( nrfx_gpiote_is_init() ) { + nrfx_gpiote_uninit(); + } + nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); + + _pinhandler_gpiote_count = 0; + _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; + _setup2(); +} + +void _setup_pin1_for_deepsleep(void) { + for(size_t i = 0; i < 64; ++i) { + uint64_t mask = 1ull << i; + int pull = 0; + int sense = 0; + if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { + continue; + } + if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { + pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; + nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); + nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); + sense = NRF_GPIO_PIN_SENSE_HIGH; + } + else + if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { + pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; + nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); + nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); + sense = NRF_GPIO_PIN_SENSE_LOW; + } + printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); + } +#if 0 + uint32_t pin_number = 2; + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + dbg_printf(" 2 PIN_CNF=0x%08X\r\n", (unsigned int)(reg->PIN_CNF[pin_number])); + pin_number = 28; + reg = nrf_gpio_pin_port_decode(&pin_number); + dbg_printf("28 PIN_CNF=0x%08X\r\n", (unsigned int)(reg->PIN_CNF[pin_number])); +#endif +} + +void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + // Bitmask of wake up settings. + size_t high_count = 0; + size_t low_count = 0; + int pin_number = -1; + + for (size_t i = 0; i < n_alarms; i++) { + if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) { + continue; + } + alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); + + pin_number = alarm->pin->number; + dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); + if (alarm->value) { + high_alarms |= 1ull << pin_number; + high_count++; + } else { + low_alarms |= 1ull << pin_number; + low_count++; + } + if (alarm->pull) { + pull_pins |= 1ull << pin_number; + } + } + if (pin_number != -1) { + if (!deep_sleep) { + _setup_pin1_for_lightsleep(); + } + else { + //_setup_pin1_for_deepsleep(pin_number); + } + } + else { + dbg_printf("alarm_pin_pinalarm_set_alarms() no valid pins\r\n"); + } +} + +void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { + _setup_pin1_for_deepsleep(); +} diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.h b/ports/nrf/common-hal/alarm/pin/PinAlarm.h new file mode 100644 index 0000000000..93672c1f2d --- /dev/null +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert 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 "py/obj.h" +#include "py/objtuple.h" + +typedef struct { + mp_obj_base_t base; + mcu_pin_obj_t *pin; + bool value; + bool pull; +} alarm_pin_pinalarm_obj_t; + +void alarm_pin_pinalarm_reset(void); +void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); +void alarm_pin_pinalarm_prepare_for_deep_sleep(void); +mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms); +bool alarm_pin_pinalarm_woke_us_up(void); diff --git a/ports/nrf/common-hal/alarm/pin/__init__.c b/ports/nrf/common-hal/alarm/pin/__init__.c new file mode 100644 index 0000000000..d2ce00a3e3 --- /dev/null +++ b/ports/nrf/common-hal/alarm/pin/__init__.c @@ -0,0 +1,38 @@ +//#include "shared-bindings/alarm_io/__init__.h" + +//#include "esp_sleep.h" +//#include "driver/rtc_io.h" + +mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { +#if 0 + if (!rtc_gpio_is_valid_gpio(self_in->gpio)) { + mp_raise_ValueError(translate("io must be rtc io")); + } + + if (self_in->pull && !self_in->level) { + for (uint8_t i = 0; i<=4; i+=2) { + if (self_in->gpio == i) { + mp_raise_ValueError(translate("IOs 0, 2 & 4 do not support internal pullup in sleep")); + } + } + } + + switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) { + case ESP_ERR_INVALID_ARG: + mp_raise_ValueError(translate("trigger level must be 0 or 1")); + case ESP_ERR_INVALID_STATE: + mp_raise_RuntimeError(translate("wakeup conflict")); + default: + break; + } + + if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); } +#endif + return self_in; +} + +void common_hal_alarm_io_disable (void) { +#if 0 + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1); +#endif +} diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c new file mode 100644 index 0000000000..220ed2f4df --- /dev/null +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -0,0 +1,101 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert 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 "esp_sleep.h" + +#include "py/runtime.h" +//#include "supervisor/esp_port.h" +#include + +#include "shared-bindings/alarm/time/TimeAlarm.h" +#include "shared-bindings/time/__init__.h" + +void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) { + self->monotonic_time = monotonic_time; +} + +mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self) { + return self->monotonic_time; +} + +mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { + // First, check to see if we match + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { + return alarms[i]; + } + } + alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t); + timer->base.type = &alarm_time_timealarm_type; + // TODO: Set monotonic_time based on the RTC state. + timer->monotonic_time = 0.0f; + return timer; +} + +extern volatile int rtc_woke_up_counter; +bool alarm_time_timealarm_woke_us_up(void) { + return rtc_woke_up_counter; +} + +extern void port_disable_interrupt_after_ticks_ch(uint32_t channel); +void alarm_time_timealarm_reset(void) { + port_disable_interrupt_after_ticks_ch(1); + rtc_woke_up_counter = 0; +} + +extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks);//XXX in port.c + +void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + bool timealarm_set = false; + alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL; + + for (size_t i = 0; i < n_alarms; i++) { + if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { + continue; + } + if (timealarm_set) { + mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); + } + timealarm = MP_OBJ_TO_PTR(alarms[i]); + timealarm_set = true; + } + if (!timealarm_set) { + return; + } + + // Compute how long to actually sleep, considering the time now. + mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; + mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs); + int wsecs = (int)(wakeup_in_secs); + if (wsecs > 510) { //XXX + mp_raise_ValueError(translate("Alarm time is too far.")); + } + + uint32_t wakeup_in_ticks = (uint32_t)(wakeup_in_secs * 1024.0f); + //printf("alarm_time_timealarm_set_alarms() %d secs 0x%08X ticks\r\n", wsecs, (int)wakeup_in_ticks); + port_interrupt_after_ticks_ch(1, wakeup_in_ticks); + rtc_woke_up_counter = 0; +} diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h new file mode 100644 index 0000000000..dfd75524fd --- /dev/null +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert 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 "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_float_t monotonic_time; // values compatible with time.monotonic_time() +} alarm_time_timealarm_obj_t; + +// Find the alarm object that caused us to wake up or create an equivalent one. +mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms); +// Check for the wake up alarm from pretend deep sleep. +bool alarm_time_timealarm_woke_us_up(void); +void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); +void alarm_time_timealarm_reset(void); diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c new file mode 100644 index 0000000000..4db178c56e --- /dev/null +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c @@ -0,0 +1,185 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * 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 "shared-bindings/alarm/touch/TouchAlarm.h" +#include "shared-bindings/microcontroller/__init__.h" + +//#include "esp_sleep.h" +//#include "peripherals/touch.h" +//#include "supervisor/esp_port.h" + +static uint16_t touch_channel_mask; +static volatile bool woke_up = false; + +void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { +#if 0 + if (pin->touch_channel == TOUCH_PAD_MAX) { + mp_raise_ValueError(translate("Invalid pin")); + } + claim_pin(pin); +#endif + self->pin = pin; +} + +mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) { + // First, check to see if we match any given alarms. + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { + return alarms[i]; + } + } + + // Create TouchAlarm object. + alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t); + alarm->base.type = &alarm_touch_touchalarm_type; + alarm->pin = NULL; +#if 0 + touch_pad_t wake_channel = touch_pad_get_current_meas_channel(); + if (wake_channel == TOUCH_PAD_MAX) { + return alarm; + } + + // Map the pin number back to a pin object. + for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { + const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); + if (pin_obj->touch_channel == wake_channel) { + alarm->pin = mcu_pin_globals.map.table[i].value; + break; + } + } +#endif + return alarm; +} + +// This is used to wake the main CircuitPython task. +void touch_interrupt(void *arg) { + (void) arg; +#if 0 + woke_up = true; + BaseType_t task_wakeup; + vTaskNotifyGiveFromISR(circuitpython_task, &task_wakeup); + if (task_wakeup) { + portYIELD_FROM_ISR(); + } +#endif +} + +void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { +#if 0 + bool touch_alarm_set = false; + alarm_touch_touchalarm_obj_t *touch_alarm = MP_OBJ_NULL; + + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { + if (deep_sleep && touch_alarm_set) { + mp_raise_ValueError(translate("Only one TouchAlarm can be set in deep sleep.")); + } + touch_alarm = MP_OBJ_TO_PTR(alarms[i]); + touch_channel_mask |= 1 << touch_alarm->pin->number; + touch_alarm_set = true; + } + } + + if (!touch_alarm_set) { + return; + } + + // configure interrupt for pretend to deep sleep + // this will be disabled if we actually deep sleep + + // reset touch peripheral + peripherals_touch_reset(); + peripherals_touch_never_reset(true); + + for (uint8_t i = 1; i <= 14; i++) { + if ((touch_channel_mask & 1 << i) != 0) { + touch_pad_t touch_channel = (touch_pad_t)i; + // intialize touchpad + peripherals_touch_init(touch_channel); + + // wait for touch data to reset + mp_hal_delay_ms(10); + + // configure trigger threshold + uint32_t touch_value; + touch_pad_read_benchmark(touch_channel, &touch_value); + touch_pad_set_thresh(touch_channel, touch_value * 0.1); //10% + } + } + + // configure touch interrupt + touch_pad_timeout_set(true, SOC_TOUCH_PAD_THRESHOLD_MAX); + touch_pad_isr_register(touch_interrupt, NULL, TOUCH_PAD_INTR_MASK_ALL); + touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); +} + +void alarm_touch_touchalarm_prepare_for_deep_sleep(void) { + if (!touch_channel_mask) { + return; + } + + touch_pad_t touch_channel = TOUCH_PAD_MAX; + for (uint8_t i = 1; i <= 14; i++) { + if ((touch_channel_mask & 1 << i) != 0) { + touch_channel = (touch_pad_t)i; + break; + } + } + + // reset touch peripheral + peripherals_touch_never_reset(false); + peripherals_touch_reset(); + + // intialize touchpad + peripherals_touch_init(touch_channel); + + // configure touchpad for sleep + touch_pad_sleep_channel_enable(touch_channel, true); + touch_pad_sleep_channel_enable_proximity(touch_channel, false); + + // wait for touch data to reset + mp_hal_delay_ms(10); + + // configure trigger threshold + uint32_t touch_value; + touch_pad_sleep_channel_read_smooth(touch_channel, &touch_value); + touch_pad_sleep_set_threshold(touch_channel, touch_value * 0.1); //10% + + // enable touchpad wakeup + esp_sleep_enable_touchpad_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); +#endif +} + +bool alarm_touch_touchalarm_woke_us_up(void) { + return woke_up; +} + +void alarm_touch_touchalarm_reset(void) { + woke_up = false; + touch_channel_mask = 0; +// peripherals_touch_never_reset(false); +} diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.h b/ports/nrf/common-hal/alarm/touch/TouchAlarm.h new file mode 100644 index 0000000000..755a3977ad --- /dev/null +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * + * 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 MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H +#define MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; +} alarm_touch_touchalarm_obj_t; + +// Find the alarm object that caused us to wake up or create an equivalent one. +mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms); +// Check for the wake up alarm from pretend deep sleep. +void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms); +void alarm_touch_touchalarm_prepare_for_deep_sleep(void); +bool alarm_touch_touchalarm_woke_us_up(void); +void alarm_touch_touchalarm_reset(void); + +#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 9560064fbc..3e3f30d350 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -42,6 +42,9 @@ CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_COUNTIO = 0 CIRCUITPY_WATCHDOG ?= 1 +# Sleep and Wakeup +CIRCUITPY_ALARM = 1 + # nRF52840-specific ifeq ($(MCU_CHIP),nrf52840) diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h index 94812d5913..1becad813d 100644 --- a/ports/nrf/nrfx_config.h +++ b/ports/nrf/nrfx_config.h @@ -116,7 +116,7 @@ // GPIO interrupt #define NRFX_GPIOTE_ENABLED 1 -#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 2 #define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 7 // NVM controller diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 78bb20ce6c..3ed822ed76 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -27,6 +27,10 @@ #include #include "supervisor/port.h" #include "supervisor/board.h" +#ifdef MY_DEBUGUART +#include "supervisor/serial.h" // dbg_printf() +extern void _debug_uart_init(void); +#endif #include "nrfx/hal/nrf_clock.h" #include "nrfx/hal/nrf_power.h" @@ -90,6 +94,9 @@ static volatile struct { uint32_t suffix; } overflow_tracker __attribute__((section(".uninitialized"))); +uint32_t reset_reason_saved = 0; +volatile int rtc_woke_up_counter = 0; + void rtc_handler(nrfx_rtc_int_type_t int_type) { if (int_type == NRFX_RTC_INT_OVERFLOW) { // Our RTC is 24 bits and we're clocking it at 32.768khz which is 32 (2 ** 5) subticks per @@ -100,9 +107,25 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { supervisor_tick(); } else if (int_type == NRFX_RTC_INT_COMPARE0) { nrfx_rtc_cc_set(&rtc_instance, 0, 0, false); + } else if (int_type == NRFX_RTC_INT_COMPARE1) { + // used in light sleep + ++rtc_woke_up_counter; + nrfx_rtc_cc_set(&rtc_instance, 1, 0, false); } } +void _xxx_dumpRTC(void) { + dbg_printf("\r\nRTC2\r\n"); + NRF_RTC_Type *r = rtc_instance.p_reg; + dbg_printf("PRESCALER=%08X, ", (int)r->PRESCALER); + dbg_printf("COUNTER=%08X ", (int)r->COUNTER); + dbg_printf("INTENSET=%08X ", (int)r->INTENSET); + dbg_printf("EVTENSET=%08X\r\n", (int)r->EVTENSET); + dbg_printf("EVENTS_COMPARE[0..3]=%X,%X,%X,%X ", (int)r->EVENTS_COMPARE[0], (int)r->EVENTS_COMPARE[1], (int)r->EVENTS_COMPARE[2], (int)r->EVENTS_COMPARE[3]); + dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); + dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); +} + void tick_init(void) { if (!nrf_clock_lf_is_running(NRF_CLOCK)) { nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART); @@ -124,6 +147,7 @@ void tick_init(void) { } } + safe_mode_t port_init(void) { nrf_peripherals_clocks_init(); @@ -153,6 +177,8 @@ safe_mode_t port_init(void) { analogin_init(); #endif + reset_reason_saved = NRF_POWER->RESETREAS; + // If the board was reset by the WatchDogTimer, we may // need to boot into safe mode. Reset the RESETREAS bit // for the WatchDogTimer so we don't encounter this the @@ -171,6 +197,7 @@ safe_mode_t port_init(void) { return NO_SAFE_MODE; } + void reset_port(void) { #ifdef CIRCUITPY_GAMEPAD_TICKS gamepad_reset(); @@ -219,6 +246,10 @@ void reset_port(void) { #endif reset_all_pins(); + +#ifdef MY_DEBUGUART + _debug_uart_init(); +#endif } void reset_to_bootloader(void) { @@ -295,7 +326,7 @@ void port_disable_tick(void) { nrfx_rtc_tick_disable(&rtc_instance); } -void port_interrupt_after_ticks(uint32_t ticks) { +void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks) { uint32_t current_ticks = nrfx_rtc_counter_get(&rtc_instance); uint32_t diff = 3; if (ticks > diff) { @@ -304,7 +335,15 @@ void port_interrupt_after_ticks(uint32_t ticks) { if (diff > 0xffffff) { diff = 0xffffff; } - nrfx_rtc_cc_set(&rtc_instance, 0, current_ticks + diff, true); + nrfx_rtc_cc_set(&rtc_instance, channel, current_ticks + diff, true); +} + +void port_disable_interrupt_after_ticks_ch(uint32_t channel) { + nrfx_rtc_cc_disable(&rtc_instance, channel); +} + +void port_interrupt_after_ticks(uint32_t ticks) { + port_interrupt_after_ticks_ch(0, ticks); } void port_idle_until_interrupt(void) { diff --git a/supervisor/serial.h b/supervisor/serial.h index 066886303e..6cd8530b36 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -29,6 +29,7 @@ #include #include +#include #include "py/mpconfig.h" @@ -47,4 +48,6 @@ char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); +int dbg_printf(const char *fmt, ...)__attribute__((format (printf, 1, 2))); + #endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index b9feb04f25..2db4c6b2ec 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -36,6 +36,103 @@ #include "tusb.h" +#ifdef MY_DEBUGUART +#include +#include +#include "nrfx.h" +#include "nrf_uart.h" +#include "nrfx_uart.h" +const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); +static int _dbg_uart_initialized = 0; +#define DBG_PBUF_LEN 80 +static char _dbg_pbuf[DBG_PBUF_LEN+1]; + +void _debug_uart_init(void) { + //if (_dbg_uart_initialized) return; + nrfx_uarte_config_t config = { + .pseltxd = 26, + .pselrxd = 15, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UART_BAUDRATE_115200, + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED + } + }; + nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); + // drive config + nrf_gpio_cfg(config.pseltxd, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_PULLUP, // orig=NOPULL + NRF_GPIO_PIN_H0H1, // orig=S0S1 + NRF_GPIO_PIN_NOSENSE); + _dbg_uart_initialized = 1; + return; +} + +void _debug_printbuf(char* data) { + int siz, l; + while((l = strlen(data)) != 0) { + if (l <= DBG_PBUF_LEN) { + siz = l; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + } +} + +void _debug_print_substr(const char* text, uint32_t length) { + char* data = (char*)text; + int siz; + while(length != 0) { + if (length <= DBG_PBUF_LEN) { + siz = length; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + length -= siz; + } +} + +void _debug_print(const char* s) { + _debug_printbuf((char*)s); +} + +void _debug_uart_deinit(void) { + nrfx_uarte_uninit(&_dbg_uart_inst); +} + +int dbg_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vprintf(fmt, ap); + va_end(ap); + return ret; +} + +extern void _debug_led_init(void); +extern void _debug_led_set(int v); +#else /*!MY_DEBUGUART*/ +int dbg_printf(const char *fmt, ...) { + return 0; +} +#endif + + /* * Note: DEBUG_UART currently only works on STM32, * enabling on another platform will cause a crash. @@ -63,10 +160,19 @@ void serial_early_init(void) { buf_array, true); common_hal_busio_uart_never_reset(&debug_uart); #endif + +#ifdef MY_DEBUGUART + _debug_uart_init(); + _debug_led_init(); + _debug_print("\r\ndebug_uart start\r\n"); +#endif } void serial_init(void) { usb_init(); +#ifdef MY_DEBUGUART + _debug_uart_init(); +#endif } bool serial_connected(void) { @@ -144,6 +250,10 @@ void serial_write_substring(const char* text, uint32_t length) { int uart_errcode; common_hal_busio_uart_write(&debug_uart, (const uint8_t*) text, length, &uart_errcode); #endif + +#ifdef MY_DEBUGUART + _debug_print_substr(text, length); +#endif } void serial_write(const char* text) { From cf2427c5618339fa248c41064796f5c39a4e5bf2 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Wed, 17 Feb 2021 21:51:28 +0900 Subject: [PATCH 02/69] light sleep reason fix. --- ports/nrf/common-hal/alarm/__init__.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index d5a4aec3c8..c91593861a 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -144,6 +144,7 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t STATIC void _idle_until_alarm(void) { int ct = 40; + reset_reason_saved = 0; // Poll for alarms. while (!mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; From 26f8f532f126bb0b66e3a812d46e78fabf73f5f6 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 00:47:07 +0900 Subject: [PATCH 03/69] safe mode fix. --- .gitignore | 6 ++ main.c | 15 +++- ports/nrf/common-hal/alarm/SleepMemory.c | 69 +++++++++++++++++-- ports/nrf/common-hal/alarm/__init__.c | 57 +++++++++++---- ports/nrf/common-hal/alarm/__init__.h | 1 + ports/nrf/common-hal/alarm/pin/PinAlarm.c | 26 +++++-- .../common-hal/microcontroller/Processor.c | 22 +++++- ports/nrf/supervisor/port.c | 8 ++- supervisor/shared/serial.c | 21 ------ 9 files changed, 175 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index a8814be45e..6f27970f89 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,9 @@ TAGS #################### .venv .env + +1FILES +2FILES +TAG +ports/nrf/LOG*.txt +ports/nrf/boards/pg8c diff --git a/main.c b/main.c index 054c6b4f53..b3c783bf79 100755 --- a/main.c +++ b/main.c @@ -214,7 +214,7 @@ STATIC bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec decompress(compressed, decompressed); mp_hal_stdout_tx_str(decompressed); pyexec_file(filename, exec_result); - dbg_printf("pyexec_file end result=(code=%d, line=%d)\r\n", exec_result->return_code, exec_result->exception_line); + //dbg_printf("pyexec_file end result=(code=%d, line=%d)\r\n", exec_result->return_code, exec_result->exception_line); return true; } @@ -260,7 +260,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } STATIC bool run_code_py(safe_mode_t safe_mode) { - dbg_printf("run_code_py (%d)\r\n", (int)safe_mode); + //dbg_printf("run_code_py (%d)\r\n", (int)safe_mode); bool serial_connected_at_start = serial_connected(); #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 serial_write("\n"); @@ -436,7 +436,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { FIL* boot_output_file; STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { - dbg_printf("run_boot_py (%d)\r\n", (int)safe_mode); + //dbg_printf("run_boot_py (%d)\r\n", (int)safe_mode); // If not in safe mode, run boot before initing USB and capture output in a // file. if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { @@ -583,6 +583,15 @@ int __attribute__((used)) main(void) { // Start serial and HID after giving boot.py a chance to tweak behavior. serial_init(); +#if 0 //XXX + int rr = (int)common_hal_mcu_processor_get_reset_reason(); + const char* rrstr[] = { + "POWER_ON", "BROWNOUT", "SOFTWARE", "DEEPSLEEPALARM", + "RESET_PIN", "WATCHDOG", "UNKNOWN" + }; + dbg_printf("reset_reason=%s\r\n", rrstr[rr]); +#endif + #if CIRCUITPY_BLEIO supervisor_start_bluetooth(); #endif diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index dd87b31b17..a867b17b13 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -26,23 +26,84 @@ */ #include +#ifdef MY_DEBUGUART +#include "supervisor/serial.h" // dbg_printf() +#endif #include "py/runtime.h" #include "common-hal/alarm/SleepMemory.h" -//static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; +#define RTC_DATA_ATTR __attribute__((section(".uninitialized"))) +static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; +static RTC_DATA_ATTR uint32_t _sleep_mem_magicnum; +#define SLEEP_MEMORY_DATA_GUARD 0xad0000af +#define SLEEP_MEMORY_DATA_GUARD_MASK 0xff0000ff + +static int is_sleep_memory_valid(void) { + if ((_sleep_mem_magicnum & SLEEP_MEMORY_DATA_GUARD_MASK) + == SLEEP_MEMORY_DATA_GUARD) { + return 1; + } + return 0; +} + +static void dumpRAMreg(void) { +#ifdef MY_DEBUGUART + int i; + for(i = 0; i <= 8; ++i) { + dbg_printf(" RAM%d:%08X", i, (int)(NRF_POWER->RAM[i].POWER)); + if (i==4) dbg_printf("\r\n"); + } + dbg_printf("\r\n"); +#endif +} + +static void initialize_sleep_memory(void) { + memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); + + // also, set RAM[n].POWER register for RAM retention + // nRF52840 has RAM[0..7].Section[0..1] and RAM[8].Section[0..5] + // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] + dumpRAMreg(); + for(int ram = 0; ram <= 7; ++ram) { + NRF_POWER->RAM[ram].POWERSET = 0x00030000; // RETENTION for section 0,1 + }; +#ifdef NRF52840 + NRF_POWER->RAM[8].POWERSET = 0x001F0000; // RETENTION for section 0..5 +#endif +#ifdef NRF52833 + NRF_POWER->RAM[8].POWERSET = 0x00030000; // RETENTION for section 0,1 +#endif + dumpRAMreg(); + + _sleep_mem_magicnum = SLEEP_MEMORY_DATA_GUARD; +} void alarm_sleep_memory_reset(void) { + if (!is_sleep_memory_valid()) { + initialize_sleep_memory(); +#ifdef MY_DEBUGUART + dbg_printf("_sleep_mem[] initialized\r\n"); +#endif + } } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - return 0; + return sizeof(_sleep_mem); } bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t* values, uint32_t len) { - return false; + if (start_index + len > sizeof(_sleep_mem)) { + return false; + } + + memcpy((uint8_t *) (_sleep_mem + start_index), values, len); + return true; } void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) { - return; + if (start_index + len > sizeof(_sleep_mem)) { + return; + } + memcpy(values, (uint8_t *) (_sleep_mem + start_index), len); } diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index c91593861a..1823bf4649 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -42,14 +42,15 @@ //#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/port.h" +#ifdef MY_DEBUGUART +#include "supervisor/serial.h" // dbg_printf() +#endif #include "nrf.h" #include "nrf_power.h" #include "nrfx.h" #include "nrfx_gpiote.h" -extern void _debug_print(const char* s); -extern void _xxx_dumpRTC(void);//XXXX #define DEBUG_LED_PIN (NRF_GPIO_PIN_MAP(1, 11)) // P1_11 = LED void _debug_led_init(void) { @@ -68,14 +69,14 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { }; void alarm_reset(void) { - //alarm_sleep_memory_reset(); + alarm_sleep_memory_reset(); alarm_pin_pinalarm_reset(); alarm_time_timealarm_reset(); //alarm_touch_touchalarm_reset(); } extern uint32_t reset_reason_saved; -STATIC uint32_t _get_wakeup_cause(void) { +STATIC nrf_sleep_source_t _get_wakeup_cause(void) { if (alarm_pin_pinalarm_woke_us_up()) { return NRF_SLEEP_WAKEUP_GPIO; } @@ -101,17 +102,30 @@ STATIC uint32_t _get_wakeup_cause(void) { } bool alarm_woken_from_sleep(void) { - uint32_t cause = _get_wakeup_cause(); + nrf_sleep_source_t cause = _get_wakeup_cause(); return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER || cause == NRF_SLEEP_WAKEUP_TOUCHPAD || cause == NRF_SLEEP_WAKEUP_RESETPIN); } +#ifdef MY_DEBUGUART +static const char* cause_str[] = { + "UNDEFINED", + "GPIO", + "TIMER", + "TOUCHPAD", + "VBUS", + "RESETPIN", +}; +#endif + STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { - uint32_t cause = _get_wakeup_cause(); - if (cause & 0x80000000) { - printf("wakeup cause = 0x%08X\r\n", (int)cause); + nrf_sleep_source_t cause = _get_wakeup_cause(); +#if 0 + if (cause >= 0 && cause < NRF_SLEEP_WAKEUP_ZZZ) { + printf("wakeup cause = NRF_SLEEP_WAKEUP_%s\r\n", cause_str[(int)cause]); } +#endif switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); @@ -122,13 +136,14 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { case NRF_SLEEP_WAKEUP_GPIO: { return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); } + default: + break; } return mp_const_none; } mp_obj_t common_hal_alarm_get_wake_alarm(void) { mp_obj_t obj = _get_wake_alarm(0, NULL); - //_xxx_dumpRTC();//XXX return obj; } @@ -139,11 +154,12 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t #if 0 alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); #endif - //_xxx_dumpRTC(); } STATIC void _idle_until_alarm(void) { +#ifdef MY_DEBUGUART int ct = 40; +#endif reset_reason_saved = 0; // Poll for alarms. while (!mp_hal_is_interrupted()) { @@ -151,26 +167,35 @@ STATIC void _idle_until_alarm(void) { // Allow ctrl-C interrupt. if (alarm_woken_from_sleep()) { alarm_save_wake_alarm(); +#ifdef MY_DEBUGUART int cause = _get_wakeup_cause(); - printf("wakeup(%d)\r\n", cause); //XXX + printf("wakeup(%d)\r\n", cause); +#endif return; } port_idle_until_interrupt(); +#ifdef MY_DEBUGUART if (ct > 0) { - printf("_"); --ct; + printf("_"); + --ct; } +#endif } } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t r_obj = mp_const_none; _setup_sleep_alarms(false, n_alarms, alarms); - _debug_print("\r\nsleep..."); +#ifdef MY_DEBUGUART + dbg_printf("\r\nsleep..."); +#endif _idle_until_alarm(); if (mp_hal_is_interrupted()) { - _debug_print("mp_hal_is_interrupted\r\n"); +#ifdef MY_DEBUGUART + dbg_printf("mp_hal_is_interrupted\r\n"); +#endif r_obj = mp_const_none; } else { @@ -185,7 +210,9 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala } void nrf_deep_sleep_start(void) { - _debug_print("go system off..\r\n"); +#ifdef MY_DEBUGUART + dbg_printf("go system off..\r\n"); +#endif sd_power_system_off(); } diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 11652ec828..6fa07bcd29 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -36,6 +36,7 @@ typedef enum { NRF_SLEEP_WAKEUP_TOUCHPAD, NRF_SLEEP_WAKEUP_VBUS, NRF_SLEEP_WAKEUP_RESETPIN, + NRF_SLEEP_WAKEUP_ZZZ } nrf_sleep_source_t; extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 0e0f6c4832..1945beaaf8 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -146,30 +146,40 @@ void _setup2(void) { }; for(size_t i = 0; i < 64; ++i) { uint64_t mask = 1ull << i; +#ifdef MY_DEBUGUART int pull = 0; int sense = 0; +#endif if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { continue; } if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; +#ifdef MY_DEBUGUART pull = -1; sense = 1; +#endif } else if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; +#ifdef MY_DEBUGUART pull = 1; sense = -1; +#endif } else { cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; cfg.pull = NRF_GPIO_PIN_NOPULL; +#ifdef MY_DEBUGUART sense = 9; +#endif } nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, pinalarm_gpiote_handler); nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); - printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); +#ifdef MY_DEBUGUART + dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); +#endif } } @@ -188,7 +198,9 @@ void _setup_pin1_for_deepsleep(void) { for(size_t i = 0; i < 64; ++i) { uint64_t mask = 1ull << i; int pull = 0; +#ifdef MY_DEBUGUART int sense = 0; +#endif if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { continue; } @@ -196,16 +208,22 @@ void _setup_pin1_for_deepsleep(void) { pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); +#ifdef MY_DEBUGUART sense = NRF_GPIO_PIN_SENSE_HIGH; +#endif } else if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); +#ifdef MY_DEBUGUART sense = NRF_GPIO_PIN_SENSE_LOW; +#endif } - printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); +#ifdef MY_DEBUGUART + dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); +#endif } #if 0 uint32_t pin_number = 2; @@ -230,7 +248,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); pin_number = alarm->pin->number; - dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); + //dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); if (alarm->value) { high_alarms |= 1ull << pin_number; high_count++; @@ -251,7 +269,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob } } else { - dbg_printf("alarm_pin_pinalarm_set_alarms() no valid pins\r\n"); + //dbg_printf("alarm_pin_pinalarm_set_alarms() no valid pins\r\n"); } } diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index ab5f29b5db..5564c86c54 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -122,6 +122,26 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } } +extern uint32_t reset_reason_saved; mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + mcu_reset_reason_t r = RESET_REASON_UNKNOWN; + if (reset_reason_saved == 0) { + r = RESET_REASON_POWER_ON; + } + else if (reset_reason_saved & POWER_RESETREAS_RESETPIN_Msk) { + r = RESET_REASON_RESET_PIN; + } + else if (reset_reason_saved & POWER_RESETREAS_DOG_Msk) { + r = RESET_REASON_WATCHDOG; + } + else if (reset_reason_saved & POWER_RESETREAS_SREQ_Msk) { + r = RESET_REASON_SOFTWARE; + } + else if ((reset_reason_saved & POWER_RESETREAS_OFF_Msk) || + (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || + (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || + (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { + r = RESET_REASON_DEEP_SLEEP_ALARM; + } + return r; } diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 3ed822ed76..6e19e7645e 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -114,7 +114,8 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { } } -void _xxx_dumpRTC(void) { +#ifdef MY_DEBUGUART +void dbg_dumpRTC(void) { dbg_printf("\r\nRTC2\r\n"); NRF_RTC_Type *r = rtc_instance.p_reg; dbg_printf("PRESCALER=%08X, ", (int)r->PRESCALER); @@ -125,6 +126,7 @@ void _xxx_dumpRTC(void) { dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); } +#endif void tick_init(void) { if (!nrf_clock_lf_is_running(NRF_CLOCK)) { @@ -178,12 +180,14 @@ safe_mode_t port_init(void) { #endif reset_reason_saved = NRF_POWER->RESETREAS; + // clear all RESET reason bits + NRF_POWER->RESETREAS = reset_reason_saved; // If the board was reset by the WatchDogTimer, we may // need to boot into safe mode. Reset the RESETREAS bit // for the WatchDogTimer so we don't encounter this the // next time we reboot. - if (NRF_POWER->RESETREAS & POWER_RESETREAS_DOG_Msk) { + if (reset_reason_saved & POWER_RESETREAS_DOG_Msk) { NRF_POWER->RESETREAS = POWER_RESETREAS_DOG_Msk; uint32_t usb_reg = NRF_POWER->USBREGSTATUS; diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 2db4c6b2ec..b5d4ef919c 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -74,22 +74,6 @@ void _debug_uart_init(void) { return; } -void _debug_printbuf(char* data) { - int siz, l; - while((l = strlen(data)) != 0) { - if (l <= DBG_PBUF_LEN) { - siz = l; - } - else { - siz = DBG_PBUF_LEN; - } - memcpy(_dbg_pbuf, data, siz); - _dbg_pbuf[siz] = 0; - nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); - data += siz; - } -} - void _debug_print_substr(const char* text, uint32_t length) { char* data = (char*)text; int siz; @@ -108,10 +92,6 @@ void _debug_print_substr(const char* text, uint32_t length) { } } -void _debug_print(const char* s) { - _debug_printbuf((char*)s); -} - void _debug_uart_deinit(void) { nrfx_uarte_uninit(&_dbg_uart_inst); } @@ -164,7 +144,6 @@ void serial_early_init(void) { #ifdef MY_DEBUGUART _debug_uart_init(); _debug_led_init(); - _debug_print("\r\ndebug_uart start\r\n"); #endif } From 41d9d4e0ab2398d2f851269e9771bd0458de8ec5 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 08:17:57 +0900 Subject: [PATCH 04/69] call sd API only when sd enabled. --- ports/nrf/common-hal/alarm/__init__.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 1823bf4649..4fe8432a1f 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -109,6 +109,7 @@ bool alarm_woken_from_sleep(void) { } #ifdef MY_DEBUGUART +#if 0 static const char* cause_str[] = { "UNDEFINED", "GPIO", @@ -118,6 +119,7 @@ static const char* cause_str[] = { "RESETPIN", }; #endif +#endif STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); @@ -209,18 +211,21 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _setup_sleep_alarms(true, n_alarms, alarms); } -void nrf_deep_sleep_start(void) { -#ifdef MY_DEBUGUART - dbg_printf("go system off..\r\n"); -#endif - sd_power_system_off(); -} - void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); //alarm_touch_touchalarm_prepare_for_deep_sleep(); - nrf_deep_sleep_start(); + uint8_t sd_enabled; + sd_softdevice_is_enabled(&sd_enabled); +#ifdef MY_DEBUGUART + dbg_printf("go system off.. %d\r\n", sd_enabled); +#endif + if (sd_enabled) { + sd_power_system_off(); + } + else { + NRF_POWER->SYSTEMOFF = 1; + } // should not reach here.. while(1) ; From 793198909eff7dee17fd79b2f5d6b6eceb1978c9 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 08:19:39 +0900 Subject: [PATCH 05/69] set SleepMemory size to 256 bytes. --- ports/nrf/common-hal/alarm/SleepMemory.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index ea3d40c35a..24fe0065d0 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -29,8 +29,7 @@ #include "py/obj.h" -// not implemented yet -#define SLEEP_MEMORY_LENGTH (4) +#define SLEEP_MEMORY_LENGTH (256) typedef struct { mp_obj_base_t base; From d659c2ce3401c3a33b73d5e6074dd7c93a9deffc Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 09:55:10 +0900 Subject: [PATCH 06/69] move port-specific debug functions from supervisor/shared/serial.c to ports/nrf/supervisor/port.c --- ports/nrf/supervisor/port.c | 78 ++++++++++++++++++++++++++++++++++++- supervisor/serial.h | 1 + supervisor/shared/serial.c | 78 ++----------------------------------- 3 files changed, 80 insertions(+), 77 deletions(-) diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 6e19e7645e..d3c31b51a6 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -77,6 +77,82 @@ static void power_warning_handler(void) { reset_into_safe_mode(BROWNOUT); } +#ifdef MY_DEBUGUART +#include +#include +#include "nrfx.h" +#include "nrf_uart.h" +#include "nrfx_uart.h" +const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); +static int _dbg_uart_initialized = 0; +#define DBG_PBUF_LEN 80 +static char _dbg_pbuf[DBG_PBUF_LEN+1]; + +void _debug_uart_init(void) { + //if (_dbg_uart_initialized) return; + nrfx_uarte_config_t config = { + .pseltxd = 26, + .pselrxd = 15, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UART_BAUDRATE_115200, + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED + } + }; + nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); + // drive config + nrf_gpio_cfg(config.pseltxd, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_PULLUP, // orig=NOPULL + NRF_GPIO_PIN_H0H1, // orig=S0S1 + NRF_GPIO_PIN_NOSENSE); + _dbg_uart_initialized = 1; + return; +} + +void _debug_print_substr(const char* text, uint32_t length) { + char* data = (char*)text; + int siz; + while(length != 0) { + if (length <= DBG_PBUF_LEN) { + siz = length; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + length -= siz; + } +} + +void _debug_uart_deinit(void) { + nrfx_uarte_uninit(&_dbg_uart_inst); +} + +int dbg_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vprintf(fmt, ap); + va_end(ap); + return ret; +} + +extern void _debug_led_init(void); +extern void _debug_led_set(int v); +#else /*!MY_DEBUGUART*/ +int dbg_printf(const char *fmt, ...) { + return 0; +} +#endif + const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(2); const nrfx_rtc_config_t rtc_config = { @@ -149,7 +225,6 @@ void tick_init(void) { } } - safe_mode_t port_init(void) { nrf_peripherals_clocks_init(); @@ -201,7 +276,6 @@ safe_mode_t port_init(void) { return NO_SAFE_MODE; } - void reset_port(void) { #ifdef CIRCUITPY_GAMEPAD_TICKS gamepad_reset(); diff --git a/supervisor/serial.h b/supervisor/serial.h index 6cd8530b36..457ee5336a 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -48,6 +48,7 @@ char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); +// XXX used in nrf52-sleep debug int dbg_printf(const char *fmt, ...)__attribute__((format (printf, 1, 2))); #endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index b5d4ef919c..d2fde39a64 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -37,82 +37,11 @@ #include "tusb.h" #ifdef MY_DEBUGUART -#include -#include -#include "nrfx.h" -#include "nrf_uart.h" -#include "nrfx_uart.h" -const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); -static int _dbg_uart_initialized = 0; -#define DBG_PBUF_LEN 80 -static char _dbg_pbuf[DBG_PBUF_LEN+1]; - -void _debug_uart_init(void) { - //if (_dbg_uart_initialized) return; - nrfx_uarte_config_t config = { - .pseltxd = 26, - .pselrxd = 15, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, - .p_context = NULL, - .baudrate = NRF_UART_BAUDRATE_115200, - .interrupt_priority = 7, - .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED - } - }; - nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); - // drive config - nrf_gpio_cfg(config.pseltxd, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_PULLUP, // orig=NOPULL - NRF_GPIO_PIN_H0H1, // orig=S0S1 - NRF_GPIO_PIN_NOSENSE); - _dbg_uart_initialized = 1; - return; -} - -void _debug_print_substr(const char* text, uint32_t length) { - char* data = (char*)text; - int siz; - while(length != 0) { - if (length <= DBG_PBUF_LEN) { - siz = length; - } - else { - siz = DBG_PBUF_LEN; - } - memcpy(_dbg_pbuf, data, siz); - _dbg_pbuf[siz] = 0; - nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); - data += siz; - length -= siz; - } -} - -void _debug_uart_deinit(void) { - nrfx_uarte_uninit(&_dbg_uart_inst); -} - -int dbg_printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int ret = vprintf(fmt, ap); - va_end(ap); - return ret; -} - -extern void _debug_led_init(void); -extern void _debug_led_set(int v); -#else /*!MY_DEBUGUART*/ -int dbg_printf(const char *fmt, ...) { - return 0; -} +// XXX these functions are in nrf/supervisor/port.c +extern void _debug_uart_init(void); +extern void _debug_print_substr(const char* text, uint32_t length); #endif - /* * Note: DEBUG_UART currently only works on STM32, * enabling on another platform will cause a crash. @@ -143,7 +72,6 @@ void serial_early_init(void) { #ifdef MY_DEBUGUART _debug_uart_init(); - _debug_led_init(); #endif } From 36c59250dde158d8b123ba8c20091fb04b3f5160 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 09:57:14 +0900 Subject: [PATCH 07/69] some cleanups. --- ports/nrf/common-hal/alarm/__init__.c | 34 +++-- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 175 +++++++++++----------- 2 files changed, 107 insertions(+), 102 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 4fe8432a1f..d39c38fe44 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -51,7 +51,8 @@ #include "nrfx.h" #include "nrfx_gpiote.h" - +#if 0 +// XXX #define DEBUG_LED_PIN (NRF_GPIO_PIN_MAP(1, 11)) // P1_11 = LED void _debug_led_init(void) { nrf_gpio_cfg_output(DEBUG_LED_PIN); @@ -59,7 +60,7 @@ void _debug_led_init(void) { void _debug_led_set(int v) { nrf_gpio_pin_write(DEBUG_LED_PIN, v); } - +#endif // Singleton instance of SleepMemory. const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { @@ -84,10 +85,10 @@ STATIC nrf_sleep_source_t _get_wakeup_cause(void) { return NRF_SLEEP_WAKEUP_TIMER; } #if 0 + // XXX not implemented yet if (alarm_touch_touchalarm_woke_us_up()) { return ESP_SLEEP_WAKEUP_TOUCHPAD; } - return esp_sleep_get_wakeup_cause(); #endif if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { return NRF_SLEEP_WAKEUP_RESETPIN; @@ -130,16 +131,16 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { #endif switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { - return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); + return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); } case NRF_SLEEP_WAKEUP_TOUCHPAD: { - return mp_const_none; + return mp_const_none; } case NRF_SLEEP_WAKEUP_GPIO: { - return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); + return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); } default: - break; + break; } return mp_const_none; } @@ -154,6 +155,7 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); #if 0 + // XXX not implemented yet alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); #endif } @@ -170,17 +172,17 @@ STATIC void _idle_until_alarm(void) { if (alarm_woken_from_sleep()) { alarm_save_wake_alarm(); #ifdef MY_DEBUGUART - int cause = _get_wakeup_cause(); - printf("wakeup(%d)\r\n", cause); + int cause = _get_wakeup_cause(); + printf("wakeup(%d)\r\n", cause); #endif return; } port_idle_until_interrupt(); #ifdef MY_DEBUGUART - if (ct > 0) { - printf("_"); - --ct; - } + if (ct > 0) { + printf("_"); + --ct; + } #endif } } @@ -201,8 +203,8 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj r_obj = mp_const_none; } else { - r_obj = _get_wake_alarm(n_alarms, alarms); - alarm_reset(); + r_obj = _get_wake_alarm(n_alarms, alarms); + alarm_reset(); } return r_obj; } @@ -213,7 +215,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - //alarm_touch_touchalarm_prepare_for_deep_sleep(); + //alarm_touch_touchalarm_prepare_for_deep_sleep(); // XXX uint8_t sd_enabled; sd_softdevice_is_enabled(&sd_enabled); diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 1945beaaf8..9ccc79db92 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -78,8 +78,8 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) { static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - ++_pinhandler_gpiote_count; - _pinhandler_ev_pin = pin; + ++_pinhandler_gpiote_count; + _pinhandler_ev_pin = pin; } bool alarm_pin_pinalarm_woke_us_up(void) { @@ -136,93 +136,95 @@ void alarm_pin_pinalarm_reset(void) { pull_pins = 0; } -void _setup2(void) { - nrfx_gpiote_in_config_t cfg = { - .sense = NRF_GPIOTE_POLARITY_TOGGLE, - .pull = NRF_GPIO_PIN_PULLUP, - .is_watcher = false, - .hi_accuracy = true, - .skip_gpio_setup = false - }; - for(size_t i = 0; i < 64; ++i) { - uint64_t mask = 1ull << i; -#ifdef MY_DEBUGUART - int pull = 0; - int sense = 0; -#endif - if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { - continue; +static void setup_pin1_for_lightsleep(void) { + if ( nrfx_gpiote_is_init() ) { + nrfx_gpiote_uninit(); } - if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { - cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; - cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART - pull = -1; sense = 1; -#endif - } - else - if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { - cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; - cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART - pull = 1; sense = -1; -#endif - } - else { - cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; - cfg.pull = NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART - sense = 9; -#endif - } - nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, pinalarm_gpiote_handler); - nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); -#ifdef MY_DEBUGUART - dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); -#endif - } -} + nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); -void _setup_pin1_for_lightsleep(void) { - if ( nrfx_gpiote_is_init() ) { - nrfx_gpiote_uninit(); - } - nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); + _pinhandler_gpiote_count = 0; + _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; - _pinhandler_gpiote_count = 0; - _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; - _setup2(); -} - -void _setup_pin1_for_deepsleep(void) { + nrfx_gpiote_in_config_t cfg = { + .sense = NRF_GPIOTE_POLARITY_TOGGLE, + .pull = NRF_GPIO_PIN_PULLUP, + .is_watcher = false, + .hi_accuracy = true, + .skip_gpio_setup = false + }; for(size_t i = 0; i < 64; ++i) { - uint64_t mask = 1ull << i; - int pull = 0; + uint64_t mask = 1ull << i; #ifdef MY_DEBUGUART - int sense = 0; + int pull = 0; + int sense = 0; #endif - if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { - continue; - } - if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { - pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; - nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); - nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); + if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { + continue; + } + if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { + cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; + cfg.pull = ((pull_pins & mask) != 0) ? + NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; #ifdef MY_DEBUGUART - sense = NRF_GPIO_PIN_SENSE_HIGH; + pull = -1; sense = 1; #endif - } - else - if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { - pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; - nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); - nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); + } + else + if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { + cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; + cfg.pull = ((pull_pins & mask) != 0) ? + NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; #ifdef MY_DEBUGUART - sense = NRF_GPIO_PIN_SENSE_LOW; + pull = 1; sense = -1; #endif - } + } + else { + cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; + cfg.pull = NRF_GPIO_PIN_NOPULL; #ifdef MY_DEBUGUART - dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); + sense = 9; +#endif + } + nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, + pinalarm_gpiote_handler); + nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); +#ifdef MY_DEBUGUART + dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); +#endif + } +} + +static void setup_pin1_for_deepsleep(void) { + for(size_t i = 0; i < 64; ++i) { + uint64_t mask = 1ull << i; + int pull = 0; +#ifdef MY_DEBUGUART + int sense = 0; +#endif + if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { + continue; + } + if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { + pull = ((pull_pins & mask) != 0) ? + NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; + nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); + nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); +#ifdef MY_DEBUGUART + sense = NRF_GPIO_PIN_SENSE_HIGH; +#endif + } + else + if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { + pull = ((pull_pins & mask) != 0) ? + NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; + nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); + nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); +#ifdef MY_DEBUGUART + sense = NRF_GPIO_PIN_SENSE_LOW; +#endif + } +#ifdef MY_DEBUGUART + dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); #endif } #if 0 @@ -261,18 +263,19 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob } } if (pin_number != -1) { - if (!deep_sleep) { - _setup_pin1_for_lightsleep(); - } - else { - //_setup_pin1_for_deepsleep(pin_number); - } + if (!deep_sleep) { + setup_pin1_for_lightsleep(); + } + else { + // we don't setup gpio HW here but do them in + // alarm_pin_pinalarm_prepare_for_deep_sleep() below + } } else { - //dbg_printf("alarm_pin_pinalarm_set_alarms() no valid pins\r\n"); + //dbg_printf("alarm_pin_pinalarm_set_alarms() no valid pins\r\n"); } } void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { - _setup_pin1_for_deepsleep(); + setup_pin1_for_deepsleep(); } From 62b38e273b2aff3c250d3fb87986fba8a199c16d Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 15:37:51 +0900 Subject: [PATCH 08/69] update translation file. --- locale/circuitpython.pot | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0a79520b88..e90883582c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -307,6 +307,10 @@ msgstr "" msgid "Address type out of range" msgstr "" +#: ports/nrf/common-hal/alarm/time/TimeAlarm.c +msgid "Alarm time is too far." +msgstr "" + #: ports/esp32s2/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" @@ -609,6 +613,7 @@ msgid "Cannot output both channels on the same pin" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +#: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." msgstr "" @@ -660,6 +665,7 @@ msgid "Cannot vary frequency on a timer that is already in use" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +#: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." msgstr "" @@ -1066,6 +1072,7 @@ msgid "I2SOut not available" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c +#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" msgstr "" @@ -1251,7 +1258,8 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c #: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c -#: ports/esp32s2/common-hal/touchio/TouchIn.c shared-bindings/pwmio/PWMOut.c +#: ports/esp32s2/common-hal/touchio/TouchIn.c +#: ports/nrf/common-hal/alarm/touch/TouchAlarm.c shared-bindings/pwmio/PWMOut.c #: shared-module/rgbmatrix/RGBMatrix.c msgid "Invalid pin" msgstr "" @@ -1633,10 +1641,12 @@ msgid "" msgstr "" #: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c +#: ports/nrf/common-hal/alarm/touch/TouchAlarm.c msgid "Only one TouchAlarm can be set in deep sleep." msgstr "" #: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c +#: ports/nrf/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set." msgstr "" @@ -3207,6 +3217,7 @@ msgid "invalid syntax for number" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c +#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "io must be rtc io" msgstr "" @@ -3958,6 +3969,7 @@ msgid "trapz is defined for 1D arrays of equal length" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c +#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "trigger level must be 0 or 1" msgstr "" @@ -4100,6 +4112,7 @@ msgid "vectors must have same lengths" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c +#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "wakeup conflict" msgstr "" From 5c858a192562bf854beb2cd9c3c59ce5d8f9da54 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 21 Feb 2021 16:27:21 +0900 Subject: [PATCH 09/69] add weak board_deinit(). --- ports/nrf/supervisor/port.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index d3c31b51a6..264fb81982 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -472,3 +472,9 @@ void HardFault_Handler(void) { asm("nop;"); } } + +#if CIRCUITPY_ALARM +// in case boards/xxx/board.c does not provide board_deinit() +MP_WEAK void board_deinit(void) { +} +#endif From 9df0f439f300f81c28d28473097cb9b897513b2b Mon Sep 17 00:00:00 2001 From: jun2sak Date: Tue, 23 Feb 2021 10:31:49 +0900 Subject: [PATCH 10/69] alarm/pin/__init__.c is no longer used. --- ports/nrf/common-hal/alarm/pin/__init__.c | 34 +++-------------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/ports/nrf/common-hal/alarm/pin/__init__.c b/ports/nrf/common-hal/alarm/pin/__init__.c index d2ce00a3e3..94778f5eb1 100644 --- a/ports/nrf/common-hal/alarm/pin/__init__.c +++ b/ports/nrf/common-hal/alarm/pin/__init__.c @@ -1,38 +1,12 @@ //#include "shared-bindings/alarm_io/__init__.h" -//#include "esp_sleep.h" -//#include "driver/rtc_io.h" +// these are in esp32s2 implementation, +// but not used in nrf -mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { #if 0 - if (!rtc_gpio_is_valid_gpio(self_in->gpio)) { - mp_raise_ValueError(translate("io must be rtc io")); - } - - if (self_in->pull && !self_in->level) { - for (uint8_t i = 0; i<=4; i+=2) { - if (self_in->gpio == i) { - mp_raise_ValueError(translate("IOs 0, 2 & 4 do not support internal pullup in sleep")); - } - } - } - - switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) { - case ESP_ERR_INVALID_ARG: - mp_raise_ValueError(translate("trigger level must be 0 or 1")); - case ESP_ERR_INVALID_STATE: - mp_raise_RuntimeError(translate("wakeup conflict")); - default: - break; - } - - if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); } -#endif - return self_in; +mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { } void common_hal_alarm_io_disable (void) { -#if 0 - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1); -#endif } +#endif From 372c98626a8e0cc7031d89e803a40ecb4746f7da Mon Sep 17 00:00:00 2001 From: jun2sak Date: Tue, 23 Feb 2021 11:56:40 +0900 Subject: [PATCH 11/69] move all the debug codes from port.c to debug_uart.c. --- ports/nrf/Makefile | 4 +- ports/nrf/supervisor/debug_uart.c | 106 ++++++++++++++++++++++++++++++ ports/nrf/supervisor/port.c | 97 +-------------------------- 3 files changed, 110 insertions(+), 97 deletions(-) create mode 100644 ports/nrf/supervisor/debug_uart.c diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index c78a5dc503..6a22e62195 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -95,11 +95,9 @@ else CFLAGS += -flto -flto-partition=none endif -ifeq ($(MY_DBG), 1) - CFLAGS += -DMY_DBG -endif ifeq ($(MY_DEBUGUART), 1) CFLAGS += -DMY_DEBUGUART=1 + SRC_SUPERVISOR += supervisor/debug_uart.c endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c new file mode 100644 index 0000000000..2bd6be39c6 --- /dev/null +++ b/ports/nrf/supervisor/debug_uart.c @@ -0,0 +1,106 @@ +/* + * debug functions + * (will be removed) + */ + +#include +#include +#include +#include + +#ifdef MY_DEBUGUART + +#define DEBUG_UART_TXPIN 26 +#define DEBUG_UART_RXPIN 15 + +#include "nrfx.h" +#include "nrf_uart.h" +#include "nrf_gpio.h" +#include "nrf_rtc.h" +#include "nrfx_uarte.h" +#include "nrfx_rtc.h" +#include "supervisor/serial.h" // dbg_printf() + +extern const nrfx_rtc_t rtc_instance; // port.c +extern volatile int rtc_woke_up_counter; // port.c + +const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); +static int _dbg_uart_initialized = 0; +#define DBG_PBUF_LEN 80 +static char _dbg_pbuf[DBG_PBUF_LEN+1]; + +void _debug_uart_init(void) { + //if (_dbg_uart_initialized) return; + nrfx_uarte_config_t config = { + .pseltxd = DEBUG_UART_TXPIN, + .pselrxd = DEBUG_UART_RXPIN, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UART_BAUDRATE_115200, + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED + } + }; + nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); + // drive config + nrf_gpio_cfg(config.pseltxd, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_PULLUP, // orig=NOPULL + NRF_GPIO_PIN_H0H1, // orig=S0S1 + NRF_GPIO_PIN_NOSENSE); + _dbg_uart_initialized = 1; + return; +} + +void _debug_print_substr(const char* text, uint32_t length) { + char* data = (char*)text; + int siz; + while(length != 0) { + if (length <= DBG_PBUF_LEN) { + siz = length; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + length -= siz; + } +} + +void _debug_uart_deinit(void) { + nrfx_uarte_uninit(&_dbg_uart_inst); +} + +int dbg_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vprintf(fmt, ap); + va_end(ap); + return ret; +} + + +void dbg_dumpRTC(void) { + dbg_printf("\r\nRTC2\r\n"); + NRF_RTC_Type *r = rtc_instance.p_reg; + dbg_printf("PRESCALER=%08X, ", (int)r->PRESCALER); + dbg_printf("COUNTER=%08X ", (int)r->COUNTER); + dbg_printf("INTENSET=%08X ", (int)r->INTENSET); + dbg_printf("EVTENSET=%08X\r\n", (int)r->EVTENSET); + dbg_printf("EVENTS_COMPARE[0..3]=%X,%X,%X,%X ", (int)r->EVENTS_COMPARE[0], (int)r->EVENTS_COMPARE[1], (int)r->EVENTS_COMPARE[2], (int)r->EVENTS_COMPARE[3]); + dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); + dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); +} + +#else /*!MY_DEBUGUART*/ +int dbg_printf(const char *fmt, ...) { + return 0; +} +#endif /*!MY_DEBUGUART*/ diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 264fb81982..d29659bf8d 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -27,10 +27,6 @@ #include #include "supervisor/port.h" #include "supervisor/board.h" -#ifdef MY_DEBUGUART -#include "supervisor/serial.h" // dbg_printf() -extern void _debug_uart_init(void); -#endif #include "nrfx/hal/nrf_clock.h" #include "nrfx/hal/nrf_power.h" @@ -78,82 +74,12 @@ static void power_warning_handler(void) { } #ifdef MY_DEBUGUART -#include -#include -#include "nrfx.h" -#include "nrf_uart.h" -#include "nrfx_uart.h" -const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); -static int _dbg_uart_initialized = 0; -#define DBG_PBUF_LEN 80 -static char _dbg_pbuf[DBG_PBUF_LEN+1]; - -void _debug_uart_init(void) { - //if (_dbg_uart_initialized) return; - nrfx_uarte_config_t config = { - .pseltxd = 26, - .pselrxd = 15, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, - .p_context = NULL, - .baudrate = NRF_UART_BAUDRATE_115200, - .interrupt_priority = 7, - .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED - } - }; - nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); - // drive config - nrf_gpio_cfg(config.pseltxd, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_PULLUP, // orig=NOPULL - NRF_GPIO_PIN_H0H1, // orig=S0S1 - NRF_GPIO_PIN_NOSENSE); - _dbg_uart_initialized = 1; - return; -} - -void _debug_print_substr(const char* text, uint32_t length) { - char* data = (char*)text; - int siz; - while(length != 0) { - if (length <= DBG_PBUF_LEN) { - siz = length; - } - else { - siz = DBG_PBUF_LEN; - } - memcpy(_dbg_pbuf, data, siz); - _dbg_pbuf[siz] = 0; - nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); - data += siz; - length -= siz; - } -} - -void _debug_uart_deinit(void) { - nrfx_uarte_uninit(&_dbg_uart_inst); -} - -int dbg_printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - int ret = vprintf(fmt, ap); - va_end(ap); - return ret; -} - -extern void _debug_led_init(void); -extern void _debug_led_set(int v); -#else /*!MY_DEBUGUART*/ -int dbg_printf(const char *fmt, ...) { - return 0; -} +extern void _debug_uart_init(void); #endif +uint32_t reset_reason_saved = 0; const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(2); +volatile int rtc_woke_up_counter = 0; const nrfx_rtc_config_t rtc_config = { .prescaler = RTC_FREQ_TO_PRESCALER(0x8000), @@ -170,9 +96,6 @@ static volatile struct { uint32_t suffix; } overflow_tracker __attribute__((section(".uninitialized"))); -uint32_t reset_reason_saved = 0; -volatile int rtc_woke_up_counter = 0; - void rtc_handler(nrfx_rtc_int_type_t int_type) { if (int_type == NRFX_RTC_INT_OVERFLOW) { // Our RTC is 24 bits and we're clocking it at 32.768khz which is 32 (2 ** 5) subticks per @@ -190,20 +113,6 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { } } -#ifdef MY_DEBUGUART -void dbg_dumpRTC(void) { - dbg_printf("\r\nRTC2\r\n"); - NRF_RTC_Type *r = rtc_instance.p_reg; - dbg_printf("PRESCALER=%08X, ", (int)r->PRESCALER); - dbg_printf("COUNTER=%08X ", (int)r->COUNTER); - dbg_printf("INTENSET=%08X ", (int)r->INTENSET); - dbg_printf("EVTENSET=%08X\r\n", (int)r->EVTENSET); - dbg_printf("EVENTS_COMPARE[0..3]=%X,%X,%X,%X ", (int)r->EVENTS_COMPARE[0], (int)r->EVENTS_COMPARE[1], (int)r->EVENTS_COMPARE[2], (int)r->EVENTS_COMPARE[3]); - dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); - dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); -} -#endif - void tick_init(void) { if (!nrf_clock_lf_is_running(NRF_CLOCK)) { nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART); From ec64fa6a291d2f7449f6ef1fc0313b53a889a6aa Mon Sep 17 00:00:00 2001 From: jun2sak Date: Tue, 23 Feb 2021 12:16:37 +0900 Subject: [PATCH 12/69] move dump_xxx functions to debug_uart.c. --- main.c | 10 ++++------ ports/nrf/common-hal/alarm/SleepMemory.c | 22 +++++----------------- ports/nrf/common-hal/alarm/__init__.c | 11 ----------- ports/nrf/supervisor/debug_uart.c | 22 +++++++++++++++++++++- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/main.c b/main.c index 2a256f5b5d..0ca6684356 100755 --- a/main.c +++ b/main.c @@ -588,12 +588,10 @@ int __attribute__((used)) main(void) { serial_init(); #if 0 //XXX - int rr = (int)common_hal_mcu_processor_get_reset_reason(); - const char* rrstr[] = { - "POWER_ON", "BROWNOUT", "SOFTWARE", "DEEPSLEEPALARM", - "RESET_PIN", "WATCHDOG", "UNKNOWN" - }; - dbg_printf("reset_reason=%s\r\n", rrstr[rr]); + { + extern void dbg_dump_reset_reason(void); + dbg_dump_reset_reason(); + } #endif #if CIRCUITPY_BLEIO diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index a867b17b13..62afd37379 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -47,26 +47,15 @@ static int is_sleep_memory_valid(void) { return 0; } -static void dumpRAMreg(void) { -#ifdef MY_DEBUGUART - int i; - for(i = 0; i <= 8; ++i) { - dbg_printf(" RAM%d:%08X", i, (int)(NRF_POWER->RAM[i].POWER)); - if (i==4) dbg_printf("\r\n"); - } - dbg_printf("\r\n"); -#endif -} - +extern void dbg_dump_RAMreg(void); static void initialize_sleep_memory(void) { memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); // also, set RAM[n].POWER register for RAM retention // nRF52840 has RAM[0..7].Section[0..1] and RAM[8].Section[0..5] // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] - dumpRAMreg(); for(int ram = 0; ram <= 7; ++ram) { - NRF_POWER->RAM[ram].POWERSET = 0x00030000; // RETENTION for section 0,1 + NRF_POWER->RAM[ram].POWERSET = 0x00030000; // RETENTION for section 0,1 }; #ifdef NRF52840 NRF_POWER->RAM[8].POWERSET = 0x001F0000; // RETENTION for section 0..5 @@ -74,7 +63,9 @@ static void initialize_sleep_memory(void) { #ifdef NRF52833 NRF_POWER->RAM[8].POWERSET = 0x00030000; // RETENTION for section 0,1 #endif - dumpRAMreg(); +#ifdef MY_DEBUGUART + dbg_dump_RAMreg(); +#endif _sleep_mem_magicnum = SLEEP_MEMORY_DATA_GUARD; } @@ -82,9 +73,6 @@ static void initialize_sleep_memory(void) { void alarm_sleep_memory_reset(void) { if (!is_sleep_memory_valid()) { initialize_sleep_memory(); -#ifdef MY_DEBUGUART - dbg_printf("_sleep_mem[] initialized\r\n"); -#endif } } diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index d39c38fe44..dfdcb76889 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -51,17 +51,6 @@ #include "nrfx.h" #include "nrfx_gpiote.h" -#if 0 -// XXX -#define DEBUG_LED_PIN (NRF_GPIO_PIN_MAP(1, 11)) // P1_11 = LED -void _debug_led_init(void) { - nrf_gpio_cfg_output(DEBUG_LED_PIN); -} -void _debug_led_set(int v) { - nrf_gpio_pin_write(DEBUG_LED_PIN, v); -} -#endif - // Singleton instance of SleepMemory. const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { .base = { diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index 2bd6be39c6..53a3baebf9 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -20,9 +20,11 @@ #include "nrfx_uarte.h" #include "nrfx_rtc.h" #include "supervisor/serial.h" // dbg_printf() +#include "shared-bindings/microcontroller/Processor.h" extern const nrfx_rtc_t rtc_instance; // port.c extern volatile int rtc_woke_up_counter; // port.c +extern uint32_t reset_reason_saved; const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); static int _dbg_uart_initialized = 0; @@ -87,7 +89,7 @@ int dbg_printf(const char *fmt, ...) { } -void dbg_dumpRTC(void) { +void dbg_dump_RTCreg(void) { dbg_printf("\r\nRTC2\r\n"); NRF_RTC_Type *r = rtc_instance.p_reg; dbg_printf("PRESCALER=%08X, ", (int)r->PRESCALER); @@ -99,6 +101,24 @@ void dbg_dumpRTC(void) { dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); } +void dbg_dump_RAMreg(void) { + int i; + for(i = 0; i <= 8; ++i) { + dbg_printf(" RAM%d:%08X", i, (int)(NRF_POWER->RAM[i].POWER)); + if (i==4) dbg_printf("\r\n"); + } + dbg_printf("\r\n"); +} + +void dbg_dump_reset_reason(void) { + int reset_reason = (int)common_hal_mcu_processor_get_reset_reason(); + const char* rr_str[] = { + "POWER_ON", "BROWNOUT", "SOFTWARE", "DEEPSLEEPALARM", + "RESET_PIN", "WATCHDOG", "UNKNOWN" + }; + dbg_printf("reset_reason=%s\r\n", rr_str[reset_reason]); +} + #else /*!MY_DEBUGUART*/ int dbg_printf(const char *fmt, ...) { return 0; From 105042e870529092113ecfee24d8790a21f45f7b Mon Sep 17 00:00:00 2001 From: jun2sak Date: Tue, 23 Feb 2021 12:22:33 +0900 Subject: [PATCH 13/69] move dump_xxx functions to debug_uart.c. --- supervisor/shared/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 832242214a..262fe706bd 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -37,7 +37,7 @@ #include "tusb.h" #ifdef MY_DEBUGUART -// XXX these functions are in nrf/supervisor/port.c +// XXX these functions are in nrf/supervisor/debug_uart.c extern void _debug_uart_init(void); extern void _debug_print_substr(const char* text, uint32_t length); #endif From 0f188befb6c115ad9bee9dee80ae47840cb560ab Mon Sep 17 00:00:00 2001 From: jun2sak Date: Wed, 24 Feb 2021 00:12:25 +0900 Subject: [PATCH 14/69] set RAM retention just before deep sleep --- ports/nrf/common-hal/alarm/SleepMemory.c | 21 ++++++++++++--------- ports/nrf/common-hal/alarm/__init__.c | 5 +++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 62afd37379..89430f2937 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -26,13 +26,13 @@ */ #include -#ifdef MY_DEBUGUART -#include "supervisor/serial.h" // dbg_printf() -#endif - #include "py/runtime.h" #include "common-hal/alarm/SleepMemory.h" +#ifdef MY_DEBUGUART +extern void dbg_dump_RAMreg(void); +#endif + #define RTC_DATA_ATTR __attribute__((section(".uninitialized"))) static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; static RTC_DATA_ATTR uint32_t _sleep_mem_magicnum; @@ -47,11 +47,8 @@ static int is_sleep_memory_valid(void) { return 0; } -extern void dbg_dump_RAMreg(void); -static void initialize_sleep_memory(void) { - memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); - - // also, set RAM[n].POWER register for RAM retention +void set_memory_retention(void) { + // set RAM[n].POWER register for RAM retention // nRF52840 has RAM[0..7].Section[0..1] and RAM[8].Section[0..5] // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] for(int ram = 0; ram <= 7; ++ram) { @@ -63,6 +60,12 @@ static void initialize_sleep_memory(void) { #ifdef NRF52833 NRF_POWER->RAM[8].POWERSET = 0x00030000; // RETENTION for section 0,1 #endif +} + +static void initialize_sleep_memory(void) { + memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); + + set_memory_retention(); #ifdef MY_DEBUGUART dbg_dump_RAMreg(); #endif diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index dfdcb76889..14f6e041f9 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -202,12 +202,17 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _setup_sleep_alarms(true, n_alarms, alarms); } +extern void set_memory_retention(void); + void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); //alarm_touch_touchalarm_prepare_for_deep_sleep(); // XXX uint8_t sd_enabled; sd_softdevice_is_enabled(&sd_enabled); + + set_memory_retention(); + #ifdef MY_DEBUGUART dbg_printf("go system off.. %d\r\n", sd_enabled); #endif From 057682f776c52500cfbbdd5f7fbe70d4010d1ad1 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Wed, 24 Feb 2021 00:13:11 +0900 Subject: [PATCH 15/69] cleanup. --- main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 0ca6684356..d6ad3ac2c1 100755 --- a/main.c +++ b/main.c @@ -537,6 +537,10 @@ STATIC int run_repl(void) { return exit_code; } +#ifdef MY_DEBUGUART +extern void dbg_dump_reset_reason(void); +#endif + int __attribute__((used)) main(void) { // initialise the cpu and peripherals safe_mode_t safe_mode = port_init(); @@ -589,7 +593,6 @@ int __attribute__((used)) main(void) { #if 0 //XXX { - extern void dbg_dump_reset_reason(void); dbg_dump_reset_reason(); } #endif From 72b5f1a9a62d05330571f0e8e4bf0c5f1ffe0d7a Mon Sep 17 00:00:00 2001 From: jun2sak Date: Thu, 25 Feb 2021 01:38:23 +0900 Subject: [PATCH 16/69] clean up my personal settings. --- .gitignore | 6 ------ ports/nrf/Makefile | 1 - 2 files changed, 7 deletions(-) diff --git a/.gitignore b/.gitignore index 6f27970f89..a8814be45e 100644 --- a/.gitignore +++ b/.gitignore @@ -86,9 +86,3 @@ TAGS #################### .venv .env - -1FILES -2FILES -TAG -ports/nrf/LOG*.txt -ports/nrf/boards/pg8c diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 6a22e62195..d48b788cba 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -87,7 +87,6 @@ INC += -I../../supervisor/shared/usb #Debugging/Optimization ifeq ($(DEBUG), 1) CFLAGS += -ggdb3 - CFLAGS += -DNDEBUG OPTIMIZATION_FLAGS = -Og else OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions From 9661d67cd37964afe66fdfced5620ac8c0c195bc Mon Sep 17 00:00:00 2001 From: jun2sak Date: Thu, 25 Feb 2021 01:49:57 +0900 Subject: [PATCH 17/69] replace MY_DEBUG_UART -> NRF_DEBUG_PRINT. --- main.c | 2 +- ports/nrf/Makefile | 4 ++-- ports/nrf/common-hal/alarm/SleepMemory.c | 4 ++-- ports/nrf/common-hal/alarm/__init__.c | 16 ++++++++-------- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 18 +++++++++--------- ports/nrf/supervisor/debug_uart.c | 6 +++--- ports/nrf/supervisor/port.c | 4 ++-- supervisor/shared/serial.c | 8 ++++---- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index d6ad3ac2c1..c15d5810b0 100755 --- a/main.c +++ b/main.c @@ -537,7 +537,7 @@ STATIC int run_repl(void) { return exit_code; } -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT extern void dbg_dump_reset_reason(void); #endif diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index d48b788cba..8925189f56 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -94,8 +94,8 @@ else CFLAGS += -flto -flto-partition=none endif -ifeq ($(MY_DEBUGUART), 1) - CFLAGS += -DMY_DEBUGUART=1 +ifeq ($(NRF_DEBUG_PRINT), 1) + CFLAGS += -DNRF_DEBUG_PRINT=1 SRC_SUPERVISOR += supervisor/debug_uart.c endif diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 89430f2937..fc7453beb4 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -29,7 +29,7 @@ #include "py/runtime.h" #include "common-hal/alarm/SleepMemory.h" -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT extern void dbg_dump_RAMreg(void); #endif @@ -66,7 +66,7 @@ static void initialize_sleep_memory(void) { memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); set_memory_retention(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_dump_RAMreg(); #endif diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 14f6e041f9..9c64e8e119 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -42,7 +42,7 @@ //#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/port.h" -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT #include "supervisor/serial.h" // dbg_printf() #endif @@ -98,7 +98,7 @@ bool alarm_woken_from_sleep(void) { || cause == NRF_SLEEP_WAKEUP_RESETPIN); } -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT #if 0 static const char* cause_str[] = { "UNDEFINED", @@ -150,7 +150,7 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t } STATIC void _idle_until_alarm(void) { -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT int ct = 40; #endif reset_reason_saved = 0; @@ -160,14 +160,14 @@ STATIC void _idle_until_alarm(void) { // Allow ctrl-C interrupt. if (alarm_woken_from_sleep()) { alarm_save_wake_alarm(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT int cause = _get_wakeup_cause(); printf("wakeup(%d)\r\n", cause); #endif return; } port_idle_until_interrupt(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT if (ct > 0) { printf("_"); --ct; @@ -179,14 +179,14 @@ STATIC void _idle_until_alarm(void) { mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t r_obj = mp_const_none; _setup_sleep_alarms(false, n_alarms, alarms); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_printf("\r\nsleep..."); #endif _idle_until_alarm(); if (mp_hal_is_interrupted()) { -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_printf("mp_hal_is_interrupted\r\n"); #endif r_obj = mp_const_none; @@ -213,7 +213,7 @@ void NORETURN alarm_enter_deep_sleep(void) { set_memory_retention(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_printf("go system off.. %d\r\n", sd_enabled); #endif if (sd_enabled) { diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 9ccc79db92..bdc268d512 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -154,7 +154,7 @@ static void setup_pin1_for_lightsleep(void) { }; for(size_t i = 0; i < 64; ++i) { uint64_t mask = 1ull << i; -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT int pull = 0; int sense = 0; #endif @@ -165,7 +165,7 @@ static void setup_pin1_for_lightsleep(void) { cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT pull = -1; sense = 1; #endif } @@ -174,21 +174,21 @@ static void setup_pin1_for_lightsleep(void) { cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT pull = 1; sense = -1; #endif } else { cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; cfg.pull = NRF_GPIO_PIN_NOPULL; -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT sense = 9; #endif } nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, pinalarm_gpiote_handler); nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); #endif } @@ -198,7 +198,7 @@ static void setup_pin1_for_deepsleep(void) { for(size_t i = 0; i < 64; ++i) { uint64_t mask = 1ull << i; int pull = 0; -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT int sense = 0; #endif if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { @@ -209,7 +209,7 @@ static void setup_pin1_for_deepsleep(void) { NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT sense = NRF_GPIO_PIN_SENSE_HIGH; #endif } @@ -219,11 +219,11 @@ static void setup_pin1_for_deepsleep(void) { NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT sense = NRF_GPIO_PIN_SENSE_LOW; #endif } -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); #endif } diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index 53a3baebf9..79cc33b198 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -8,7 +8,7 @@ #include #include -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT #define DEBUG_UART_TXPIN 26 #define DEBUG_UART_RXPIN 15 @@ -119,8 +119,8 @@ void dbg_dump_reset_reason(void) { dbg_printf("reset_reason=%s\r\n", rr_str[reset_reason]); } -#else /*!MY_DEBUGUART*/ +#else /*!NRF_DEBUG_PRINT*/ int dbg_printf(const char *fmt, ...) { return 0; } -#endif /*!MY_DEBUGUART*/ +#endif /*!NRF_DEBUG_PRINT*/ diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index d29659bf8d..5908683008 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -73,7 +73,7 @@ static void power_warning_handler(void) { reset_into_safe_mode(BROWNOUT); } -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT extern void _debug_uart_init(void); #endif @@ -234,7 +234,7 @@ void reset_port(void) { reset_all_pins(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT _debug_uart_init(); #endif } diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 262fe706bd..479a996553 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -36,7 +36,7 @@ #include "tusb.h" -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT // XXX these functions are in nrf/supervisor/debug_uart.c extern void _debug_uart_init(void); extern void _debug_print_substr(const char* text, uint32_t length); @@ -70,14 +70,14 @@ void serial_early_init(void) { common_hal_busio_uart_never_reset(&debug_uart); #endif -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT _debug_uart_init(); #endif } void serial_init(void) { usb_init(); -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT _debug_uart_init(); #endif } @@ -157,7 +157,7 @@ void serial_write_substring(const char* text, uint32_t length) { common_hal_busio_uart_write(&debug_uart, (const uint8_t*) text, length, &uart_errcode); #endif -#ifdef MY_DEBUGUART +#ifdef NRF_DEBUG_PRINT _debug_print_substr(text, length); #endif } From f66896ce32351e0992d6d3417d1a8af1038c5d4b Mon Sep 17 00:00:00 2001 From: jun2sak Date: Thu, 25 Feb 2021 02:34:43 +0900 Subject: [PATCH 18/69] use nRF SDK function to set up memory retention. --- ports/nrf/common-hal/alarm/SleepMemory.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index fc7453beb4..e78e9fdd76 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -28,6 +28,7 @@ #include #include "py/runtime.h" #include "common-hal/alarm/SleepMemory.h" +#include "nrf_power.h" #ifdef NRF_DEBUG_PRINT extern void dbg_dump_RAMreg(void); @@ -51,14 +52,24 @@ void set_memory_retention(void) { // set RAM[n].POWER register for RAM retention // nRF52840 has RAM[0..7].Section[0..1] and RAM[8].Section[0..5] // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] - for(int ram = 0; ram <= 7; ++ram) { - NRF_POWER->RAM[ram].POWERSET = 0x00030000; // RETENTION for section 0,1 + for(int block = 0; block <= 7; ++block) { + nrf_power_rampower_mask_on(NRF_POWER, block, + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); }; #ifdef NRF52840 - NRF_POWER->RAM[8].POWERSET = 0x001F0000; // RETENTION for section 0..5 + nrf_power_rampower_mask_on(NRF_POWER, 8, + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK | + NRF_POWER_RAMPOWER_S2RETENTION_MASK | + NRF_POWER_RAMPOWER_S3RETENTION_MASK | + NRF_POWER_RAMPOWER_S4RETENTION_MASK | + NRF_POWER_RAMPOWER_S5RETENTION_MASK); #endif #ifdef NRF52833 - NRF_POWER->RAM[8].POWERSET = 0x00030000; // RETENTION for section 0,1 + nrf_power_rampower_mask_on(NRF_POWER, 8, + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); #endif } From 61a69daae1fd6460b830b7fd6707c74adbcd3f23 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Thu, 25 Feb 2021 08:19:03 +0900 Subject: [PATCH 19/69] raise NotImplementedError when construct TouchAlarm. --- ports/nrf/common-hal/alarm/touch/TouchAlarm.c | 142 +----------------- 1 file changed, 5 insertions(+), 137 deletions(-) diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c index 4db178c56e..1878b78b33 100644 --- a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c @@ -24,162 +24,30 @@ * THE SOFTWARE. */ +#include "py/runtime.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" #include "shared-bindings/microcontroller/__init__.h" -//#include "esp_sleep.h" -//#include "peripherals/touch.h" -//#include "supervisor/esp_port.h" - -static uint16_t touch_channel_mask; static volatile bool woke_up = false; void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { -#if 0 - if (pin->touch_channel == TOUCH_PAD_MAX) { - mp_raise_ValueError(translate("Invalid pin")); - } - claim_pin(pin); -#endif - self->pin = pin; + mp_raise_NotImplementedError(NULL); + (void)pin; } mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) { - // First, check to see if we match any given alarms. - for (size_t i = 0; i < n_alarms; i++) { - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { - return alarms[i]; - } - } - - // Create TouchAlarm object. - alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t); - alarm->base.type = &alarm_touch_touchalarm_type; - alarm->pin = NULL; -#if 0 - touch_pad_t wake_channel = touch_pad_get_current_meas_channel(); - if (wake_channel == TOUCH_PAD_MAX) { - return alarm; - } - - // Map the pin number back to a pin object. - for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { - const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); - if (pin_obj->touch_channel == wake_channel) { - alarm->pin = mcu_pin_globals.map.table[i].value; - break; - } - } -#endif - return alarm; -} - -// This is used to wake the main CircuitPython task. -void touch_interrupt(void *arg) { - (void) arg; -#if 0 - woke_up = true; - BaseType_t task_wakeup; - vTaskNotifyGiveFromISR(circuitpython_task, &task_wakeup); - if (task_wakeup) { - portYIELD_FROM_ISR(); - } -#endif + return mp_const_none; } void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { -#if 0 - bool touch_alarm_set = false; - alarm_touch_touchalarm_obj_t *touch_alarm = MP_OBJ_NULL; - - for (size_t i = 0; i < n_alarms; i++) { - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { - if (deep_sleep && touch_alarm_set) { - mp_raise_ValueError(translate("Only one TouchAlarm can be set in deep sleep.")); - } - touch_alarm = MP_OBJ_TO_PTR(alarms[i]); - touch_channel_mask |= 1 << touch_alarm->pin->number; - touch_alarm_set = true; - } - } - - if (!touch_alarm_set) { - return; - } - - // configure interrupt for pretend to deep sleep - // this will be disabled if we actually deep sleep - - // reset touch peripheral - peripherals_touch_reset(); - peripherals_touch_never_reset(true); - - for (uint8_t i = 1; i <= 14; i++) { - if ((touch_channel_mask & 1 << i) != 0) { - touch_pad_t touch_channel = (touch_pad_t)i; - // intialize touchpad - peripherals_touch_init(touch_channel); - - // wait for touch data to reset - mp_hal_delay_ms(10); - - // configure trigger threshold - uint32_t touch_value; - touch_pad_read_benchmark(touch_channel, &touch_value); - touch_pad_set_thresh(touch_channel, touch_value * 0.1); //10% - } - } - - // configure touch interrupt - touch_pad_timeout_set(true, SOC_TOUCH_PAD_THRESHOLD_MAX); - touch_pad_isr_register(touch_interrupt, NULL, TOUCH_PAD_INTR_MASK_ALL); - touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); } void alarm_touch_touchalarm_prepare_for_deep_sleep(void) { - if (!touch_channel_mask) { - return; - } - - touch_pad_t touch_channel = TOUCH_PAD_MAX; - for (uint8_t i = 1; i <= 14; i++) { - if ((touch_channel_mask & 1 << i) != 0) { - touch_channel = (touch_pad_t)i; - break; - } - } - - // reset touch peripheral - peripherals_touch_never_reset(false); - peripherals_touch_reset(); - - // intialize touchpad - peripherals_touch_init(touch_channel); - - // configure touchpad for sleep - touch_pad_sleep_channel_enable(touch_channel, true); - touch_pad_sleep_channel_enable_proximity(touch_channel, false); - - // wait for touch data to reset - mp_hal_delay_ms(10); - - // configure trigger threshold - uint32_t touch_value; - touch_pad_sleep_channel_read_smooth(touch_channel, &touch_value); - touch_pad_sleep_set_threshold(touch_channel, touch_value * 0.1); //10% - - // enable touchpad wakeup - esp_sleep_enable_touchpad_wakeup(); - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); -#endif } bool alarm_touch_touchalarm_woke_us_up(void) { - return woke_up; + return false; } void alarm_touch_touchalarm_reset(void) { - woke_up = false; - touch_channel_mask = 0; -// peripherals_touch_never_reset(false); } From 9328d09a7a7a3cddc1ca0c346c781f3cb55203ee Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 00:50:44 +0900 Subject: [PATCH 20/69] re-enable parameters check. --- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 7 ++----- ports/nrf/common-hal/alarm/pin/__init__.c | 12 ------------ 2 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 ports/nrf/common-hal/alarm/pin/__init__.c diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index bdc268d512..606a7125fa 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -46,15 +46,12 @@ volatile nrfx_gpiote_pin_t _pinhandler_ev_pin; #define MYGPIOTE_EV_PIN_UNDEF 0xFF void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { -#if 0 if (edge) { mp_raise_ValueError(translate("Cannot wake on pin edge. Only level.")); } - - if (pull && !GPIO_IS_VALID_OUTPUT_GPIO(pin->number)) { - mp_raise_ValueError(translate("Cannot pull on input-only pin.")); + if (pin->number >= NUMBER_OF_PINS) { + mp_raise_ValueError(translate("Invalid pin")); } -#endif self->pin = pin; self->value = value; self->pull = pull; diff --git a/ports/nrf/common-hal/alarm/pin/__init__.c b/ports/nrf/common-hal/alarm/pin/__init__.c deleted file mode 100644 index 94778f5eb1..0000000000 --- a/ports/nrf/common-hal/alarm/pin/__init__.c +++ /dev/null @@ -1,12 +0,0 @@ -//#include "shared-bindings/alarm_io/__init__.h" - -// these are in esp32s2 implementation, -// but not used in nrf - -#if 0 -mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { -} - -void common_hal_alarm_io_disable (void) { -} -#endif From c86ca2a4ff7e23feeb77fbbfcee1a9ea61178851 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 00:51:52 +0900 Subject: [PATCH 21/69] move externs to .h --- ports/nrf/common-hal/alarm/time/TimeAlarm.c | 4 ---- ports/nrf/common-hal/alarm/time/TimeAlarm.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index 220ed2f4df..2a9a0fcd33 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -55,19 +55,15 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * return timer; } -extern volatile int rtc_woke_up_counter; bool alarm_time_timealarm_woke_us_up(void) { return rtc_woke_up_counter; } -extern void port_disable_interrupt_after_ticks_ch(uint32_t channel); void alarm_time_timealarm_reset(void) { port_disable_interrupt_after_ticks_ch(1); rtc_woke_up_counter = 0; } -extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks);//XXX in port.c - void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { bool timealarm_set = false; alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL; diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index dfd75524fd..14a2ff80cf 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -32,6 +32,10 @@ typedef struct { mp_float_t monotonic_time; // values compatible with time.monotonic_time() } alarm_time_timealarm_obj_t; +extern volatile int rtc_woke_up_counter; +extern void port_disable_interrupt_after_ticks_ch(uint32_t channel); +extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks); + // Find the alarm object that caused us to wake up or create an equivalent one. mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms); // Check for the wake up alarm from pretend deep sleep. From c713d31d0d77e461c97efa95229467e311b7e35b Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 01:20:55 +0900 Subject: [PATCH 22/69] move externs to .h --- ports/nrf/common-hal/microcontroller/Processor.c | 1 - ports/nrf/common-hal/microcontroller/Processor.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index 5564c86c54..edff0fa076 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -122,7 +122,6 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } } -extern uint32_t reset_reason_saved; mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { mcu_reset_reason_t r = RESET_REASON_UNKNOWN; if (reset_reason_saved == 0) { diff --git a/ports/nrf/common-hal/microcontroller/Processor.h b/ports/nrf/common-hal/microcontroller/Processor.h index 4049c165fb..1abbe1e4eb 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.h +++ b/ports/nrf/common-hal/microcontroller/Processor.h @@ -36,4 +36,6 @@ typedef struct { // Stores no state currently. } mcu_processor_obj_t; +extern uint32_t reset_reason_saved; + #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H From 5b3c6ed0c3cb923a597da1221cb4386f033bb741 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 01:28:13 +0900 Subject: [PATCH 23/69] update translation file. --- locale/circuitpython.pot | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index e90883582c..dc0ec9fb7e 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -613,7 +613,6 @@ msgid "Cannot output both channels on the same pin" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c -#: ports/nrf/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." msgstr "" @@ -1072,7 +1071,6 @@ msgid "I2SOut not available" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c -#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" msgstr "" @@ -1259,7 +1257,7 @@ msgstr "" #: ports/atmel-samd/common-hal/touchio/TouchIn.c #: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c #: ports/esp32s2/common-hal/touchio/TouchIn.c -#: ports/nrf/common-hal/alarm/touch/TouchAlarm.c shared-bindings/pwmio/PWMOut.c +#: ports/nrf/common-hal/alarm/pin/PinAlarm.c shared-bindings/pwmio/PWMOut.c #: shared-module/rgbmatrix/RGBMatrix.c msgid "Invalid pin" msgstr "" @@ -1641,7 +1639,6 @@ msgid "" msgstr "" #: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c -#: ports/nrf/common-hal/alarm/touch/TouchAlarm.c msgid "Only one TouchAlarm can be set in deep sleep." msgstr "" @@ -3217,7 +3214,6 @@ msgid "invalid syntax for number" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c -#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "io must be rtc io" msgstr "" @@ -3969,7 +3965,6 @@ msgid "trapz is defined for 1D arrays of equal length" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c -#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "trigger level must be 0 or 1" msgstr "" @@ -4112,7 +4107,6 @@ msgid "vectors must have same lengths" msgstr "" #: ports/esp32s2/common-hal/alarm/pin/__init__.c -#: ports/nrf/common-hal/alarm/pin/__init__.c msgid "wakeup conflict" msgstr "" From 2aa5aec0d5b9c3b9c11ecf0f1d728cc7891f0ca6 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 01:45:12 +0900 Subject: [PATCH 24/69] cleanup. --- ports/nrf/common-hal/alarm/__init__.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 9c64e8e119..c719deb876 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -38,9 +38,6 @@ #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" -//#include "shared-bindings/wifi/__init__.h" -//#include "shared-bindings/microcontroller/__init__.h" - #include "supervisor/port.h" #ifdef NRF_DEBUG_PRINT #include "supervisor/serial.h" // dbg_printf() @@ -73,12 +70,9 @@ STATIC nrf_sleep_source_t _get_wakeup_cause(void) { if (alarm_time_timealarm_woke_us_up()) { return NRF_SLEEP_WAKEUP_TIMER; } -#if 0 - // XXX not implemented yet if (alarm_touch_touchalarm_woke_us_up()) { - return ESP_SLEEP_WAKEUP_TOUCHPAD; + return NRF_SLEEP_WAKEUP_TOUCHPAD; } -#endif if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { return NRF_SLEEP_WAKEUP_RESETPIN; } @@ -99,7 +93,6 @@ bool alarm_woken_from_sleep(void) { } #ifdef NRF_DEBUG_PRINT -#if 0 static const char* cause_str[] = { "UNDEFINED", "GPIO", @@ -108,15 +101,18 @@ static const char* cause_str[] = { "VBUS", "RESETPIN", }; -#endif +void print_wakeup_cause(nrf_sleep_source_t cause) { + if (cause >= 0 && cause < NRF_SLEEP_WAKEUP_ZZZ) { + dbg_printf("wakeup cause = NRF_SLEEP_WAKEUP_%s\r\n", + cause_str[(int)cause]); + } +} #endif STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); -#if 0 - if (cause >= 0 && cause < NRF_SLEEP_WAKEUP_ZZZ) { - printf("wakeup cause = NRF_SLEEP_WAKEUP_%s\r\n", cause_str[(int)cause]); - } +#ifdef NRF_DEBUG_PRINT + //print_wakeup_cause(cause); #endif switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { @@ -143,10 +139,7 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); -#if 0 - // XXX not implemented yet alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); -#endif } STATIC void _idle_until_alarm(void) { @@ -206,7 +199,7 @@ extern void set_memory_retention(void); void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - //alarm_touch_touchalarm_prepare_for_deep_sleep(); // XXX + //alarm_touch_touchalarm_prepare_for_deep_sleep(); uint8_t sd_enabled; sd_softdevice_is_enabled(&sd_enabled); From 277a67d8767b6b297bc0ce375c44bf3fdd38c617 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 08:11:50 +0900 Subject: [PATCH 25/69] call touchalarm funcs as well as pin/timealarm. --- ports/nrf/common-hal/alarm/__init__.c | 6 +++--- ports/nrf/common-hal/alarm/touch/TouchAlarm.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index c719deb876..8042855a61 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -59,7 +59,7 @@ void alarm_reset(void) { alarm_sleep_memory_reset(); alarm_pin_pinalarm_reset(); alarm_time_timealarm_reset(); - //alarm_touch_touchalarm_reset(); + alarm_touch_touchalarm_reset(); } extern uint32_t reset_reason_saved; @@ -119,7 +119,7 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); } case NRF_SLEEP_WAKEUP_TOUCHPAD: { - return mp_const_none; + return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms); } case NRF_SLEEP_WAKEUP_GPIO: { return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); @@ -199,7 +199,7 @@ extern void set_memory_retention(void); void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - //alarm_touch_touchalarm_prepare_for_deep_sleep(); + alarm_touch_touchalarm_prepare_for_deep_sleep(); uint8_t sd_enabled; sd_softdevice_is_enabled(&sd_enabled); diff --git a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c index 1878b78b33..e85797e692 100644 --- a/ports/nrf/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/nrf/common-hal/alarm/touch/TouchAlarm.c @@ -28,7 +28,7 @@ #include "shared-bindings/alarm/touch/TouchAlarm.h" #include "shared-bindings/microcontroller/__init__.h" -static volatile bool woke_up = false; +//static volatile bool woke_up = false; void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { mp_raise_NotImplementedError(NULL); From 7fd4648cd5ce467520920d58dd7518e7beace08d Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 09:06:11 +0900 Subject: [PATCH 26/69] rase error if Alarm time >= 512 sec. --- locale/circuitpython.pot | 2 +- ports/nrf/common-hal/alarm/time/TimeAlarm.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index dc0ec9fb7e..39bc4d74e1 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -308,7 +308,7 @@ msgid "Address type out of range" msgstr "" #: ports/nrf/common-hal/alarm/time/TimeAlarm.c -msgid "Alarm time is too far." +msgid "Alarm time must be < 512 seconds." msgstr "" #: ports/esp32s2/common-hal/canio/CAN.c diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index 2a9a0fcd33..e9c536414b 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -86,12 +86,13 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs); int wsecs = (int)(wakeup_in_secs); - if (wsecs > 510) { //XXX - mp_raise_ValueError(translate("Alarm time is too far.")); + // timealarm is implemented by RTC, which is a 24bit counter + // running at 32768Hz. So, 2^24 / 32768 = 512sec is an upper limit. + if (wsecs >= 512) { + mp_raise_ValueError(translate("Alarm time must be < 512 seconds.")); } uint32_t wakeup_in_ticks = (uint32_t)(wakeup_in_secs * 1024.0f); - //printf("alarm_time_timealarm_set_alarms() %d secs 0x%08X ticks\r\n", wsecs, (int)wakeup_in_ticks); port_interrupt_after_ticks_ch(1, wakeup_in_ticks); rtc_woke_up_counter = 0; } From 0f8c96f424c08d5bdfcec565d5718c5151955ab6 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Fri, 26 Feb 2021 09:11:35 +0900 Subject: [PATCH 27/69] remove trailing whitespaces. --- ports/nrf/common-hal/alarm/SleepMemory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index e78e9fdd76..f29ac07f67 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -53,12 +53,12 @@ void set_memory_retention(void) { // nRF52840 has RAM[0..7].Section[0..1] and RAM[8].Section[0..5] // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] for(int block = 0; block <= 7; ++block) { - nrf_power_rampower_mask_on(NRF_POWER, block, + nrf_power_rampower_mask_on(NRF_POWER, block, NRF_POWER_RAMPOWER_S0RETENTION_MASK | NRF_POWER_RAMPOWER_S1RETENTION_MASK); }; #ifdef NRF52840 - nrf_power_rampower_mask_on(NRF_POWER, 8, + nrf_power_rampower_mask_on(NRF_POWER, 8, NRF_POWER_RAMPOWER_S0RETENTION_MASK | NRF_POWER_RAMPOWER_S1RETENTION_MASK | NRF_POWER_RAMPOWER_S2RETENTION_MASK | @@ -67,7 +67,7 @@ void set_memory_retention(void) { NRF_POWER_RAMPOWER_S5RETENTION_MASK); #endif #ifdef NRF52833 - nrf_power_rampower_mask_on(NRF_POWER, 8, + nrf_power_rampower_mask_on(NRF_POWER, 8, NRF_POWER_RAMPOWER_S0RETENTION_MASK | NRF_POWER_RAMPOWER_S1RETENTION_MASK); #endif From fac86c8277bca2002c8ed8983c8a8e4055c1c31a Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 15:34:55 +0900 Subject: [PATCH 28/69] remove unused debug printf's. --- main.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/main.c b/main.c index c15d5810b0..7df6e293aa 100755 --- a/main.c +++ b/main.c @@ -218,7 +218,6 @@ STATIC bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec decompress(compressed, decompressed); mp_hal_stdout_tx_str(decompressed); pyexec_file(filename, exec_result); - //dbg_printf("pyexec_file end result=(code=%d, line=%d)\r\n", exec_result->return_code, exec_result->exception_line); return true; } @@ -264,7 +263,6 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } STATIC bool run_code_py(safe_mode_t safe_mode) { - //dbg_printf("run_code_py (%d)\r\n", (int)safe_mode); bool serial_connected_at_start = serial_connected(); #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 serial_write("\n"); @@ -440,7 +438,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { FIL* boot_output_file; STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { - //dbg_printf("run_boot_py (%d)\r\n", (int)safe_mode); // If not in safe mode, run boot before initing USB and capture output in a // file. if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { @@ -537,10 +534,6 @@ STATIC int run_repl(void) { return exit_code; } -#ifdef NRF_DEBUG_PRINT -extern void dbg_dump_reset_reason(void); -#endif - int __attribute__((used)) main(void) { // initialise the cpu and peripherals safe_mode_t safe_mode = port_init(); @@ -591,12 +584,6 @@ int __attribute__((used)) main(void) { // Start serial and HID after giving boot.py a chance to tweak behavior. serial_init(); -#if 0 //XXX - { - dbg_dump_reset_reason(); - } -#endif - #if CIRCUITPY_BLEIO supervisor_start_bluetooth(); #endif From 9b34726c0d5b2a5a79deec8132828199ba5ff25a Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 15:36:14 +0900 Subject: [PATCH 29/69] GPIO and GPIOTE reg dump for debug. --- ports/nrf/supervisor/debug_uart.c | 55 ++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index 79cc33b198..dda03a00af 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -88,7 +88,6 @@ int dbg_printf(const char *fmt, ...) { return ret; } - void dbg_dump_RTCreg(void) { dbg_printf("\r\nRTC2\r\n"); NRF_RTC_Type *r = rtc_instance.p_reg; @@ -110,6 +109,60 @@ void dbg_dump_RAMreg(void) { dbg_printf("\r\n"); } +void dbg_dump_GPIOregs(void) { + int i, port, col; + + NRF_GPIO_Type *gpio[] = { NRF_P0, NRF_P1 }; + const char cnf_pull_chr[] = "-D*U"; // pull down, pull up + const char cnf_sense_chr[] = "-?HL"; // sense high, sense low + for(port=0, col=0; port<=1; ++port) { + for(i=0; i<32; ++i) { + uint32_t cnf = gpio[port]->PIN_CNF[i]; + if (cnf != 0x0002) { // changed from default value + dbg_printf("[%d_%02d]:%c%c%c%d%c ", port, i, + (cnf & 1) ? 'O' : 'I', // output, input + (cnf & 2) ? 'd' : 'c', // disconnected, connected + cnf_pull_chr[(cnf >> 2) & 3], + (int)((cnf >> 8) & 7), // drive config 0-7 + cnf_sense_chr[(cnf >> 16) & 3]); + if (++col >= 6) { + dbg_printf("\r\n"); + col = 0; + } + } + } + } + if (col > 0) dbg_printf("\r\n"); + + dbg_printf("GPIOTE\r\n"); + NRF_GPIOTE_Type const *reg = NRF_GPIOTE; + const char config_mode_chr[] = "-E-T"; // event, task + const char config_pol_chr[] = "-HLT"; // low-to-Hi, hi-to-Low, Toggle + const char config_outinit_chr[] = "01"; // initial value is 0 or 1 + for(i=0, col=0; i<8; ++i) { + uint32_t conf = reg->CONFIG[i]; + if (conf != 0) { // changed from default value + dbg_printf("CONFIG[%d]:%d_%02d,%c%c%c ", i, + (int)((conf >> 13) & 1), (int)((conf >> 8) & 0x1F), + config_mode_chr[conf & 3], + config_pol_chr[(conf >> 16) & 3], + (conf & 3) == 3 ? + config_outinit_chr[(conf >> 20) & 1] : '-'); + if (++col >= 4) { + dbg_printf("\r\n"); + col = 0; + } + } + } + if (col > 0) dbg_printf("\r\n"); + for(i=0; i<8; ++i) { + dbg_printf("EVENTS_IN[%d]:%X ", i, (int)(reg->EVENTS_IN[i])); + if ((i & 3) == 3) dbg_printf("\r\n"); + } + dbg_printf("EVENTS_PORT:%X INTENSET:%08X\r\n", + (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); +} + void dbg_dump_reset_reason(void) { int reset_reason = (int)common_hal_mcu_processor_get_reset_reason(); const char* rr_str[] = { From 498debc82621efb12f45f14a15b4282636f78299 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 15:37:25 +0900 Subject: [PATCH 30/69] remove unused debug printf's. --- ports/nrf/common-hal/alarm/SleepMemory.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index f29ac07f67..49eb0b2594 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -32,6 +32,7 @@ #ifdef NRF_DEBUG_PRINT extern void dbg_dump_RAMreg(void); +#include "supervisor/serial.h" // dbg_printf() #endif #define RTC_DATA_ATTR __attribute__((section(".uninitialized"))) @@ -78,7 +79,7 @@ static void initialize_sleep_memory(void) { set_memory_retention(); #ifdef NRF_DEBUG_PRINT - dbg_dump_RAMreg(); + //dbg_dump_RAMreg(); #endif _sleep_mem_magicnum = SLEEP_MEMORY_DATA_GUARD; @@ -87,6 +88,9 @@ static void initialize_sleep_memory(void) { void alarm_sleep_memory_reset(void) { if (!is_sleep_memory_valid()) { initialize_sleep_memory(); +#ifdef NRF_DEBUG_PRINT + dbg_printf("sleep memory initialized\r\n"); +#endif } } From 3e47e00291909e13260482e18a0814da7dbf39ff Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 15:57:37 +0900 Subject: [PATCH 31/69] address the pretending-to-deep-sleep issue. --- main.c | 2 +- ports/nrf/common-hal/alarm/__init__.c | 48 +++++++----- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 89 +++++++---------------- shared-bindings/alarm/__init__.c | 5 ++ shared-bindings/alarm/__init__.h | 1 + 5 files changed, 62 insertions(+), 83 deletions(-) diff --git a/main.c b/main.c index 7df6e293aa..2aebfa062f 100755 --- a/main.c +++ b/main.c @@ -430,7 +430,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // it may also return due to another interrupt, that's why we check // for deep sleep alarms above. If it wasn't a deep sleep alarm, // then we'll idle here again. - port_idle_until_interrupt(); + alarm_pretending_deep_sleep(); } } } diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 8042855a61..f54b54a3f9 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -85,13 +85,6 @@ STATIC nrf_sleep_source_t _get_wakeup_cause(void) { return NRF_SLEEP_WAKEUP_UNDEFINED; } -bool alarm_woken_from_sleep(void) { - nrf_sleep_source_t cause = _get_wakeup_cause(); - return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER - || cause == NRF_SLEEP_WAKEUP_TOUCHPAD - || cause == NRF_SLEEP_WAKEUP_RESETPIN); -} - #ifdef NRF_DEBUG_PRINT static const char* cause_str[] = { "UNDEFINED", @@ -109,6 +102,17 @@ void print_wakeup_cause(nrf_sleep_source_t cause) { } #endif +bool alarm_woken_from_sleep(void) { + nrf_sleep_source_t cause = _get_wakeup_cause(); +#ifdef NRF_DEBUG_PRINT + if (cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + //print_wakeup_cause(cause); + } +#endif + return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER + || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); +} + STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); #ifdef NRF_DEBUG_PRINT @@ -152,19 +156,15 @@ STATIC void _idle_until_alarm(void) { RUN_BACKGROUND_TASKS; // Allow ctrl-C interrupt. if (alarm_woken_from_sleep()) { - alarm_save_wake_alarm(); -#ifdef NRF_DEBUG_PRINT - int cause = _get_wakeup_cause(); - printf("wakeup(%d)\r\n", cause); -#endif - return; - } + alarm_save_wake_alarm(); + return; + } port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT - if (ct > 0) { - printf("_"); - --ct; - } + if (ct > 0) { + dbg_printf("_"); + --ct; + } #endif } } @@ -186,8 +186,8 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } else { r_obj = _get_wake_alarm(n_alarms, alarms); - alarm_reset(); } + alarm_reset(); return r_obj; } @@ -220,6 +220,16 @@ void NORETURN alarm_enter_deep_sleep(void) { while(1) ; } +void alarm_pretending_deep_sleep(void) { + alarm_pin_pinalarm_prepare_for_deep_sleep(); + alarm_touch_touchalarm_prepare_for_deep_sleep(); + + port_idle_until_interrupt(); + if (alarm_woken_from_sleep()) { + alarm_reset(); + } +} + void common_hal_alarm_gc_collect(void) { void* p = alarm_get_wake_alarm(); gc_collect_ptr(p); diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 606a7125fa..5ed6fb725c 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -27,6 +27,7 @@ #include "py/runtime.h" #include +#include #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" @@ -44,6 +45,10 @@ volatile char _pinhandler_gpiote_count; volatile nrfx_gpiote_pin_t _pinhandler_ev_pin; #define MYGPIOTE_EV_PIN_UNDEF 0xFF +static bool pins_configured = false; + +extern uint32_t reset_reason_saved; +extern void dbg_dump_GPIOregs(void); void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { if (edge) { @@ -94,7 +99,6 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al return alarms[i]; } } - alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); alarm->base.type = &alarm_pin_pinalarm_type; alarm->pin = NULL; @@ -133,11 +137,14 @@ void alarm_pin_pinalarm_reset(void) { pull_pins = 0; } -static void setup_pin1_for_lightsleep(void) { +static void configure_pins_for_sleep(void) { + nrfx_err_t err; if ( nrfx_gpiote_is_init() ) { - nrfx_gpiote_uninit(); + nrfx_gpiote_uninit(); } - nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); + err = nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); + assert(err == NRFX_SUCCESS); + (void)err; // to suppress unused warning _pinhandler_gpiote_count = 0; _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; @@ -151,10 +158,6 @@ static void setup_pin1_for_lightsleep(void) { }; for(size_t i = 0; i < 64; ++i) { uint64_t mask = 1ull << i; -#ifdef NRF_DEBUG_PRINT - int pull = 0; - int sense = 0; -#endif if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { continue; } @@ -162,76 +165,28 @@ static void setup_pin1_for_lightsleep(void) { cfg.sense = NRF_GPIOTE_POLARITY_LOTOHI; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; -#ifdef NRF_DEBUG_PRINT - pull = -1; sense = 1; -#endif } else if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { cfg.sense = NRF_GPIOTE_POLARITY_HITOLO; cfg.pull = ((pull_pins & mask) != 0) ? NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; -#ifdef NRF_DEBUG_PRINT - pull = 1; sense = -1; -#endif } else { cfg.sense = NRF_GPIOTE_POLARITY_TOGGLE; cfg.pull = NRF_GPIO_PIN_NOPULL; -#ifdef NRF_DEBUG_PRINT - sense = 9; -#endif } - nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, - pinalarm_gpiote_handler); + err = nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, + pinalarm_gpiote_handler); + assert(err == NRFX_SUCCESS); nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); -#ifdef NRF_DEBUG_PRINT - dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); -#endif - } -} - -static void setup_pin1_for_deepsleep(void) { - for(size_t i = 0; i < 64; ++i) { - uint64_t mask = 1ull << i; - int pull = 0; -#ifdef NRF_DEBUG_PRINT - int sense = 0; -#endif - if (((high_alarms & mask) == 0) && ((low_alarms & mask) == 0)) { - continue; - } if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { - pull = ((pull_pins & mask) != 0) ? - NRF_GPIO_PIN_PULLDOWN : NRF_GPIO_PIN_NOPULL; - nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); -#ifdef NRF_DEBUG_PRINT - sense = NRF_GPIO_PIN_SENSE_HIGH; -#endif - } - else + } if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { - pull = ((pull_pins & mask) != 0) ? - NRF_GPIO_PIN_PULLUP : NRF_GPIO_PIN_NOPULL; - nrf_gpio_cfg_input((uint32_t)i, (nrf_gpio_pin_pull_t)pull); nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); -#ifdef NRF_DEBUG_PRINT - sense = NRF_GPIO_PIN_SENSE_LOW; -#endif - } -#ifdef NRF_DEBUG_PRINT - dbg_printf("pin=%d, sense=%d, pull=%d\r\n", i, sense, pull); -#endif + } } -#if 0 - uint32_t pin_number = 2; - NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); - dbg_printf(" 2 PIN_CNF=0x%08X\r\n", (unsigned int)(reg->PIN_CNF[pin_number])); - pin_number = 28; - reg = nrf_gpio_pin_port_decode(&pin_number); - dbg_printf("28 PIN_CNF=0x%08X\r\n", (unsigned int)(reg->PIN_CNF[pin_number])); -#endif } void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { @@ -261,11 +216,13 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob } if (pin_number != -1) { if (!deep_sleep) { - setup_pin1_for_lightsleep(); + configure_pins_for_sleep(); } else { // we don't setup gpio HW here but do them in // alarm_pin_pinalarm_prepare_for_deep_sleep() below + reset_reason_saved = 0; + pins_configured = false; } } else { @@ -274,5 +231,11 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob } void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { - setup_pin1_for_deepsleep(); + if (!pins_configured) { + configure_pins_for_sleep(); + pins_configured = true; +#ifdef NRF_DEBUG_PRINT + dbg_dump_GPIOregs(); +#endif + } } diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 7023c70e5d..509e0acebd 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -242,3 +242,8 @@ const mp_obj_module_t alarm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&alarm_module_globals, }; + +extern void port_idle_until_interrupt(void); +MP_WEAK void alarm_pretending_deep_sleep(void) { + port_idle_until_interrupt(); +} diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 154f91e265..37e8b98ecc 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -42,6 +42,7 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); // Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix. extern NORETURN void alarm_enter_deep_sleep(void); +extern void alarm_pretending_deep_sleep(void); // Fetches value from module dict. extern mp_obj_t alarm_get_wake_alarm(void); From 7cecd996584d819a99b3a09cc1dc1c86d6514041 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 16:04:29 +0900 Subject: [PATCH 32/69] remove unused debug printf's. --- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 5ed6fb725c..47d7ce8360 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -235,7 +235,7 @@ void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { configure_pins_for_sleep(); pins_configured = true; #ifdef NRF_DEBUG_PRINT - dbg_dump_GPIOregs(); + //dbg_dump_GPIOregs(); #endif } } From 7bb789625ed8713334c24c1d78460bf5c2f03492 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 28 Feb 2021 16:27:37 +0900 Subject: [PATCH 33/69] use the original port_idle_until_interrupt() if not CIRCUITPY_ALARM. --- main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.c b/main.c index 2aebfa062f..e6e5a6d2a8 100755 --- a/main.c +++ b/main.c @@ -430,7 +430,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // it may also return due to another interrupt, that's why we check // for deep sleep alarms above. If it wasn't a deep sleep alarm, // then we'll idle here again. + #if CIRCUITPY_ALARM alarm_pretending_deep_sleep(); + #else + port_idle_until_interrupt(); + #endif } } } From 3fab9f8b1b8e86d0c9224ea4c79b4ba35da6ade1 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 01:09:54 +0900 Subject: [PATCH 34/69] new wait-until-alarm design, don't use System OFF. --- main.c | 1 + ports/nrf/common-hal/alarm/SleepMemory.c | 26 +-- ports/nrf/common-hal/alarm/SleepMemory.h | 1 + ports/nrf/common-hal/alarm/__init__.c | 184 +++++++++++++++++--- ports/nrf/common-hal/alarm/__init__.h | 9 + ports/nrf/common-hal/alarm/pin/PinAlarm.c | 14 +- ports/nrf/common-hal/alarm/time/TimeAlarm.c | 36 ++-- ports/nrf/common-hal/alarm/time/TimeAlarm.h | 6 + ports/nrf/supervisor/debug_uart.c | 32 +++- ports/nrf/supervisor/port.c | 32 +++- 10 files changed, 274 insertions(+), 67 deletions(-) diff --git a/main.c b/main.c index e6e5a6d2a8..0f7ca8860e 100755 --- a/main.c +++ b/main.c @@ -435,6 +435,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #else port_idle_until_interrupt(); #endif + return false; // to go REPL } } } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 49eb0b2594..367f305972 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -27,6 +27,7 @@ #include #include "py/runtime.h" +#include "common-hal/alarm/__init__.h" #include "common-hal/alarm/SleepMemory.h" #include "nrf_power.h" @@ -35,14 +36,15 @@ extern void dbg_dump_RAMreg(void); #include "supervisor/serial.h" // dbg_printf() #endif -#define RTC_DATA_ATTR __attribute__((section(".uninitialized"))) -static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; -static RTC_DATA_ATTR uint32_t _sleep_mem_magicnum; +__attribute__((section(".uninitialized"))) static uint8_t _sleepmem[SLEEP_MEMORY_LENGTH]; +__attribute__((section(".uninitialized"))) uint8_t sleepmem_wakeup_event; +__attribute__((section(".uninitialized"))) uint8_t sleepmem_wakeup_pin; +__attribute__((section(".uninitialized"))) static uint32_t _sleepmem_magicnum; #define SLEEP_MEMORY_DATA_GUARD 0xad0000af #define SLEEP_MEMORY_DATA_GUARD_MASK 0xff0000ff static int is_sleep_memory_valid(void) { - if ((_sleep_mem_magicnum & SLEEP_MEMORY_DATA_GUARD_MASK) + if ((_sleepmem_magicnum & SLEEP_MEMORY_DATA_GUARD_MASK) == SLEEP_MEMORY_DATA_GUARD) { return 1; } @@ -75,14 +77,16 @@ void set_memory_retention(void) { } static void initialize_sleep_memory(void) { - memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); + memset((uint8_t *)_sleepmem, 0, SLEEP_MEMORY_LENGTH); + sleepmem_wakeup_event = 0; + sleepmem_wakeup_pin = 0; set_memory_retention(); #ifdef NRF_DEBUG_PRINT //dbg_dump_RAMreg(); #endif - _sleep_mem_magicnum = SLEEP_MEMORY_DATA_GUARD; + _sleepmem_magicnum = SLEEP_MEMORY_DATA_GUARD; } void alarm_sleep_memory_reset(void) { @@ -95,21 +99,21 @@ void alarm_sleep_memory_reset(void) { } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - return sizeof(_sleep_mem); + return sizeof(_sleepmem); } bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t* values, uint32_t len) { - if (start_index + len > sizeof(_sleep_mem)) { + if (start_index + len > sizeof(_sleepmem)) { return false; } - memcpy((uint8_t *) (_sleep_mem + start_index), values, len); + memcpy((uint8_t *) (_sleepmem + start_index), values, len); return true; } void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) { - if (start_index + len > sizeof(_sleep_mem)) { + if (start_index + len > sizeof(_sleepmem)) { return; } - memcpy(values, (uint8_t *) (_sleep_mem + start_index), len); + memcpy(values, (uint8_t *) (_sleepmem + start_index), len); } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index 24fe0065d0..11cc4a8fb9 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -35,6 +35,7 @@ typedef struct { mp_obj_base_t base; } alarm_sleep_memory_obj_t; +extern void set_memory_retention(void); extern void alarm_sleep_memory_reset(void); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index f54b54a3f9..12bb2a40c4 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -37,10 +37,13 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" +#include "shared-bindings/time/__init__.h" #include "supervisor/port.h" +#include "supervisor/serial.h" // serial_connected() #ifdef NRF_DEBUG_PRINT #include "supervisor/serial.h" // dbg_printf() +extern int dbg_check_RTCprescaler(void); #endif #include "nrf.h" @@ -113,6 +116,23 @@ bool alarm_woken_from_sleep(void) { || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); } +nrf_sleep_source_t alarm_woken_from_sleep_2(void) { + nrf_sleep_source_t cause = _get_wakeup_cause(); +#ifdef NRF_DEBUG_PRINT + if (cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + //print_wakeup_cause(cause); + } +#endif + if (cause == NRF_SLEEP_WAKEUP_GPIO || + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + return cause; + } + else { + return NRF_SLEEP_WAKEUP_UNDEFINED; + } +} + STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); #ifdef NRF_DEBUG_PRINT @@ -146,19 +166,74 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); } -STATIC void _idle_until_alarm(void) { +nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { + bool have_timeout = false; + uint64_t start_tick = 0, end_tick = 0; + + if (timediff_ms != -1) { + have_timeout = true; +#if 0 + int64_t now = common_hal_time_monotonic_ms(); + dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); +#endif + if (timediff_ms < 0) timediff_ms = 0; + int64_t tickdiff; + if (prescaler == 0) { + // 1 tick = 1/1024 sec = 1000/1024 ms + // -> 1 ms = 1024/1000 ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks + } + else { + // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms + // -> 1ms = 1024/(1000*prescaler) ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); + } + start_tick = port_get_raw_ticks(NULL); + end_tick = start_tick + tickdiff; + } +#if 0 + dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); +#endif + + int64_t remaining; + nrf_sleep_source_t wakeup_cause = NRF_SLEEP_WAKEUP_UNDEFINED; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; + #ifdef NRF_DEBUG_PRINT int ct = 40; + char reason = '?'; +#define WAKEUP_REASON(x) reason = (x) +#else +#define WAKEUP_REASON(x) #endif - reset_reason_saved = 0; - // Poll for alarms. - while (!mp_hal_is_interrupted()) { - RUN_BACKGROUND_TASKS; - // Allow ctrl-C interrupt. - if (alarm_woken_from_sleep()) { - alarm_save_wake_alarm(); - return; + + while(1) { + if (mp_hal_is_interrupted()) { + WAKEUP_REASON('I'); + break; } + if (serial_connected() && serial_bytes_available()) { + WAKEUP_REASON('S'); + break; + } + RUN_BACKGROUND_TASKS; + wakeup_cause = alarm_woken_from_sleep_2(); + if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + WAKEUP_REASON('0'+wakeup_cause); + break; + } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + // We break a bit early so we don't risk setting the alarm before the time when we call + // sleep. + if (remaining < 1) { + WAKEUP_REASON('t'); + break; + } + port_interrupt_after_ticks(remaining); + } + // Idle until an interrupt happens. port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT if (ct > 0) { @@ -166,17 +241,39 @@ STATIC void _idle_until_alarm(void) { --ct; } #endif + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + if (remaining <= 0) { + wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + WAKEUP_REASON('T'); + break; + } + } } +#ifdef NRF_DEBUG_PRINT + dbg_printf("%c\r\n", reason); +#endif + return wakeup_cause; } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t r_obj = mp_const_none; + alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(false, n_alarms, alarms); + #ifdef NRF_DEBUG_PRINT - dbg_printf("\r\nsleep..."); + dbg_printf("\r\nlight sleep..."); #endif - _idle_until_alarm(); + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + //dbg_printf("wakeup! "); + print_wakeup_cause(cause); +#endif if (mp_hal_is_interrupted()) { #ifdef NRF_DEBUG_PRINT @@ -192,29 +289,47 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { + alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(true, n_alarms, alarms); } -extern void set_memory_retention(void); +#if defined(MICROPY_QSPI_CS) +extern void qspi_disable(void); +#endif + +#define PRESCALER_VALUE_IN_DEEP_SLEEP (1024) +extern void _debug_uart_init(void); +extern void _debug_uart_uninit(void); void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - alarm_touch_touchalarm_prepare_for_deep_sleep(); + alarm_time_timealarm_prepare_for_deep_sleep(); - uint8_t sd_enabled; - sd_softdevice_is_enabled(&sd_enabled); - - set_memory_retention(); +#if defined(MICROPY_QSPI_CS) + qspi_disable(); +#endif #ifdef NRF_DEBUG_PRINT - dbg_printf("go system off.. %d\r\n", sd_enabled); + dbg_printf("\r\ndeep sleep..."); #endif - if (sd_enabled) { - sd_power_system_off(); - } - else { - NRF_POWER->SYSTEMOFF = 1; - } + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + tick_set_prescaler(PRESCALER_VALUE_IN_DEEP_SLEEP -1); +#ifdef NRF_DEBUG_PRINT + dbg_dump_RTCreg(); //XXX + dbg_check_RTCprescaler(); //XXX +#endif + nrf_sleep_source_t cause; + cause = system_on_idle_until_alarm(timediff_ms, + PRESCALER_VALUE_IN_DEEP_SLEEP); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + dbg_printf("wakeup! "); + print_wakeup_cause(cause); + dbg_printf("RESET...\r\n\r\n"); +#endif + + reset_cpu(); // should not reach here.. while(1) ; @@ -222,12 +337,23 @@ void NORETURN alarm_enter_deep_sleep(void) { void alarm_pretending_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - alarm_touch_touchalarm_prepare_for_deep_sleep(); + alarm_time_timealarm_prepare_for_deep_sleep(); - port_idle_until_interrupt(); - if (alarm_woken_from_sleep()) { - alarm_reset(); - } +#ifdef NRF_DEBUG_PRINT + dbg_printf("\r\npretending to deep sleep..."); +#endif + + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + dbg_printf("wakeup! "); + print_wakeup_cause(cause); + dbg_printf("continue..\r\n"); +#endif + + alarm_reset(); } void common_hal_alarm_gc_collect(void) { diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 6fa07bcd29..7df3aaf4c3 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -41,6 +41,15 @@ typedef enum { extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; +enum { + SLEEPMEM_WAKEUP_BY_NONE = 0, + SLEEPMEM_WAKEUP_BY_PIN = 1, + SLEEPMEM_WAKEUP_BY_TIMER = 2, +}; +#define WAKEUP_PIN_UNDEF 0xFF +extern uint8_t sleepmem_wakeup_event; +extern uint8_t sleepmem_wakeup_pin; + extern void alarm_reset(void); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 47d7ce8360..1f00dc0c33 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -32,6 +32,7 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +#include "common-hal/alarm/__init__.h" #include "nrfx.h" #include "nrf_gpio.h" @@ -43,8 +44,6 @@ #define WPIN_UNUSED 0xFF volatile char _pinhandler_gpiote_count; -volatile nrfx_gpiote_pin_t _pinhandler_ev_pin; -#define MYGPIOTE_EV_PIN_UNDEF 0xFF static bool pins_configured = false; extern uint32_t reset_reason_saved; @@ -81,11 +80,13 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) { static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { ++_pinhandler_gpiote_count; - _pinhandler_ev_pin = pin; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_PIN; + sleepmem_wakeup_pin = pin & 0xFF; } bool alarm_pin_pinalarm_woke_us_up(void) { - return (_pinhandler_gpiote_count > 0 && _pinhandler_ev_pin != MYGPIOTE_EV_PIN_UNDEF); + return (sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN && + sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); } mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { @@ -95,7 +96,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); - if (alarm->pin->number == _pinhandler_ev_pin) { + if (alarm->pin->number == sleepmem_wakeup_pin) { return alarms[i]; } } @@ -105,7 +106,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al // Map the pin number back to a pin object. for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); - if ((size_t) pin_obj->number == _pinhandler_ev_pin) { + if ((size_t) pin_obj->number == sleepmem_wakeup_pin) { alarm->pin = mcu_pin_globals.map.table[i].value; break; } @@ -147,7 +148,6 @@ static void configure_pins_for_sleep(void) { (void)err; // to suppress unused warning _pinhandler_gpiote_count = 0; - _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; nrfx_gpiote_in_config_t cfg = { .sense = NRF_GPIOTE_POLARITY_TOGGLE, diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index e9c536414b..c4b06982bf 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -30,6 +30,7 @@ //#include "supervisor/esp_port.h" #include +#include "common-hal/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" @@ -56,17 +57,31 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * } bool alarm_time_timealarm_woke_us_up(void) { - return rtc_woke_up_counter; + return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_TIMER; +} + +int64_t wakeup_time_saved =0; + +int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void) { + if (wakeup_time_saved == 0) { + return -1; + } + return wakeup_time_saved - common_hal_time_monotonic_ms(); +} + +void alarm_time_timealarm_clear_wakeup_time(void) { + wakeup_time_saved = 0; } void alarm_time_timealarm_reset(void) { port_disable_interrupt_after_ticks_ch(1); - rtc_woke_up_counter = 0; + wakeup_time_saved = 0; } void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { bool timealarm_set = false; alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL; + wakeup_time_saved = 0; for (size_t i = 0; i < n_alarms; i++) { if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { @@ -82,17 +97,8 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ return; } - // Compute how long to actually sleep, considering the time now. - mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; - mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs); - int wsecs = (int)(wakeup_in_secs); - // timealarm is implemented by RTC, which is a 24bit counter - // running at 32768Hz. So, 2^24 / 32768 = 512sec is an upper limit. - if (wsecs >= 512) { - mp_raise_ValueError(translate("Alarm time must be < 512 seconds.")); - } - - uint32_t wakeup_in_ticks = (uint32_t)(wakeup_in_secs * 1024.0f); - port_interrupt_after_ticks_ch(1, wakeup_in_ticks); - rtc_woke_up_counter = 0; + wakeup_time_saved = (int64_t)(timealarm->monotonic_time * 1000.0f); +} + +void alarm_time_timealarm_prepare_for_deep_sleep(void) { } diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index 14a2ff80cf..a824c52535 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -42,3 +42,9 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * bool alarm_time_timealarm_woke_us_up(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_time_timealarm_reset(void); + +extern void alarm_time_timealarm_prepare_for_deep_sleep(void); +extern int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void); +extern void alarm_time_timealarm_clear_wakeup_time(void); +extern void dbg_dump_RTCreg(void); +extern void tick_set_prescaler(uint32_t prescaler_val); diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index dda03a00af..f920cdae32 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -21,9 +21,9 @@ #include "nrfx_rtc.h" #include "supervisor/serial.h" // dbg_printf() #include "shared-bindings/microcontroller/Processor.h" +#include "common-hal/alarm/__init__.h" extern const nrfx_rtc_t rtc_instance; // port.c -extern volatile int rtc_woke_up_counter; // port.c extern uint32_t reset_reason_saved; const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); @@ -31,6 +31,16 @@ static int _dbg_uart_initialized = 0; #define DBG_PBUF_LEN 80 static char _dbg_pbuf[DBG_PBUF_LEN+1]; +void _debug_uart_uninit(void) { + nrf_gpio_cfg(DEBUG_UART_TXPIN, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + nrfx_uarte_uninit(&_dbg_uart_inst); +} + void _debug_uart_init(void) { //if (_dbg_uart_initialized) return; nrfx_uarte_config_t config = { @@ -55,6 +65,16 @@ void _debug_uart_init(void) { NRF_GPIO_PIN_H0H1, // orig=S0S1 NRF_GPIO_PIN_NOSENSE); _dbg_uart_initialized = 1; +#if 1 //XXX + #define DBGPIN 6+32 + nrf_gpio_cfg(DBGPIN, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_H0H1, + NRF_GPIO_PIN_NOSENSE); + nrf_gpio_pin_write(DBGPIN, 1); +#endif return; } @@ -97,7 +117,15 @@ void dbg_dump_RTCreg(void) { dbg_printf("EVTENSET=%08X\r\n", (int)r->EVTENSET); dbg_printf("EVENTS_COMPARE[0..3]=%X,%X,%X,%X ", (int)r->EVENTS_COMPARE[0], (int)r->EVENTS_COMPARE[1], (int)r->EVENTS_COMPARE[2], (int)r->EVENTS_COMPARE[3]); dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); - dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); +} + +int dbg_check_RTCprescaler(void) { + NRF_RTC_Type *r = rtc_instance.p_reg; + if ((int)r->PRESCALER == 0) { + dbg_printf("****** PRESCALER == 0\r\n"); + return -1; + } + return 0; } void dbg_dump_RAMreg(void) { diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 5908683008..d5efa92b46 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -51,6 +51,7 @@ #include "common-hal/rtc/RTC.h" #include "common-hal/neopixel_write/__init__.h" #include "common-hal/watchdog/WatchDogTimer.h" +#include "common-hal/alarm/__init__.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/rtc/__init__.h" @@ -75,13 +76,13 @@ static void power_warning_handler(void) { #ifdef NRF_DEBUG_PRINT extern void _debug_uart_init(void); +#define DBGPIN 6+32 //XXX P1_06 = TP1 #endif uint32_t reset_reason_saved = 0; const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(2); -volatile int rtc_woke_up_counter = 0; -const nrfx_rtc_config_t rtc_config = { +nrfx_rtc_config_t rtc_config = { .prescaler = RTC_FREQ_TO_PRESCALER(0x8000), .reliable = 0, .tick_latency = 0, @@ -97,6 +98,11 @@ static volatile struct { } overflow_tracker __attribute__((section(".uninitialized"))); void rtc_handler(nrfx_rtc_int_type_t int_type) { +#ifdef NRF_DEBUG_PRINT + if (int_type == NRFX_RTC_INT_TICK) { + nrf_gpio_pin_toggle(DBGPIN); //XXX + } +#endif if (int_type == NRFX_RTC_INT_OVERFLOW) { // Our RTC is 24 bits and we're clocking it at 32.768khz which is 32 (2 ** 5) subticks per // tick. @@ -108,7 +114,7 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { nrfx_rtc_cc_set(&rtc_instance, 0, 0, false); } else if (int_type == NRFX_RTC_INT_COMPARE1) { // used in light sleep - ++rtc_woke_up_counter; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; nrfx_rtc_cc_set(&rtc_instance, 1, 0, false); } } @@ -134,6 +140,22 @@ void tick_init(void) { } } +void tick_uninit(void) { + nrfx_rtc_counter_clear(&rtc_instance); + nrfx_rtc_disable(&rtc_instance); + nrfx_rtc_uninit(&rtc_instance); +} + +void tick_set_prescaler(uint32_t prescaler_val) { + tick_uninit(); + // update of prescaler value sometimes fails if we skip this delay.. + NRFX_DELAY_US(1000); + uint16_t prescaler_saved = rtc_config.prescaler; + rtc_config.prescaler = prescaler_val; + tick_init(); + rtc_config.prescaler = prescaler_saved; +} + safe_mode_t port_init(void) { nrf_peripherals_clocks_init(); @@ -166,6 +188,10 @@ safe_mode_t port_init(void) { reset_reason_saved = NRF_POWER->RESETREAS; // clear all RESET reason bits NRF_POWER->RESETREAS = reset_reason_saved; + // clear wakeup event/pin when reset by reset-pin + if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + } // If the board was reset by the WatchDogTimer, we may // need to boot into safe mode. Reset the RESETREAS bit From cd5c0e99f797a5d21156c1f6d421b8c8e7fbf090 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 19:09:01 +0900 Subject: [PATCH 35/69] Clean up. --- ports/nrf/supervisor/debug_uart.c | 26 ++++++++++++++++---------- ports/nrf/supervisor/port.c | 6 ------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index f920cdae32..f770b661fc 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -65,16 +65,6 @@ void _debug_uart_init(void) { NRF_GPIO_PIN_H0H1, // orig=S0S1 NRF_GPIO_PIN_NOSENSE); _dbg_uart_initialized = 1; -#if 1 //XXX - #define DBGPIN 6+32 - nrf_gpio_cfg(DBGPIN, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_H0H1, - NRF_GPIO_PIN_NOSENSE); - nrf_gpio_pin_write(DBGPIN, 1); -#endif return; } @@ -191,6 +181,22 @@ void dbg_dump_GPIOregs(void) { (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); } +void dbg_dumpQSPIreg(void) { + uint32_t r; + dbg_printf("QSPI\r\n"); + r = NRF_QSPI->IFCONFIG0; + dbg_printf("IFCONFIG0 READ=%ld write=%ld ADDR=%ld DPM=%ld PPSIZE=%ld\r\n", + r & 7, (r >> 3) & 7, (r >> 6) & 1, (r >> 7) & 1, (r >> 12) & 1); + r = NRF_QSPI->IFCONFIG1; + dbg_printf("IFCONFIG1 SCKDELAY=%ld SPIMODE=%ld SCKFREQ=%ld\r\n", + r & 0xFF, (r >> 25) & 1, (r >> 28) & 0xF); + r = NRF_QSPI->STATUS; + dbg_printf("STATUS DPM=%ld READY=%ld SREG=0x%02lX\r\n", + (r >> 2) & 1, (r >> 3) & 1, (r >> 24) & 0xFF); + r = NRF_QSPI->DPMDUR; + dbg_printf("DPMDUR ENTER=%ld EXIT=%ld\r\n", r & 0xFFFF, (r >> 16) & 0xFFFF); +} + void dbg_dump_reset_reason(void) { int reset_reason = (int)common_hal_mcu_processor_get_reset_reason(); const char* rr_str[] = { diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index d5efa92b46..1ae3cb29ab 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -76,7 +76,6 @@ static void power_warning_handler(void) { #ifdef NRF_DEBUG_PRINT extern void _debug_uart_init(void); -#define DBGPIN 6+32 //XXX P1_06 = TP1 #endif uint32_t reset_reason_saved = 0; @@ -98,11 +97,6 @@ static volatile struct { } overflow_tracker __attribute__((section(".uninitialized"))); void rtc_handler(nrfx_rtc_int_type_t int_type) { -#ifdef NRF_DEBUG_PRINT - if (int_type == NRFX_RTC_INT_TICK) { - nrf_gpio_pin_toggle(DBGPIN); //XXX - } -#endif if (int_type == NRFX_RTC_INT_OVERFLOW) { // Our RTC is 24 bits and we're clocking it at 32.768khz which is 32 (2 ** 5) subticks per // tick. From 2795c002adbaa4bdac90c87159cd00eed31792bb Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 19:14:04 +0900 Subject: [PATCH 36/69] disable QSPI while system ON idle loop. --- ports/nrf/common-hal/alarm/__init__.c | 21 ++++--- ports/nrf/supervisor/qspi_flash.c | 86 +++++++++++++++++++++++++++ ports/nrf/supervisor/qspi_flash.h | 2 + 3 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 ports/nrf/supervisor/qspi_flash.h diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 12bb2a40c4..10d3bcc4fb 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -45,6 +45,7 @@ #include "supervisor/serial.h" // dbg_printf() extern int dbg_check_RTCprescaler(void); #endif +#include "supervisor/qspi_flash.h" #include "nrf.h" #include "nrf_power.h" @@ -170,6 +171,10 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres bool have_timeout = false; uint64_t start_tick = 0, end_tick = 0; +#if defined(MICROPY_QSPI_CS) + qspi_flash_enter_sleep(); +#endif + if (timediff_ms != -1) { have_timeout = true; #if 0 @@ -254,6 +259,11 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres #ifdef NRF_DEBUG_PRINT dbg_printf("%c\r\n", reason); #endif + +#if defined(MICROPY_QSPI_CS) + qspi_flash_exit_sleep(); +#endif + return wakeup_cause; } @@ -293,29 +303,18 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _setup_sleep_alarms(true, n_alarms, alarms); } -#if defined(MICROPY_QSPI_CS) -extern void qspi_disable(void); -#endif - #define PRESCALER_VALUE_IN_DEEP_SLEEP (1024) -extern void _debug_uart_init(void); -extern void _debug_uart_uninit(void); void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_time_timealarm_prepare_for_deep_sleep(); -#if defined(MICROPY_QSPI_CS) - qspi_disable(); -#endif - #ifdef NRF_DEBUG_PRINT dbg_printf("\r\ndeep sleep..."); #endif int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); tick_set_prescaler(PRESCALER_VALUE_IN_DEEP_SLEEP -1); #ifdef NRF_DEBUG_PRINT - dbg_dump_RTCreg(); //XXX dbg_check_RTCprescaler(); //XXX #endif nrf_sleep_source_t cause; diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 7ca27d56c4..00a88d52b9 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -37,6 +37,9 @@ #include "supervisor/shared/external_flash/common_commands.h" #include "supervisor/shared/external_flash/qspi_flash.h" +#ifdef NRF_DEBUG_PRINT +#include "supervisor/serial.h" // dbg_printf() +#endif // When USB is disconnected, disable QSPI in sleep mode to save energy void qspi_disable(void) @@ -190,7 +193,11 @@ void spi_flash_init(void) { .readoc = NRF_QSPI_READOC_FASTREAD, .writeoc = NRF_QSPI_WRITEOC_PP, .addrmode = NRF_QSPI_ADDRMODE_24BIT, +#ifdef QSPI_FLASH_POWERDOWN + .dpmconfig = true +#else .dpmconfig = false +#endif }, .phy_if = { .sck_freq = NRF_QSPI_FREQ_32MDIV16, // Start at a slow 2MHz and speed up once we know what we're talking to. @@ -238,3 +245,82 @@ void spi_flash_init_device(const external_flash_device* device) { NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_SCKFREQ_Msk; NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; } + +#ifdef QSPI_FLASH_POWERDOWN +// Parameters for external QSPI Flash power-down +// for W25Q128FV, +// tDP (nCS high to Power-down mode) = 3us +// tRES (nCS high to Standby mode) = 3us +// sck_delay = max(tDP, tRES) / 62.5ns = 48 -> 50 (w/ margin) +#define DUR_DPM_ENTER 1 // tDP in (256*62.5ns) units +#define DUR_DPM_EXIT 1 // tRES in (256*62.5ns) units +#define SCK_DELAY 50 // max(tDP, tRES) in (62.5ns) units +// wait necessary just after DPM enter/exit (cut and try) +#define WAIT_AFTER_DPM_ENTER 10 // usec +#define WAIT_AFTER_DPM_EXIT 50 // usec +#endif + +static int sck_delay_saved = 0; +#ifdef NRF_DEBUG_PRINT +extern void dbg_dumpQSPIreg(void); +#else +#define dbg_dumpQSPIreg(...) +#endif + +void qspi_flash_enter_sleep(void) { +#ifdef QSPI_FLASH_POWERDOWN + uint32_t r; + NRF_QSPI->DPMDUR = + ((DUR_DPM_ENTER & 0xFFFF) << 16) | (DUR_DPM_EXIT & 0xFFFF); + // set sck_delay tempolarily + r = NRF_QSPI->IFCONFIG1; + sck_delay_saved = (r & QSPI_IFCONFIG1_SCKDELAY_Msk) + >> QSPI_IFCONFIG1_SCKDELAY_Pos; + NRF_QSPI->IFCONFIG1 + = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) + | (SCK_DELAY << QSPI_IFCONFIG1_SCKDELAY_Pos); + + // enabling IFCONFIG0.DPMENABLE here won't work. + // -> do it in spi_flash_init() + //NRF_QSPI->IFCONFIG0 |= QSPI_IFCONFIG0_DPMENABLE_Msk; + //dbg_dumpQSPIreg(); + + // enter deep power-down mode (DPM) + NRF_QSPI->IFCONFIG1 |= QSPI_IFCONFIG1_DPMEN_Msk; + NRFX_DELAY_US(WAIT_AFTER_DPM_ENTER); + if (!(NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk)) { +#ifdef NRF_DEBUG_PRINT + dbg_printf("qspi flash: DPM failed\r\n"); +#endif + } +#endif + + qspi_disable(); + //dbg_dumpQSPIreg(); +} + +void qspi_flash_exit_sleep(void) { + qspi_enable(); + +#ifdef QSPI_FLASH_POWERDOWN + if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { + // exit deep power-down mode + NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_DPMEN_Msk; + NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); + + if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { +#ifdef NRF_DEBUG_PRINT + dbg_printf("qspi flash: exiting DPM failed\r\n"); +#endif + } + // restore sck_delay + if (sck_delay_saved == 0) { + sck_delay_saved = 10; // default + } + NRF_QSPI->IFCONFIG1 + = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) + | (sck_delay_saved << QSPI_IFCONFIG1_SCKDELAY_Pos); + } + //dbg_dumpQSPIreg(); +#endif +} diff --git a/ports/nrf/supervisor/qspi_flash.h b/ports/nrf/supervisor/qspi_flash.h new file mode 100644 index 0000000000..527f3cec39 --- /dev/null +++ b/ports/nrf/supervisor/qspi_flash.h @@ -0,0 +1,2 @@ +extern void qspi_flash_enter_sleep(void); +extern void qspi_flash_exit_sleep(void); From 7430b92d27c912cf2e43337b4c4a45dac73100b0 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 20:20:29 +0900 Subject: [PATCH 37/69] address hw pin-reset while sleep. --- ports/nrf/supervisor/qspi_flash.c | 49 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index 00a88d52b9..d2bf9678da 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -41,6 +41,27 @@ #include "supervisor/serial.h" // dbg_printf() #endif +#ifdef QSPI_FLASH_POWERDOWN +// Parameters for external QSPI Flash power-down +// for W25Q128FV, +// tDP (nCS high to Power-down mode) = 3us +// tRES (nCS high to Standby mode) = 3us +// sck_delay = max(tDP, tRES) / 62.5ns = 48 -> 50 (w/ margin) +#define DUR_DPM_ENTER 1 // tDP in (256*62.5ns) units +#define DUR_DPM_EXIT 1 // tRES in (256*62.5ns) units +#define SCK_DELAY 50 // max(tDP, tRES) in (62.5ns) units +// wait necessary just after DPM enter/exit (cut and try) +#define WAIT_AFTER_DPM_ENTER 10 // usec +#define WAIT_AFTER_DPM_EXIT 50 // usec +#endif + +static int sck_delay_saved = 0; +#ifdef NRF_DEBUG_PRINT +extern void dbg_dumpQSPIreg(void); +#else +#define dbg_dumpQSPIreg(...) +#endif + // When USB is disconnected, disable QSPI in sleep mode to save energy void qspi_disable(void) { @@ -222,6 +243,13 @@ void spi_flash_init(void) { // No callback for blocking API nrfx_qspi_init(&qspi_cfg, NULL, NULL); + +#ifdef QSPI_FLASH_POWERDOWN + // If pin-reset while flash is in power-down mode, + // the flash cannot accept any commands. Send CMD_WAKE to release it. + spi_flash_write_command(CMD_WAKE, NULL, 0); + NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); +#endif } void spi_flash_init_device(const external_flash_device* device) { @@ -246,27 +274,6 @@ void spi_flash_init_device(const external_flash_device* device) { NRF_QSPI->IFCONFIG1 |= sckfreq << QSPI_IFCONFIG1_SCKFREQ_Pos; } -#ifdef QSPI_FLASH_POWERDOWN -// Parameters for external QSPI Flash power-down -// for W25Q128FV, -// tDP (nCS high to Power-down mode) = 3us -// tRES (nCS high to Standby mode) = 3us -// sck_delay = max(tDP, tRES) / 62.5ns = 48 -> 50 (w/ margin) -#define DUR_DPM_ENTER 1 // tDP in (256*62.5ns) units -#define DUR_DPM_EXIT 1 // tRES in (256*62.5ns) units -#define SCK_DELAY 50 // max(tDP, tRES) in (62.5ns) units -// wait necessary just after DPM enter/exit (cut and try) -#define WAIT_AFTER_DPM_ENTER 10 // usec -#define WAIT_AFTER_DPM_EXIT 50 // usec -#endif - -static int sck_delay_saved = 0; -#ifdef NRF_DEBUG_PRINT -extern void dbg_dumpQSPIreg(void); -#else -#define dbg_dumpQSPIreg(...) -#endif - void qspi_flash_enter_sleep(void) { #ifdef QSPI_FLASH_POWERDOWN uint32_t r; From 2eed9a173555e837f2b33178346c42374379fa0e Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 20:21:33 +0900 Subject: [PATCH 38/69] old System OFF sleep code for future reference. --- ports/nrf/common-hal/alarm/__init__.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 10d3bcc4fb..5544cdeb59 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -334,6 +334,25 @@ void NORETURN alarm_enter_deep_sleep(void) { while(1) ; } +// old version deep sleep code that was used in alarm_enter_deep_sleep() +// for anyone who might want true System OFF sleep .. +#if 0 +void OLD_go_system_off(void) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; + uint8_t sd_enabled; + sd_softdevice_is_enabled(&sd_enabled); + set_memory_retention(); + dbg_printf("OLD go system off.. %d\r\n", sd_enabled); + if (sd_enabled) { + sd_power_system_off(); + } + else { + NRF_POWER->SYSTEMOFF = 1; + } +} +#endif + void alarm_pretending_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_time_timealarm_prepare_for_deep_sleep(); From 5bd1107feca0eb3e1d0e59f50d3e6d6d88753832 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 20:38:04 +0900 Subject: [PATCH 39/69] Clean up. --- ports/nrf/supervisor/qspi_flash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index d2bf9678da..e4449bcba0 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -53,9 +53,10 @@ // wait necessary just after DPM enter/exit (cut and try) #define WAIT_AFTER_DPM_ENTER 10 // usec #define WAIT_AFTER_DPM_EXIT 50 // usec -#endif static int sck_delay_saved = 0; +#endif + #ifdef NRF_DEBUG_PRINT extern void dbg_dumpQSPIreg(void); #else From c8f36e604cc8d9f566e1f68f0fffb1ad828204ce Mon Sep 17 00:00:00 2001 From: jun2sak Date: Tue, 9 Mar 2021 00:42:22 +0900 Subject: [PATCH 40/69] reset myself, not go REPL, after wakeup from deep sleep. --- ports/nrf/common-hal/alarm/__init__.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 5544cdeb59..b9b39b84a4 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -170,6 +170,7 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { bool have_timeout = false; uint64_t start_tick = 0, end_tick = 0; + int64_t tickdiff; #if defined(MICROPY_QSPI_CS) qspi_flash_enter_sleep(); @@ -182,7 +183,6 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); #endif if (timediff_ms < 0) timediff_ms = 0; - int64_t tickdiff; if (prescaler == 0) { // 1 tick = 1/1024 sec = 1000/1024 ms // -> 1 ms = 1024/1000 ticks @@ -264,6 +264,18 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres qspi_flash_exit_sleep(); #endif + tickdiff = port_get_raw_ticks(NULL) - start_tick; + if (prescaler == 0) { + timediff_ms = tickdiff / 1024; + } + else { + timediff_ms = tickdiff * prescaler / 1024; + } + (void)timediff_ms; +#ifdef NRF_DEBUG_PRINT + dbg_printf("lapse %6.1f sec\r\n", (double)(timediff_ms)); +#endif + return wakeup_cause; } @@ -368,10 +380,17 @@ void alarm_pretending_deep_sleep(void) { #ifdef NRF_DEBUG_PRINT dbg_printf("wakeup! "); print_wakeup_cause(cause); - dbg_printf("continue..\r\n"); #endif alarm_reset(); + + // if one of Alarm event occurred, reset myself + if (cause == NRF_SLEEP_WAKEUP_GPIO || + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + reset_cpu(); + } + // else, just return and go into REPL } void common_hal_alarm_gc_collect(void) { From 6e9429d779f01c823ca4e0d0b277e20533d6ada3 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Mon, 12 Apr 2021 20:53:14 +0900 Subject: [PATCH 41/69] soft reboot for pretending deep sleep. --- main.c | 19 +++++++++++++++---- ports/nrf/common-hal/alarm/__init__.c | 7 ++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index b311db39dd..755f8d5362 100755 --- a/main.c +++ b/main.c @@ -404,10 +404,10 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { new_status_color(BLACK); board_deinit(); if (!supervisor_workflow_active()) { - // Enter true deep sleep. When we wake up we'll be back at the - // top of main(), not in this loop. + // Enter deep sleep. When we wake up we'll return from + // this loop. common_hal_alarm_enter_deep_sleep(); - // Does not return. + // Does not return. } else { serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n")); } @@ -426,10 +426,21 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #if CIRCUITPY_ALARM common_hal_alarm_pretending_deep_sleep(); + bool serial_in = (serial_connected() && + serial_bytes_available()); + supervisor_set_run_reason(RUN_REASON_STARTUP); + board_init(); + if (serial_in) { + bool ctrl_d = serial_read() == CHAR_CTRL_D; + if (ctrl_d) { + supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); + } + return ctrl_d; + } + return true; #else port_idle_until_interrupt(); #endif - //return false; // to go REPL } } } diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 2baec6b433..c8180fb2e0 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -346,7 +346,7 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { while(1) ; } -// old version deep sleep code that was used in alarm_enter_deep_sleep() +// old version deep sleep code that was used in common_hal_alarm_enter_deep_sleep() // for anyone who might want true System OFF sleep .. #if 0 void OLD_go_system_off(void) { @@ -384,6 +384,7 @@ void common_hal_alarm_pretending_deep_sleep(void) { alarm_reset(); +#if 0 // if one of Alarm event occurred, reset myself if (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER || @@ -391,9 +392,9 @@ void common_hal_alarm_pretending_deep_sleep(void) { reset_cpu(); } // else, just return and go into REPL +#endif } void common_hal_alarm_gc_collect(void) { - void* p = shared_alarm_get_wake_alarm(); - gc_collect_ptr(p); + gc_collect_ptr(shared_alarm_get_wake_alarm()); } From 436e33e7ecd7af42ac52e94b6604c728d296bffe Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Tue, 20 Apr 2021 15:04:52 -0400 Subject: [PATCH 42/69] Fix CI formatting issues --- locale/circuitpython.pot | 5 +---- supervisor/shared/serial.c | 10 +++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a5a4da90f8..2a43daf014 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -309,10 +309,6 @@ msgstr "" msgid "Address type out of range" msgstr "" -#: ports/nrf/common-hal/alarm/time/TimeAlarm.c -msgid "Alarm time must be < 512 seconds." -msgstr "" - #: ports/esp32s2/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" @@ -3722,6 +3718,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h #: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h +#: ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index dc3a37e116..beb2541a15 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -40,7 +40,7 @@ #ifdef NRF_DEBUG_PRINT // XXX these functions are in nrf/supervisor/debug_uart.c extern void _debug_uart_init(void); -extern void _debug_print_substr(const char* text, uint32_t length); +extern void _debug_print_substr(const char *text, uint32_t length); #endif /* @@ -72,15 +72,15 @@ void serial_early_init(void) { #endif #ifdef NRF_DEBUG_PRINT - _debug_uart_init(); + _debug_uart_init(); #endif } void serial_init(void) { usb_init(); -#ifdef NRF_DEBUG_PRINT + #ifdef NRF_DEBUG_PRINT _debug_uart_init(); -#endif + #endif } bool serial_connected(void) { @@ -160,7 +160,7 @@ void serial_write_substring(const char *text, uint32_t length) { #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) int uart_errcode; - common_hal_busio_uart_write(&debug_uart, (const uint8_t*) text, length, &uart_errcode); + common_hal_busio_uart_write(&debug_uart, (const uint8_t *)text, length, &uart_errcode); #endif #ifdef NRF_DEBUG_PRINT From a1dc423569c94b994aaa7ee21cd4d3bbdb59fbc8 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Tue, 20 Apr 2021 17:20:53 -0400 Subject: [PATCH 43/69] Remove Alarm from small boards --- ports/nrf/boards/pca10100/mpconfigboard.mk | 1 + ports/nrf/boards/simmel/mpconfigboard.mk | 1 + ports/nrf/mpconfigport.mk | 2 +- ports/nrf/supervisor/port.c | 4 ++++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index 74080a1ed9..dd59eb96c9 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -7,6 +7,7 @@ MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_ALARM = 0 CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITMAPTOOLS = 0 diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 005ec8af2f..e6750877b2 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -10,6 +10,7 @@ MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_ALARM = 0 CIRCUITPY_AESIO = 1 CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_BITMAPTOOLS = 0 diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index a5766cf1fe..132aba208f 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -47,7 +47,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_WATCHDOG ?= 1 # Sleep and Wakeup -CIRCUITPY_ALARM = 1 +CIRCUITPY_ALARM ?= 1 # nRF52840-specific diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 5cad994c0d..8026e51d84 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -108,7 +108,9 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { nrfx_rtc_cc_set(&rtc_instance, 0, 0, false); } else if (int_type == NRFX_RTC_INT_COMPARE1) { // used in light sleep + #if CIRCUITPY_ALARM sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + #endif nrfx_rtc_cc_set(&rtc_instance, 1, 0, false); } } @@ -184,7 +186,9 @@ safe_mode_t port_init(void) { NRF_POWER->RESETREAS = reset_reason_saved; // clear wakeup event/pin when reset by reset-pin if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { + #if CIRCUITPY_ALARM sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + #endif } // If the board was reset by the WatchDogTimer, we may From 39b7d9bcf2098d8402392dd5f237787cf8d75d86 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Tue, 20 Apr 2021 18:03:37 -0400 Subject: [PATCH 44/69] Fix indentation --- main.c | 12 +- ports/nrf/common-hal/alarm/SleepMemory.c | 22 ++-- ports/nrf/common-hal/alarm/__init__.c | 106 +++++++++--------- ports/nrf/common-hal/alarm/__init__.h | 14 +-- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 26 ++--- .../common-hal/microcontroller/Processor.c | 6 +- ports/nrf/supervisor/debug_uart.c | 104 ++++++++--------- ports/nrf/supervisor/qspi_flash.c | 24 ++-- 8 files changed, 157 insertions(+), 157 deletions(-) diff --git a/main.c b/main.c index 755f8d5362..d16db235e8 100755 --- a/main.c +++ b/main.c @@ -407,7 +407,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // Enter deep sleep. When we wake up we'll return from // this loop. common_hal_alarm_enter_deep_sleep(); - // Does not return. + // Does not return. } else { serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n")); } @@ -431,11 +431,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { supervisor_set_run_reason(RUN_REASON_STARTUP); board_init(); if (serial_in) { - bool ctrl_d = serial_read() == CHAR_CTRL_D; - if (ctrl_d) { - supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); - } - return ctrl_d; + bool ctrl_d = serial_read() == CHAR_CTRL_D; + if (ctrl_d) { + supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); + } + return ctrl_d; } return true; #else diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 367f305972..e87fcd7991 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -57,22 +57,22 @@ void set_memory_retention(void) { // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] for(int block = 0; block <= 7; ++block) { nrf_power_rampower_mask_on(NRF_POWER, block, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); }; #ifdef NRF52840 nrf_power_rampower_mask_on(NRF_POWER, 8, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK | - NRF_POWER_RAMPOWER_S2RETENTION_MASK | - NRF_POWER_RAMPOWER_S3RETENTION_MASK | - NRF_POWER_RAMPOWER_S4RETENTION_MASK | - NRF_POWER_RAMPOWER_S5RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK | + NRF_POWER_RAMPOWER_S2RETENTION_MASK | + NRF_POWER_RAMPOWER_S3RETENTION_MASK | + NRF_POWER_RAMPOWER_S4RETENTION_MASK | + NRF_POWER_RAMPOWER_S5RETENTION_MASK); #endif #ifdef NRF52833 nrf_power_rampower_mask_on(NRF_POWER, 8, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); #endif } @@ -93,7 +93,7 @@ void alarm_sleep_memory_reset(void) { if (!is_sleep_memory_valid()) { initialize_sleep_memory(); #ifdef NRF_DEBUG_PRINT - dbg_printf("sleep memory initialized\r\n"); + dbg_printf("sleep memory initialized\r\n"); #endif } } diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index c8180fb2e0..aabb27ef25 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -101,7 +101,7 @@ static const char* cause_str[] = { void print_wakeup_cause(nrf_sleep_source_t cause) { if (cause >= 0 && cause < NRF_SLEEP_WAKEUP_ZZZ) { dbg_printf("wakeup cause = NRF_SLEEP_WAKEUP_%s\r\n", - cause_str[(int)cause]); + cause_str[(int)cause]); } } #endif @@ -114,7 +114,7 @@ bool common_hal_alarm_woken_from_sleep(void) { } #endif return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER - || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); + || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); } nrf_sleep_source_t alarm_woken_from_sleep_2(void) { @@ -125,8 +125,8 @@ nrf_sleep_source_t alarm_woken_from_sleep_2(void) { } #endif if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { return cause; } else { @@ -179,22 +179,22 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres if (timediff_ms != -1) { have_timeout = true; #if 0 - int64_t now = common_hal_time_monotonic_ms(); - dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); + int64_t now = common_hal_time_monotonic_ms(); + dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); #endif - if (timediff_ms < 0) timediff_ms = 0; - if (prescaler == 0) { - // 1 tick = 1/1024 sec = 1000/1024 ms - // -> 1 ms = 1024/1000 ticks - tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks - } - else { - // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms - // -> 1ms = 1024/(1000*prescaler) ticks - tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); - } - start_tick = port_get_raw_ticks(NULL); - end_tick = start_tick + tickdiff; + if (timediff_ms < 0) timediff_ms = 0; + if (prescaler == 0) { + // 1 tick = 1/1024 sec = 1000/1024 ms + // -> 1 ms = 1024/1000 ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks + } + else { + // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms + // -> 1ms = 1024/(1000*prescaler) ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); + } + start_tick = port_get_raw_ticks(NULL); + end_tick = start_tick + tickdiff; } #if 0 dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); @@ -214,30 +214,30 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres #endif while(1) { - if (mp_hal_is_interrupted()) { - WAKEUP_REASON('I'); - break; - } + if (mp_hal_is_interrupted()) { + WAKEUP_REASON('I'); + break; + } if (serial_connected() && serial_bytes_available()) { - WAKEUP_REASON('S'); - break; - } + WAKEUP_REASON('S'); + break; + } RUN_BACKGROUND_TASKS; - wakeup_cause = alarm_woken_from_sleep_2(); - if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { - WAKEUP_REASON('0'+wakeup_cause); - break; - } - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - // We break a bit early so we don't risk setting the alarm before the time when we call - // sleep. - if (remaining < 1) { - WAKEUP_REASON('t'); - break; - } - port_interrupt_after_ticks(remaining); - } + wakeup_cause = alarm_woken_from_sleep_2(); + if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + WAKEUP_REASON('0'+wakeup_cause); + break; + } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + // We break a bit early so we don't risk setting the alarm before the time when we call + // sleep. + if (remaining < 1) { + WAKEUP_REASON('t'); + break; + } + port_interrupt_after_ticks(remaining); + } // Idle until an interrupt happens. port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT @@ -246,15 +246,15 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres --ct; } #endif - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - if (remaining <= 0) { - wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; - sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; - WAKEUP_REASON('T'); - break; - } - } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + if (remaining <= 0) { + wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + WAKEUP_REASON('T'); + break; + } + } } #ifdef NRF_DEBUG_PRINT dbg_printf("%c\r\n", reason); @@ -331,7 +331,7 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { #endif nrf_sleep_source_t cause; cause = system_on_idle_until_alarm(timediff_ms, - PRESCALER_VALUE_IN_DEEP_SLEEP); + PRESCALER_VALUE_IN_DEEP_SLEEP); (void)cause; #ifdef NRF_DEBUG_PRINT @@ -387,8 +387,8 @@ void common_hal_alarm_pretending_deep_sleep(void) { #if 0 // if one of Alarm event occurred, reset myself if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { reset_cpu(); } // else, just return and go into REPL diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 7df3aaf4c3..ce8ca5f327 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -30,13 +30,13 @@ #include "common-hal/alarm/SleepMemory.h" typedef enum { - NRF_SLEEP_WAKEUP_UNDEFINED, - NRF_SLEEP_WAKEUP_GPIO, - NRF_SLEEP_WAKEUP_TIMER, - NRF_SLEEP_WAKEUP_TOUCHPAD, - NRF_SLEEP_WAKEUP_VBUS, - NRF_SLEEP_WAKEUP_RESETPIN, - NRF_SLEEP_WAKEUP_ZZZ + NRF_SLEEP_WAKEUP_UNDEFINED, + NRF_SLEEP_WAKEUP_GPIO, + NRF_SLEEP_WAKEUP_TIMER, + NRF_SLEEP_WAKEUP_TOUCHPAD, + NRF_SLEEP_WAKEUP_VBUS, + NRF_SLEEP_WAKEUP_RESETPIN, + NRF_SLEEP_WAKEUP_ZZZ } nrf_sleep_source_t; extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 1f00dc0c33..89ec2ad30f 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -86,7 +86,7 @@ static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t bool alarm_pin_pinalarm_woke_us_up(void) { return (sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN && - sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); + sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); } mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { @@ -96,7 +96,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); - if (alarm->pin->number == sleepmem_wakeup_pin) { + if (alarm->pin->number == sleepmem_wakeup_pin) { return alarms[i]; } } @@ -129,8 +129,8 @@ void alarm_pin_pinalarm_reset(void) { continue; } reset_pin_number(i); - nrfx_gpiote_in_event_disable((nrfx_gpiote_pin_t)i); - nrfx_gpiote_in_uninit((nrfx_gpiote_pin_t)i); + nrfx_gpiote_in_event_disable((nrfx_gpiote_pin_t)i); + nrfx_gpiote_in_uninit((nrfx_gpiote_pin_t)i); } high_alarms = 0; @@ -177,15 +177,15 @@ static void configure_pins_for_sleep(void) { cfg.pull = NRF_GPIO_PIN_NOPULL; } err = nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, - pinalarm_gpiote_handler); - assert(err == NRFX_SUCCESS); + pinalarm_gpiote_handler); + assert(err == NRFX_SUCCESS); nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); - } + } if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); - } + } } } @@ -202,7 +202,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); pin_number = alarm->pin->number; - //dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); + //dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); if (alarm->value) { high_alarms |= 1ull << pin_number; high_count++; @@ -221,8 +221,8 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob else { // we don't setup gpio HW here but do them in // alarm_pin_pinalarm_prepare_for_deep_sleep() below - reset_reason_saved = 0; - pins_configured = false; + reset_reason_saved = 0; + pins_configured = false; } } else { @@ -233,9 +233,9 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { if (!pins_configured) { configure_pins_for_sleep(); - pins_configured = true; + pins_configured = true; #ifdef NRF_DEBUG_PRINT - //dbg_dump_GPIOregs(); + //dbg_dump_GPIOregs(); #endif } } diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index 4baa4eaace..bcad002ffe 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -141,9 +141,9 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { r = RESET_REASON_SOFTWARE; } else if ((reset_reason_saved & POWER_RESETREAS_OFF_Msk) || - (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || - (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || - (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { + (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || + (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || + (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { r = RESET_REASON_DEEP_SLEEP_ALARM; } return r; diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index f770b661fc..420ba14b82 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -33,11 +33,11 @@ static char _dbg_pbuf[DBG_PBUF_LEN+1]; void _debug_uart_uninit(void) { nrf_gpio_cfg(DEBUG_UART_TXPIN, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); nrfx_uarte_uninit(&_dbg_uart_inst); } @@ -59,11 +59,11 @@ void _debug_uart_init(void) { nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); // drive config nrf_gpio_cfg(config.pseltxd, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_PULLUP, // orig=NOPULL - NRF_GPIO_PIN_H0H1, // orig=S0S1 - NRF_GPIO_PIN_NOSENSE); + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_PULLUP, // orig=NOPULL + NRF_GPIO_PIN_H0H1, // orig=S0S1 + NRF_GPIO_PIN_NOSENSE); _dbg_uart_initialized = 1; return; } @@ -73,16 +73,16 @@ void _debug_print_substr(const char* text, uint32_t length) { int siz; while(length != 0) { if (length <= DBG_PBUF_LEN) { - siz = length; - } - else { - siz = DBG_PBUF_LEN; - } - memcpy(_dbg_pbuf, data, siz); - _dbg_pbuf[siz] = 0; - nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); - data += siz; - length -= siz; + siz = length; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + length -= siz; } } @@ -113,7 +113,7 @@ int dbg_check_RTCprescaler(void) { NRF_RTC_Type *r = rtc_instance.p_reg; if ((int)r->PRESCALER == 0) { dbg_printf("****** PRESCALER == 0\r\n"); - return -1; + return -1; } return 0; } @@ -135,20 +135,20 @@ void dbg_dump_GPIOregs(void) { const char cnf_sense_chr[] = "-?HL"; // sense high, sense low for(port=0, col=0; port<=1; ++port) { for(i=0; i<32; ++i) { - uint32_t cnf = gpio[port]->PIN_CNF[i]; - if (cnf != 0x0002) { // changed from default value - dbg_printf("[%d_%02d]:%c%c%c%d%c ", port, i, - (cnf & 1) ? 'O' : 'I', // output, input - (cnf & 2) ? 'd' : 'c', // disconnected, connected - cnf_pull_chr[(cnf >> 2) & 3], - (int)((cnf >> 8) & 7), // drive config 0-7 - cnf_sense_chr[(cnf >> 16) & 3]); - if (++col >= 6) { - dbg_printf("\r\n"); - col = 0; - } - } - } + uint32_t cnf = gpio[port]->PIN_CNF[i]; + if (cnf != 0x0002) { // changed from default value + dbg_printf("[%d_%02d]:%c%c%c%d%c ", port, i, + (cnf & 1) ? 'O' : 'I', // output, input + (cnf & 2) ? 'd' : 'c', // disconnected, connected + cnf_pull_chr[(cnf >> 2) & 3], + (int)((cnf >> 8) & 7), // drive config 0-7 + cnf_sense_chr[(cnf >> 16) & 3]); + if (++col >= 6) { + dbg_printf("\r\n"); + col = 0; + } + } + } } if (col > 0) dbg_printf("\r\n"); @@ -159,26 +159,26 @@ void dbg_dump_GPIOregs(void) { const char config_outinit_chr[] = "01"; // initial value is 0 or 1 for(i=0, col=0; i<8; ++i) { uint32_t conf = reg->CONFIG[i]; - if (conf != 0) { // changed from default value - dbg_printf("CONFIG[%d]:%d_%02d,%c%c%c ", i, - (int)((conf >> 13) & 1), (int)((conf >> 8) & 0x1F), - config_mode_chr[conf & 3], - config_pol_chr[(conf >> 16) & 3], - (conf & 3) == 3 ? - config_outinit_chr[(conf >> 20) & 1] : '-'); - if (++col >= 4) { - dbg_printf("\r\n"); - col = 0; - } - } + if (conf != 0) { // changed from default value + dbg_printf("CONFIG[%d]:%d_%02d,%c%c%c ", i, + (int)((conf >> 13) & 1), (int)((conf >> 8) & 0x1F), + config_mode_chr[conf & 3], + config_pol_chr[(conf >> 16) & 3], + (conf & 3) == 3 ? + config_outinit_chr[(conf >> 20) & 1] : '-'); + if (++col >= 4) { + dbg_printf("\r\n"); + col = 0; + } + } } if (col > 0) dbg_printf("\r\n"); for(i=0; i<8; ++i) { dbg_printf("EVENTS_IN[%d]:%X ", i, (int)(reg->EVENTS_IN[i])); - if ((i & 3) == 3) dbg_printf("\r\n"); + if ((i & 3) == 3) dbg_printf("\r\n"); } dbg_printf("EVENTS_PORT:%X INTENSET:%08X\r\n", - (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); + (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); } void dbg_dumpQSPIreg(void) { @@ -186,13 +186,13 @@ void dbg_dumpQSPIreg(void) { dbg_printf("QSPI\r\n"); r = NRF_QSPI->IFCONFIG0; dbg_printf("IFCONFIG0 READ=%ld write=%ld ADDR=%ld DPM=%ld PPSIZE=%ld\r\n", - r & 7, (r >> 3) & 7, (r >> 6) & 1, (r >> 7) & 1, (r >> 12) & 1); + r & 7, (r >> 3) & 7, (r >> 6) & 1, (r >> 7) & 1, (r >> 12) & 1); r = NRF_QSPI->IFCONFIG1; dbg_printf("IFCONFIG1 SCKDELAY=%ld SPIMODE=%ld SCKFREQ=%ld\r\n", - r & 0xFF, (r >> 25) & 1, (r >> 28) & 0xF); + r & 0xFF, (r >> 25) & 1, (r >> 28) & 0xF); r = NRF_QSPI->STATUS; dbg_printf("STATUS DPM=%ld READY=%ld SREG=0x%02lX\r\n", - (r >> 2) & 1, (r >> 3) & 1, (r >> 24) & 0xFF); + (r >> 2) & 1, (r >> 3) & 1, (r >> 24) & 0xFF); r = NRF_QSPI->DPMDUR; dbg_printf("DPMDUR ENTER=%ld EXIT=%ld\r\n", r & 0xFFFF, (r >> 16) & 0xFFFF); } diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index f2beb3e3a9..6d1bec4422 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -281,7 +281,7 @@ void qspi_flash_enter_sleep(void) { // set sck_delay tempolarily r = NRF_QSPI->IFCONFIG1; sck_delay_saved = (r & QSPI_IFCONFIG1_SCKDELAY_Msk) - >> QSPI_IFCONFIG1_SCKDELAY_Pos; + >> QSPI_IFCONFIG1_SCKDELAY_Pos; NRF_QSPI->IFCONFIG1 = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) | (SCK_DELAY << QSPI_IFCONFIG1_SCKDELAY_Pos); @@ -312,20 +312,20 @@ void qspi_flash_exit_sleep(void) { if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { // exit deep power-down mode NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_DPMEN_Msk; - NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); + NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); - if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { + if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { #ifdef NRF_DEBUG_PRINT - dbg_printf("qspi flash: exiting DPM failed\r\n"); + dbg_printf("qspi flash: exiting DPM failed\r\n"); #endif - } - // restore sck_delay - if (sck_delay_saved == 0) { - sck_delay_saved = 10; // default - } - NRF_QSPI->IFCONFIG1 - = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) - | (sck_delay_saved << QSPI_IFCONFIG1_SCKDELAY_Pos); + } + // restore sck_delay + if (sck_delay_saved == 0) { + sck_delay_saved = 10; // default + } + NRF_QSPI->IFCONFIG1 + = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) + | (sck_delay_saved << QSPI_IFCONFIG1_SCKDELAY_Pos); } //dbg_dumpQSPIreg(); #endif From 779169da266cc52759596cf8e25ae18e5e8f7e8d Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Wed, 21 Apr 2021 13:43:10 -0400 Subject: [PATCH 45/69] Reduce Simmel size --- ports/nrf/boards/simmel/mpconfigboard.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index e6750877b2..e235fd1051 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -16,6 +16,7 @@ CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSIO = 1 +CIRCUITPY_COUNTIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_ERRNO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 @@ -24,10 +25,13 @@ CIRCUITPY_MSGPACK = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 1 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_SYNTHIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 CIRCUITPY_USB_CDC = 0 From beb7e33db333fdb21653e81f56ae8a676120fa82 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Wed, 21 Apr 2021 16:34:03 -0400 Subject: [PATCH 46/69] Fix attribution and revert changes to main --- main.c | 16 ++----------- ports/nrf/common-hal/alarm/SleepMemory.c | 3 +-- ports/nrf/common-hal/alarm/SleepMemory.h | 2 +- ports/nrf/common-hal/alarm/__init__.c | 8 ++++--- ports/nrf/common-hal/alarm/__init__.h | 2 +- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 3 +-- ports/nrf/common-hal/alarm/pin/PinAlarm.h | 2 +- ports/nrf/common-hal/alarm/time/TimeAlarm.c | 2 +- ports/nrf/common-hal/alarm/time/TimeAlarm.h | 2 +- ports/nrf/supervisor/debug_uart.c | 25 +++++++++++++++++++-- 10 files changed, 37 insertions(+), 28 deletions(-) diff --git a/main.c b/main.c index d16db235e8..7020ab3851 100755 --- a/main.c +++ b/main.c @@ -404,8 +404,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { new_status_color(BLACK); board_deinit(); if (!supervisor_workflow_active()) { - // Enter deep sleep. When we wake up we'll return from - // this loop. + // Enter true deep sleep. When we wake up we'll be back at the + // top of main(), not in this loop. common_hal_alarm_enter_deep_sleep(); // Does not return. } else { @@ -426,18 +426,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #if CIRCUITPY_ALARM common_hal_alarm_pretending_deep_sleep(); - bool serial_in = (serial_connected() && - serial_bytes_available()); - supervisor_set_run_reason(RUN_REASON_STARTUP); - board_init(); - if (serial_in) { - bool ctrl_d = serial_read() == CHAR_CTRL_D; - if (ctrl_d) { - supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); - } - return ctrl_d; - } - return true; #else port_idle_until_interrupt(); #endif diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index e87fcd7991..a27fb88e4c 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 microDev - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index 11cc4a8fb9..816f4f492b 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index aabb27ef25..f60a33ca4c 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -167,6 +166,9 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); } +// TODO: this handles all possible types of wakeup, which is redundant with main. +// revise to extract all parts essential to enabling sleep wakeup, but leave the +// alarm/non-alarm sorting to the existing main loop. nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { bool have_timeout = false; uint64_t start_tick = 0, end_tick = 0; @@ -382,7 +384,7 @@ void common_hal_alarm_pretending_deep_sleep(void) { print_wakeup_cause(cause); #endif - alarm_reset(); + // alarm_reset(); #if 0 // if one of Alarm event occurred, reset myself diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index ce8ca5f327..2473ab64a1 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries. + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 89ec2ad30f..b6293ad1c5 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.h b/ports/nrf/common-hal/alarm/pin/PinAlarm.h index 93672c1f2d..0b7401669f 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.h +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index c4b06982bf..c6a79cbbc9 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index a824c52535..61938210a2 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Jun2Sak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index 420ba14b82..9cf33279f7 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -1,6 +1,27 @@ /* - * debug functions - * (will be removed) + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jun2Sak + * + * 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 From 79fb03c2403008335a3839ba170957bf0c1f42f9 Mon Sep 17 00:00:00 2001 From: Jose David M Date: Fri, 23 Apr 2021 12:47:06 +0000 Subject: [PATCH 47/69] Translated using Weblate (Spanish) Currently translated at 100.0% (970 of 970 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/es/ --- locale/es.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/locale/es.po b/locale/es.po index 2b0538e8b3..71ecb5d328 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-22 17:16+0000\n" +"PO-Revision-Date: 2021-04-23 20:32+0000\n" "Last-Translator: Jose David M \n" "Language-Team: \n" "Language: es\n" @@ -2470,7 +2470,7 @@ msgstr "addresses esta vacío" #: py/compile.c msgid "annotation must be an identifier" -msgstr "" +msgstr "la anotación debe ser un identificador" #: py/modbuiltins.c msgid "arg is an empty sequence" @@ -2656,7 +2656,7 @@ msgstr "no puede convertir %q a %q" #: py/runtime.c msgid "can't convert %q to int" -msgstr "" +msgstr "no se puede convertir %q a int" #: py/objstr.c msgid "can't convert '%q' object to %q implicitly" @@ -3081,7 +3081,7 @@ msgstr "lleno" #: py/argcheck.c msgid "function doesn't take keyword arguments" -msgstr "" +msgstr "la función no toma argumentos de tipo keyword" #: py/argcheck.c #, c-format @@ -3137,7 +3137,7 @@ msgstr "generador ignorado GeneratorExit" #: py/objgenerator.c msgid "generator raised StopIteration" -msgstr "" +msgstr "el generador genero StopIteration" #: shared-bindings/_stage/Layer.c msgid "graphic must be 2048 bytes long" @@ -3199,7 +3199,7 @@ msgstr "ensamblador en línea debe ser una función" #: extmod/ulab/code/ndarray.c msgid "input and output shapes are not compatible" -msgstr "Formas de entrada y salida no son compactibles" +msgstr "Formas de entrada y salida no son compatibles" #: extmod/ulab/code/ulab_create.c msgid "input argument must be an integer, a tuple, or a list" @@ -3524,7 +3524,7 @@ msgstr "necesita más de %d valores para descomprimir" #: py/modmath.c msgid "negative factorial" -msgstr "" +msgstr "factorial negativo" #: py/objint_longlong.c py/objint_mpz.c py/runtime.c msgid "negative power with no float support" From 7e5f00a0e2242cdc481b0357ae32e7ab5b8230e7 Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Fri, 23 Apr 2021 16:34:12 +0000 Subject: [PATCH 48/69] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (970 of 970 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index e3a9e6675e..6b12165900 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-22 17:16+0000\n" +"PO-Revision-Date: 2021-04-23 20:32+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -2477,7 +2477,7 @@ msgstr "os endereços estão vazios" #: py/compile.c msgid "annotation must be an identifier" -msgstr "" +msgstr "a anotação deve ser um identificador" #: py/modbuiltins.c msgid "arg is an empty sequence" @@ -2663,7 +2663,7 @@ msgstr "não é possível converter %q para %q" #: py/runtime.c msgid "can't convert %q to int" -msgstr "" +msgstr "Não é possível converter %q para int" #: py/objstr.c msgid "can't convert '%q' object to %q implicitly" @@ -3090,7 +3090,7 @@ msgstr "cheio" #: py/argcheck.c msgid "function doesn't take keyword arguments" -msgstr "" +msgstr "a função não aceita palavras-chave como argumentos" #: py/argcheck.c #, c-format @@ -3146,7 +3146,7 @@ msgstr "ignorando o gerador GeneratorExit" #: py/objgenerator.c msgid "generator raised StopIteration" -msgstr "" +msgstr "gerador StopIteration elevado" #: shared-bindings/_stage/Layer.c msgid "graphic must be 2048 bytes long" @@ -3535,7 +3535,7 @@ msgstr "precisa de mais de %d valores para desempacotar" #: py/modmath.c msgid "negative factorial" -msgstr "" +msgstr "fatorial negativo" #: py/objint_longlong.c py/objint_mpz.c py/runtime.c msgid "negative power with no float support" From b21afac006d08dbd8f136b247d218c22596416c7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 23 Apr 2021 22:32:05 +0200 Subject: [PATCH 49/69] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 19 +++++++++++++++++++ locale/cs.po | 19 +++++++++++++++++++ locale/de_DE.po | 19 +++++++++++++++++++ locale/el.po | 19 +++++++++++++++++++ locale/en_GB.po | 19 +++++++++++++++++++ locale/es.po | 19 +++++++++++++++++++ locale/fil.po | 19 +++++++++++++++++++ locale/fr.po | 19 +++++++++++++++++++ locale/hi.po | 19 +++++++++++++++++++ locale/it_IT.po | 19 +++++++++++++++++++ locale/ja.po | 19 +++++++++++++++++++ locale/ko.po | 19 +++++++++++++++++++ locale/nl.po | 19 +++++++++++++++++++ locale/pl.po | 19 +++++++++++++++++++ locale/pt_BR.po | 19 +++++++++++++++++++ locale/sv.po | 19 +++++++++++++++++++ locale/zh_Latn_pinyin.po | 19 +++++++++++++++++++ 17 files changed, 323 insertions(+) diff --git a/locale/ID.po b/locale/ID.po index 213537ea56..97d3e15d18 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -1207,6 +1207,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "%q pada tidak valid" @@ -1277,6 +1278,11 @@ msgstr "Periode penangkapan tidak valid. Kisaran yang valid: 1 - 500" msgid "Invalid channel count" msgstr "Jumlah kanal tidak valid" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Arah tidak valid." @@ -2155,6 +2161,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Untuk keluar, silahkan reset board tanpa " @@ -2840,6 +2854,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 874f0bf329..79f18261a4 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -1188,6 +1188,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "" @@ -1258,6 +1259,11 @@ msgstr "" msgid "Invalid channel count" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "" @@ -2117,6 +2123,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "" @@ -2794,6 +2808,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index d59651ef3e..419e42b498 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -1208,6 +1208,7 @@ msgstr "Ungültiger %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Ungültiger %q Pin" @@ -1278,6 +1279,11 @@ msgstr "Ungültiger Aufnahmezeitraum. Gültiger Bereich: 1 - 500" msgid "Invalid channel count" msgstr "Ungültige Anzahl von Kanälen" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Ungültige Richtung." @@ -2161,6 +2167,14 @@ msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" "Zeitbeschränkung ist zu groß: Maximale Zeitbeschränkung ist %d Sekunden" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Zum beenden, resette bitte das board ohne " @@ -2863,6 +2877,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/el.po b/locale/el.po index 93d1c14efe..9f3027016c 100644 --- a/locale/el.po +++ b/locale/el.po @@ -1185,6 +1185,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "" @@ -1255,6 +1256,11 @@ msgstr "" msgid "Invalid channel count" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "" @@ -2114,6 +2120,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "" @@ -2791,6 +2805,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index f3fd1e71ad..ef1677f66d 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -1202,6 +1202,7 @@ msgstr "Invalid %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Invalid %q pin" @@ -1272,6 +1273,11 @@ msgstr "Invalid capture period. Valid range: 1 - 500" msgid "Invalid channel count" msgstr "Invalid channel count" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Invalid direction." @@ -2151,6 +2157,14 @@ msgstr "Time is in the past." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Timeout is too long: Maximum timeout length is %d seconds" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "To exit, please reset the board without " @@ -2837,6 +2851,11 @@ msgstr "cata must be iterable" msgid "data must be of equal length" msgstr "cata must be of equal length" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "cata type not understood" diff --git a/locale/es.po b/locale/es.po index 71ecb5d328..0970910e8e 100644 --- a/locale/es.po +++ b/locale/es.po @@ -1219,6 +1219,7 @@ msgstr "%q inválido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Pin %q inválido" @@ -1289,6 +1290,11 @@ msgstr "Inválido periodo de captura. Rango válido: 1 - 500" msgid "Invalid channel count" msgstr "Cuenta de canales inválida" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Dirección inválida." @@ -2180,6 +2186,14 @@ msgstr "" "Tiempo de espera demasiado largo: El tiempo máximo de espera es de %d " "segundos" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Para salir, por favor reinicia la tarjeta sin " @@ -2873,6 +2887,11 @@ msgstr "los datos deben permitir iteración" msgid "data must be of equal length" msgstr "los datos deben ser de igual tamaño" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "tipo de dato no comprendido" diff --git a/locale/fil.po b/locale/fil.po index aa1badbfaf..1e85ccbf4b 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -1200,6 +1200,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Mali ang %q pin" @@ -1270,6 +1271,11 @@ msgstr "" msgid "Invalid channel count" msgstr "Maling bilang ng channel" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Mali ang direksyon." @@ -2134,6 +2140,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Para lumabas, paki-reset ang board na wala ang " @@ -2826,6 +2840,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 941f877fe4..b3df316885 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -1231,6 +1231,7 @@ msgstr "%q invalide" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Broche invalide pour '%q'" @@ -1301,6 +1302,11 @@ msgstr "Période de capture invalide. Portée valide : 1 à 500" msgid "Invalid channel count" msgstr "Nombre de canaux invalide" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Direction invalide." @@ -2191,6 +2197,14 @@ msgstr "L'heure est dans le passé." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Le délai est trop long : le délai maximal est de %d secondes" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Pour quitter, SVP redémarrez la carte sans " @@ -2893,6 +2907,11 @@ msgstr "les données doivent être les objets iterables" msgid "data must be of equal length" msgstr "les données doivent être de longueur égale" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "le type de donnée n'est pas reconnu" diff --git a/locale/hi.po b/locale/hi.po index ff2a0530e5..135f9781f1 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -1185,6 +1185,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "" @@ -1255,6 +1256,11 @@ msgstr "" msgid "Invalid channel count" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "" @@ -2114,6 +2120,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "" @@ -2791,6 +2805,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 188e25d16f..53b78ea1ef 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -1209,6 +1209,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Pin %q non valido" @@ -1281,6 +1282,11 @@ msgstr "periodo di cattura invalido. Zona valida: 1 - 500" msgid "Invalid channel count" msgstr "Argomento non valido" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Direzione non valida." @@ -2155,6 +2161,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Per uscire resettare la scheda senza " @@ -2840,6 +2854,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/ja.po b/locale/ja.po index 0d3e93d1c2..6c833f6f49 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -1198,6 +1198,7 @@ msgstr "不正な %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "不正な%qピン" @@ -1268,6 +1269,11 @@ msgstr "不正なキャプチャ周期。有効な周期は1-500" msgid "Invalid channel count" msgstr "不正なチャンネル数" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "不正な方向" @@ -2136,6 +2142,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "タイムアウトが長すぎです。最大のタイムアウト長は%d秒" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "" @@ -2816,6 +2830,11 @@ msgstr "dataはイテレート可能でなければなりません" msgid "data must be of equal length" msgstr "dataは同じ長さでなければなりません" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 7adda96b93..1178d45dd6 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -1188,6 +1188,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "" @@ -1258,6 +1259,11 @@ msgstr "" msgid "Invalid channel count" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "" @@ -2117,6 +2123,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "" @@ -2795,6 +2809,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index abc7a00a57..3498a11820 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -1199,6 +1199,7 @@ msgstr "Ongeldige %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Ongeldige %q pin" @@ -1269,6 +1270,11 @@ msgstr "Ongeldige vastlegging periode. Geldig bereik: 1 - 500" msgid "Invalid channel count" msgstr "Ongeldige kanaal aantallen" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Ongeldige richting." @@ -2154,6 +2160,14 @@ msgstr "Tijdstip ligt in het verleden." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Time-out is te lang. Maximale time-out lengte is %d seconden" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Om te beëindigen, reset het bord zonder " @@ -2844,6 +2858,11 @@ msgstr "data moet itereerbaar zijn" msgid "data must be of equal length" msgstr "data moet van gelijke lengte zijn" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/pl.po b/locale/pl.po index 1fbc6e4e34..32d839de23 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -1198,6 +1198,7 @@ msgstr "Nieprawidłowe %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Zła nóżka %q" @@ -1268,6 +1269,11 @@ msgstr "Zły okres. Poprawny zakres to: 1 - 500" msgid "Invalid channel count" msgstr "Zła liczba kanałów" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Nieprawidłowy kierunek." @@ -2127,6 +2133,14 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "By wyjść, proszę zresetować płytkę bez " @@ -2810,6 +2824,11 @@ msgstr "" msgid "data must be of equal length" msgstr "" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 6b12165900..1f5b691c79 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -1222,6 +1222,7 @@ msgstr "%q Inválido" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Pino do %q inválido" @@ -1292,6 +1293,11 @@ msgstr "O período de captura é inválido. O intervalo válido é: 1 - 500" msgid "Invalid channel count" msgstr "A contagem do canal é inválido" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Direção inválida." @@ -2186,6 +2192,14 @@ msgstr "" "O tempo limite é long demais: O comprimento máximo do tempo limite é de %d " "segundos" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Para sair, por favor, reinicie a placa sem " @@ -2881,6 +2895,11 @@ msgstr "os dados devem ser iteráveis" msgid "data must be of equal length" msgstr "os dados devem ser de igual comprimento" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "o tipo do dado não foi compreendido" diff --git a/locale/sv.po b/locale/sv.po index 29d7e22ca2..24e7af90a1 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -1206,6 +1206,7 @@ msgstr "Ogiltig %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Ogiltig %q-pinne" @@ -1276,6 +1277,11 @@ msgstr "Ogiltig inspelningsperiod. Giltigt intervall: 1 - 500" msgid "Invalid channel count" msgstr "Ogiltigt kanalantal" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Ogiltig riktning." @@ -2160,6 +2166,14 @@ msgstr "Tid har passerats." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Åtgärden tog för lång tid: Max väntetid är %d sekunder" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "För att avsluta, gör reset på kortet utan " @@ -2847,6 +2861,11 @@ msgstr "data måste vara itererbar" msgid "data must be of equal length" msgstr "data måste vara av samma längd" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "datatyp inte förstådd" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8062dfe3ee..8a21a68f42 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -1208,6 +1208,7 @@ msgstr "wú xiào %q" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Invalid %q pin" msgstr "Wúxiào de %q yǐn jiǎo" @@ -1278,6 +1279,11 @@ msgstr "Wúxiào de bǔhuò zhōuqí. Yǒuxiào fànwéi: 1-500" msgid "Invalid channel count" msgstr "Wúxiào de tōngdào jìshù" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_count %d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." msgstr "Wúxiào de fāngxiàng." @@ -2157,6 +2163,14 @@ msgstr "shí jiān yǐ jīng guò qù." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Chāoshí shíjiān tài zhǎng: Zuìdà chāoshí shíjiān wèi%d miǎo" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for DRDY" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +msgid "Timeout waiting for VSYNC" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " msgstr "Yào tuìchū, qǐng chóng zhì bǎnkuài ér bùyòng " @@ -2847,6 +2861,11 @@ msgstr "shùjù bìxū shì kě diédài de" msgid "data must be of equal length" msgstr "shùjù chángdù bìxū xiāngděng" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "data type not understood" msgstr "wèi lǐ jiě de shù jù lèi xíng" From 7b492773e3c4fde0e100be84f9d84f4b1fc032b6 Mon Sep 17 00:00:00 2001 From: Hugo Dahl Date: Fri, 23 Apr 2021 23:21:39 +0000 Subject: [PATCH 50/69] Translated using Weblate (French) Currently translated at 100.0% (974 of 974 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/fr/ --- locale/fr.po | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index b3df316885..0e8bbe3232 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-22 17:16+0000\n" +"PO-Revision-Date: 2021-04-24 14:29+0000\n" "Last-Translator: Hugo Dahl \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1305,7 +1305,7 @@ msgstr "Nombre de canaux invalide" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_count %d" -msgstr "" +msgstr "data_count invalide %d" #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." @@ -2199,11 +2199,11 @@ msgstr "Le délai est trop long : le délai maximal est de %d secondes" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for DRDY" -msgstr "" +msgstr "Délais expiré en attandant DRDY" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for VSYNC" -msgstr "" +msgstr "Délais expiré en attandant VSYNC" #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " @@ -2499,7 +2499,7 @@ msgstr "adresses vides" #: py/compile.c msgid "annotation must be an identifier" -msgstr "" +msgstr "l'annotation doit être un identificateur" #: py/modbuiltins.c msgid "arg is an empty sequence" @@ -2686,7 +2686,7 @@ msgstr "impossible de convertir %q en %q" #: py/runtime.c msgid "can't convert %q to int" -msgstr "" +msgstr "ne peut convertir %q à int" #: py/objstr.c msgid "can't convert '%q' object to %q implicitly" @@ -2910,7 +2910,7 @@ msgstr "les données doivent être de longueur égale" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "data pin #%d in use" -msgstr "" +msgstr "broche de donnée #%d utilisée" #: extmod/ulab/code/ndarray.c msgid "data type not understood" @@ -3123,7 +3123,7 @@ msgstr "plein" #: py/argcheck.c msgid "function doesn't take keyword arguments" -msgstr "" +msgstr "la fonction n'accepte pas de paramètre nommés" #: py/argcheck.c #, c-format @@ -3179,7 +3179,7 @@ msgstr "le générateur a ignoré GeneratorExit" #: py/objgenerator.c msgid "generator raised StopIteration" -msgstr "" +msgstr "générateur (generator) à surlevé StopIteration" #: shared-bindings/_stage/Layer.c msgid "graphic must be 2048 bytes long" @@ -3567,7 +3567,7 @@ msgstr "nécessite plus de %d valeurs à dégrouper" #: py/modmath.c msgid "negative factorial" -msgstr "" +msgstr "factoriel négatif" #: py/objint_longlong.c py/objint_mpz.c py/runtime.c msgid "negative power with no float support" From a680b37232290663b806dc2a1b453e77d51ef834 Mon Sep 17 00:00:00 2001 From: Jonny Bergdahl Date: Sat, 24 Apr 2021 11:29:42 +0000 Subject: [PATCH 51/69] Translated using Weblate (Swedish) Currently translated at 100.0% (974 of 974 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/sv/ --- locale/sv.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locale/sv.po b/locale/sv.po index 24e7af90a1..8defcb5546 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-23 12:37+0000\n" +"PO-Revision-Date: 2021-04-24 14:29+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -1280,7 +1280,7 @@ msgstr "Ogiltigt kanalantal" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_count %d" -msgstr "" +msgstr "Ogiltig data_count %d" #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." @@ -2168,11 +2168,11 @@ msgstr "Åtgärden tog för lång tid: Max väntetid är %d sekunder" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for DRDY" -msgstr "" +msgstr "Timeout i väntan på DRDY" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for VSYNC" -msgstr "" +msgstr "Timeout i väntan på VSYNC" #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " @@ -2864,7 +2864,7 @@ msgstr "data måste vara av samma längd" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "data pin #%d in use" -msgstr "" +msgstr "data pin #%d används redan" #: extmod/ulab/code/ndarray.c msgid "data type not understood" From a17fcb6d1ab05ff2e6a984e992462130c17812fc Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 25 Apr 2021 19:19:11 +0900 Subject: [PATCH 52/69] add copyright notice. remove obsolete comments. --- ports/nrf/common-hal/alarm/__init__.c | 19 ++++++------------- ports/nrf/common-hal/alarm/__init__.h | 1 + ports/nrf/common-hal/alarm/pin/PinAlarm.c | 1 + ports/nrf/common-hal/alarm/time/TimeAlarm.c | 4 +--- ports/nrf/supervisor/port.c | 1 + supervisor/shared/serial.c | 6 +++--- 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index c8180fb2e0..f678b5f22b 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -5,6 +5,7 @@ * * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -119,11 +120,6 @@ bool common_hal_alarm_woken_from_sleep(void) { nrf_sleep_source_t alarm_woken_from_sleep_2(void) { nrf_sleep_source_t cause = _get_wakeup_cause(); -#ifdef NRF_DEBUG_PRINT - if (cause != NRF_SLEEP_WAKEUP_UNDEFINED) { - //print_wakeup_cause(cause); - } -#endif if (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER || cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { @@ -136,9 +132,6 @@ nrf_sleep_source_t alarm_woken_from_sleep_2(void) { STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); -#ifdef NRF_DEBUG_PRINT - //print_wakeup_cause(cause); -#endif switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); @@ -264,16 +257,16 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres qspi_flash_exit_sleep(); #endif +#ifdef NRF_DEBUG_PRINT tickdiff = port_get_raw_ticks(NULL) - start_tick; + double sec; if (prescaler == 0) { - timediff_ms = tickdiff / 1024; + sec = (double)tickdiff / 1024; } else { - timediff_ms = tickdiff * prescaler / 1024; + sec = (double)(tickdiff * prescaler) / 1024; } - (void)timediff_ms; -#ifdef NRF_DEBUG_PRINT - dbg_printf("lapse %6.1f sec\r\n", (double)(timediff_ms)); + dbg_printf("lapse %6.1f sec\r\n", sec); #endif return wakeup_cause; diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 7df3aaf4c3..642fb7d93a 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2020 Dan Halbert for Adafruit Industries. + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 1f00dc0c33..fcfd02f84c 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -5,6 +5,7 @@ * * Copyright (c) 2020 Dan Halbert for Adafruit Industries * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index c4b06982bf..09409e7ce4 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +25,7 @@ * THE SOFTWARE. */ -//#include "esp_sleep.h" - #include "py/runtime.h" -//#include "supervisor/esp_port.h" #include #include "common-hal/alarm/__init__.h" diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 5cad994c0d..c984feb77d 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 41bb200afc..c73d702c9c 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -39,7 +39,7 @@ #ifdef NRF_DEBUG_PRINT // XXX these functions are in nrf/supervisor/debug_uart.c extern void _debug_uart_init(void); -extern void _debug_print_substr(const char* text, uint32_t length); +extern void _debug_print_substr(const char *text, uint32_t length); #endif /* @@ -71,7 +71,7 @@ void serial_early_init(void) { #endif #ifdef NRF_DEBUG_PRINT - _debug_uart_init(); + _debug_uart_init(); #endif } @@ -155,7 +155,7 @@ void serial_write_substring(const char *text, uint32_t length) { #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) int uart_errcode; - common_hal_busio_uart_write(&debug_uart, (const uint8_t*) text, length, &uart_errcode); + common_hal_busio_uart_write(&debug_uart, (const uint8_t *) text, length, &uart_errcode); #endif #ifdef NRF_DEBUG_PRINT From 7accb8b173ce97979e466bf3d2dc1e7f56300332 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 25 Apr 2021 19:57:21 +0900 Subject: [PATCH 53/69] modify copyright notice. --- .github/workflows/build.yml | 19 +- .github/workflows/match-build-fail.json | 14 ++ .gitmodules | 6 + conf.py | 2 + .../common-hal/_bleio/Characteristic.c | 4 + .../ble_hci/common-hal/_bleio/PacketBuffer.c | 16 +- .../ble_hci/common-hal/_bleio/PacketBuffer.h | 1 + docs/static/filter.css | 17 ++ docs/static/filter.js | 86 +++++++ frozen/Adafruit_CircuitPython_MIDI | 1 + frozen/Adafruit_CircuitPython_SimpleMath | 1 + lib/protomatter | 2 +- locale/ID.po | 74 +++--- locale/circuitpython.pot | 66 +++--- locale/cs.po | 59 +++-- locale/de_DE.po | 81 ++++--- locale/el.po | 59 +++-- locale/en_GB.po | 95 +++++--- locale/es.po | 97 +++++--- locale/fil.po | 62 ++--- locale/fr.po | 169 ++++++++------ locale/hi.po | 59 +++-- locale/it_IT.po | 64 +++--- locale/ja.po | 73 +++--- locale/ko.po | 59 +++-- locale/nl.po | 85 ++++--- locale/pl.po | 75 ++++--- locale/pt_BR.po | 92 +++++--- locale/sv.po | 89 +++++--- locale/zh_Latn_pinyin.po | 103 +++++---- main.c | 18 +- .../board.c | 0 .../mpconfigboard.h | 58 +++++ .../mpconfigboard.mk | 34 +++ .../boards/adafruit_neokey_trinkey_m0/pins.c | 8 + .../adafruit_proxlight_trinkey_m0/board.c | 40 ++++ .../mpconfigboard.h | 58 +++++ .../mpconfigboard.mk | 33 +++ .../adafruit_proxlight_trinkey_m0/pins.c | 15 ++ .../boards/adafruit_rotary_trinkey_m0/board.c | 40 ++++ .../mpconfigboard.h | 0 .../mpconfigboard.mk | 2 +- .../pins.c | 0 .../boards/adafruit_slide_trinkey_m0/board.c | 40 ++++ .../adafruit_slide_trinkey_m0/mpconfigboard.h | 58 +++++ .../mpconfigboard.mk | 35 +++ .../boards/adafruit_slide_trinkey_m0/pins.c | 8 + .../feather_m0_adalogger/mpconfigboard.h | 4 +- .../neopixel_trinkey_m0/mpconfigboard.mk | 2 +- ports/atmel-samd/boards/sensebox_mcu/board.c | 39 ++++ .../boards/sensebox_mcu/mpconfigboard.h | 24 ++ .../boards/sensebox_mcu/mpconfigboard.mk | 14 ++ ports/atmel-samd/boards/sensebox_mcu/pins.c | 71 ++++++ ports/atmel-samd/mpconfigport.mk | 20 ++ .../esp32s2/boards/atmegazero_esp32s2/board.c | 61 +++++ .../boards/atmegazero_esp32s2/mpconfigboard.h | 47 ++++ .../atmegazero_esp32s2/mpconfigboard.mk | 15 ++ .../esp32s2/boards/atmegazero_esp32s2/pins.c | 80 +++++++ .../boards/atmegazero_esp32s2/sdkconfig | 39 ++++ ports/nrf/boards/aramcon2_badge/board.c | 40 ++++ .../nrf/boards/aramcon2_badge/mpconfigboard.h | 68 ++++++ .../boards/aramcon2_badge/mpconfigboard.mk | 11 + ports/nrf/boards/aramcon2_badge/pins.c | 42 ++++ ports/nrf/boards/pca10100/mpconfigboard.mk | 1 + ports/nrf/boards/simmel/mpconfigboard.mk | 5 + ports/nrf/common-hal/_bleio/Characteristic.c | 4 + ports/nrf/common-hal/_bleio/PacketBuffer.c | 34 ++- ports/nrf/common-hal/_bleio/PacketBuffer.h | 1 + ports/nrf/common-hal/alarm/SleepMemory.c | 25 +-- ports/nrf/common-hal/alarm/SleepMemory.h | 2 +- ports/nrf/common-hal/alarm/__init__.c | 111 ++++----- ports/nrf/common-hal/alarm/__init__.h | 14 +- ports/nrf/common-hal/alarm/pin/PinAlarm.c | 26 +-- ports/nrf/common-hal/alarm/pin/PinAlarm.h | 2 +- ports/nrf/common-hal/alarm/time/TimeAlarm.h | 2 +- .../common-hal/microcontroller/Processor.c | 6 +- ports/nrf/mpconfigport.mk | 2 +- ports/nrf/supervisor/debug_uart.c | 129 ++++++----- ports/nrf/supervisor/port.c | 4 + ports/nrf/supervisor/qspi_flash.c | 24 +- .../boards/pimoroni_picolipo_16mb/board.c | 37 +++ .../pimoroni_picolipo_16mb/mpconfigboard.h | 10 + .../pimoroni_picolipo_16mb/mpconfigboard.mk | 11 + .../boards/pimoroni_picolipo_16mb/pins.c | 52 +++++ .../boards/pimoroni_picolipo_4mb/board.c | 37 +++ .../pimoroni_picolipo_4mb/mpconfigboard.h | 10 + .../pimoroni_picolipo_4mb/mpconfigboard.mk | 11 + .../boards/pimoroni_picolipo_4mb/pins.c | 52 +++++ .../boards/raspberry_pi_pico/pins.c | 10 + .../boards/sparkfun_micromod_rp2040/board.c | 40 ++++ .../sparkfun_micromod_rp2040/mpconfigboard.h | 12 + .../sparkfun_micromod_rp2040/mpconfigboard.mk | 9 + .../boards/sparkfun_micromod_rp2040/pins.c | 105 +++++++++ ports/raspberrypi/mpconfigport.mk | 3 +- .../mpconfigboard.mk | 2 + py/binary.c | 6 +- py/circuitpy_defns.mk | 5 + py/circuitpy_mpconfig.h | 8 + py/circuitpy_mpconfig.mk | 3 + py/compile.c | 2 +- py/makeqstrdata.py | 50 ++--- py/modstruct.c | 6 +- py/mpstate.h | 2 +- py/qstr.c | 130 ++++++----- py/qstr.h | 20 +- py/repl.c | 13 +- shared-bindings/_bleio/Characteristic.c | 17 ++ shared-bindings/_bleio/Characteristic.h | 1 + shared-bindings/_bleio/PacketBuffer.c | 20 +- shared-bindings/_bleio/PacketBuffer.h | 2 +- shared-bindings/_typing/__init__.pyi | 3 +- shared-bindings/audiocore/RawSample.c | 26 +-- shared-bindings/audiocore/RawSample.h | 1 - shared-bindings/audiocore/WaveFile.c | 2 +- shared-bindings/support_matrix.rst | 5 + shared-bindings/synthio/MidiTrack.c | 169 ++++++++++++++ shared-bindings/synthio/MidiTrack.h | 43 ++++ shared-bindings/synthio/__init__.c | 136 +++++++++++ shared-bindings/synthio/__init__.h | 34 +++ shared-module/audiomixer/Mixer.c | 45 ++++ shared-module/struct/__init__.c | 6 +- shared-module/synthio/MidiTrack.c | 212 ++++++++++++++++++ shared-module/synthio/MidiTrack.h | 65 ++++++ shared-module/synthio/__init__.c | 0 shared-module/synthio/__init__.h | 32 +++ supervisor/shared/cpu.c | 40 ++++ supervisor/shared/cpu.h | 36 +++ supervisor/shared/safe_mode.c | 6 +- supervisor/shared/serial.c | 11 +- supervisor/shared/translate.c | 2 +- supervisor/supervisor.mk | 1 + tests/basics/struct1.py | 2 + .../audiocore/single-track.midi | Bin 0 -> 5123 bytes tools/build_board_info.py | 2 +- tools/mpy-tool.py | 27 ++- 135 files changed, 3646 insertions(+), 992 deletions(-) create mode 100644 .github/workflows/match-build-fail.json create mode 100644 docs/static/filter.css create mode 100644 docs/static/filter.js create mode 160000 frozen/Adafruit_CircuitPython_MIDI create mode 160000 frozen/Adafruit_CircuitPython_SimpleMath rename ports/atmel-samd/boards/{rotary_trinkey_m0 => adafruit_neokey_trinkey_m0}/board.c (100%) create mode 100644 ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/pins.c create mode 100644 ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c create mode 100644 ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/pins.c create mode 100644 ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c rename ports/atmel-samd/boards/{rotary_trinkey_m0 => adafruit_rotary_trinkey_m0}/mpconfigboard.h (100%) rename ports/atmel-samd/boards/{rotary_trinkey_m0 => adafruit_rotary_trinkey_m0}/mpconfigboard.mk (97%) rename ports/atmel-samd/boards/{rotary_trinkey_m0 => adafruit_rotary_trinkey_m0}/pins.c (100%) create mode 100644 ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c create mode 100644 ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/adafruit_slide_trinkey_m0/pins.c create mode 100644 ports/atmel-samd/boards/sensebox_mcu/board.c create mode 100644 ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/sensebox_mcu/pins.c create mode 100644 ports/esp32s2/boards/atmegazero_esp32s2/board.c create mode 100644 ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h create mode 100644 ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.mk create mode 100644 ports/esp32s2/boards/atmegazero_esp32s2/pins.c create mode 100644 ports/esp32s2/boards/atmegazero_esp32s2/sdkconfig create mode 100644 ports/nrf/boards/aramcon2_badge/board.c create mode 100644 ports/nrf/boards/aramcon2_badge/mpconfigboard.h create mode 100644 ports/nrf/boards/aramcon2_badge/mpconfigboard.mk create mode 100644 ports/nrf/boards/aramcon2_badge/pins.c create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_16mb/pins.c create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/pimoroni_picolipo_4mb/pins.c create mode 100644 ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c create mode 100644 ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c create mode 100644 shared-bindings/synthio/MidiTrack.c create mode 100644 shared-bindings/synthio/MidiTrack.h create mode 100644 shared-bindings/synthio/__init__.c create mode 100644 shared-bindings/synthio/__init__.h create mode 100644 shared-module/synthio/MidiTrack.c create mode 100644 shared-module/synthio/MidiTrack.h create mode 100644 shared-module/synthio/__init__.c create mode 100644 shared-module/synthio/__init__.h create mode 100644 supervisor/shared/cpu.c create mode 100644 supervisor/shared/cpu.h create mode 100755 tests/circuitpython-manual/audiocore/single-track.midi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dce5388211..6d58085929 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -178,8 +178,13 @@ jobs: - "TG-Watch" - "adafruit_feather_rp2040" - "adafruit_itsybitsy_rp2040" + - "adafruit_neokey_trinkey_m0" + - "adafruit_proxlight_trinkey_m0" - "adafruit_qtpy_rp2040" + - "adafruit_rotary_trinkey_m0" + - "adafruit_slide_trinkey_m0" - "aloriumtech_evo_m51" + - "aramcon2_badge" - "aramcon_badge_2019" - "arduino_mkr1300" - "arduino_mkrzero" @@ -285,6 +290,8 @@ jobs: - "pewpew_m4" - "picoplanet" - "pimoroni_keybow2040" + - "pimoroni_picolipo_16mb" + - "pimoroni_picolipo_4mb" - "pimoroni_picosystem" - "pimoroni_tiny2040" - "pirkey_m0" @@ -305,17 +312,18 @@ jobs: - "raspberry_pi_pico" - "raytac_mdbt50q-db-40" - "robohatmm1_m4" - - "rotary_trinkey_m0" - "sam32" - "same54_xplained" - "seeeduino_wio_terminal" - "seeeduino_xiao" + - "sensebox_mcu" - "serpente" - "shirtty" - "silicognition-m4-shim" - "simmel" - "snekboard" - "sparkfun_lumidrive" + - "sparkfun_micromod_rp2040" - "sparkfun_nrf52840_micromod" - "sparkfun_nrf52840_mini" - "sparkfun_pro_micro_rp2040" @@ -375,6 +383,8 @@ jobs: python3 --version - name: mpy-cross run: make -C mpy-cross -j2 + - name: Setup build failure matcher + run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json" - name: build run: python3 -u build_release_files.py working-directory: tools @@ -424,6 +434,8 @@ jobs: python3 --version - name: mpy-cross run: make -C mpy-cross -j2 + - name: Setup build failure matcher + run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json" - name: build run: python3 -u build_release_files.py working-directory: tools @@ -453,6 +465,7 @@ jobs: - "adafruit_magtag_2.9_grayscale" - "adafruit_metro_esp32s2" - "artisense_rd00" + - "atmegazero_esp32s2" - "electroniccats_bastwifi" - "espressif_kaluga_1" - "espressif_saola_1_wroom" @@ -485,7 +498,7 @@ jobs: id: idf-cache with: path: ${{ github.workspace }}/.idf_tools - key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20210304 + key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20210415 - name: Clone IDF submodules run: | (cd $IDF_PATH && git submodule update --init) @@ -522,6 +535,8 @@ jobs: IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools - name: mpy-cross run: make -C mpy-cross -j2 + - name: Setup build failure matcher + run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json" - name: build run: | source $IDF_PATH/export.sh diff --git a/.github/workflows/match-build-fail.json b/.github/workflows/match-build-fail.json new file mode 100644 index 0000000000..938c484f26 --- /dev/null +++ b/.github/workflows/match-build-fail.json @@ -0,0 +1,14 @@ +{ + "problemMatcher": [ + { + "severity": "error", + "pattern": [ + { + "regexp": "^(Build .+ and \\x1b\\[31mfailed\\x1b\\[0m)$", + "message": 1 + } + ], + "owner": "build-failed" + } + ] +} diff --git a/.gitmodules b/.gitmodules index 52abb02a99..da5b5835a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -171,6 +171,9 @@ [submodule "frozen/Adafruit_CircuitPython_LC709203F"] path = frozen/Adafruit_CircuitPython_LC709203F url = https://github.com/adafruit/Adafruit_CircuitPython_LC709203F +[submodule "frozen/Adafruit_CircuitPython_SimpleMath"] + path = frozen/Adafruit_CircuitPython_SimpleMath + url = https://github.com/adafruit/Adafruit_CircuitPython_SimpleMath [submodule "ports/raspberrypi/sdk"] path = ports/raspberrypi/sdk url = https://github.com/adafruit/pico-sdk.git @@ -178,3 +181,6 @@ path = data/nvm.toml url = https://github.com/adafruit/nvm.toml.git branch = main +[submodule "frozen/Adafruit_CircuitPython_MIDI"] + path = frozen/Adafruit_CircuitPython_MIDI + url = https://github.com/adafruit/Adafruit_CircuitPython_MIDI diff --git a/conf.py b/conf.py index 44f86f6361..2625ad63c1 100644 --- a/conf.py +++ b/conf.py @@ -489,6 +489,8 @@ class CoreModuleTransform(SphinxTransform): def setup(app): app.add_css_file("customstyle.css") + app.add_css_file("filter.css") + app.add_js_file("filter.js") app.add_config_value('redirects_file', 'redirects', 'env') app.connect('builder-inited', generate_redirects) app.add_transform(CoreModuleTransform) diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.c b/devices/ble_hci/common-hal/_bleio/Characteristic.c index 7255661576..db1317f4c8 100644 --- a/devices/ble_hci/common-hal/_bleio/Characteristic.c +++ b/devices/ble_hci/common-hal/_bleio/Characteristic.c @@ -78,6 +78,10 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character return self->service; } +size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) { + return self->max_length; +} + size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len) { // Do GATT operations only if this characteristic has been added to a registered service. if (self->handle != BLE_GATT_HANDLE_INVALID) { diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c index 9d8a21601d..cb14f4044b 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c @@ -81,7 +81,7 @@ void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_ void common_hal_bleio_packet_buffer_construct( bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, - size_t buffer_size) { + size_t buffer_size, size_t max_packet_size) { self->characteristic = characteristic; self->client = self->characteristic->service->is_remote; @@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct( } if (incoming) { - if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) { + if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) { mp_raise_ValueError(translate("Buffer too large and unable to allocate")); } } @@ -110,12 +110,13 @@ void common_hal_bleio_packet_buffer_construct( self->packet_queued = false; self->pending_index = 0; self->pending_size = 0; - self->outgoing[0] = m_malloc(characteristic->max_length, false); - self->outgoing[1] = m_malloc(characteristic->max_length, false); + self->outgoing[0] = m_malloc(max_packet_size, false); + self->outgoing[1] = m_malloc(max_packet_size, false); } else { self->outgoing[0] = NULL; self->outgoing[1] = NULL; } + self->max_packet_size = max_packet_size; bleio_characteristic_set_observer(self->characteristic, self); } @@ -243,15 +244,16 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) { bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle); if (connection) { - return MIN(common_hal_bleio_connection_get_max_packet_length(connection), - self->characteristic->max_length); + return MIN(MIN(common_hal_bleio_connection_get_max_packet_length(connection), + self->max_packet_size), + self->characteristic->max_length); } } // There's no current connection, so we don't know the MTU, and // we can't tell what the largest outgoing packet length would be. return -1; } - return self->characteristic->max_length; + return MIN(self->characteristic->max_length, self->max_packet_size); } bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.h b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h index 7f351929d5..34471741fe 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.h +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h @@ -42,6 +42,7 @@ typedef struct { // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client. // We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read). volatile uint16_t conn_handle; + uint16_t max_packet_size; uint8_t pending_index; uint8_t write_type; bool client; diff --git a/docs/static/filter.css b/docs/static/filter.css new file mode 100644 index 0000000000..12efe14a40 --- /dev/null +++ b/docs/static/filter.css @@ -0,0 +1,17 @@ +#support-matrix-filter-block { position: relative; } +#support-matrix-filter { + width: 100%; +} +#support-matrix-filter-num { + position: absolute; + right: 10px; + top: 4px; +} +.support-matrix-table .this_module code, +.support-matrix-table .this_module span { + background: black; + color: white; +} +.support-matrix-table .board_hidden { + display: none; +} diff --git a/docs/static/filter.js b/docs/static/filter.js new file mode 100644 index 0000000000..9dc46a9eed --- /dev/null +++ b/docs/static/filter.js @@ -0,0 +1,86 @@ +$(() => { + var urlTimeout = null; + function setURL(query, value) { + clearTimeout(urlTimeout); + + urlTimeout = setTimeout(function() { + var url = new URL(window.location.href); + console.log(query,value,value.length,!value.length); + if (!value.length) { + console.log + url.searchParams.delete(query); + } else if (Array.isArray(value)) { + url.searchParams.delete(query); + value.forEach(function(v) { + url.searchParams.append(query, v); + }) + } else { + url.searchParams.set(query, value); + } + + window.history.pushState(null, document.title, url.href); + }, 1000); + } + + function handlePageLoad() { + var url = new URL(window.location.href); + //get values from URL + var filters = url.searchParams.getAll('filter'); + search_terms = filters.join(" "); + $("#support-matrix-filter").val(search_terms); + run_filter(); + } + + function filter_boards(search_string) { + $(".board_hidden").removeClass("board_hidden"); + $(".this_module").removeClass("this_module"); + var nboards = $(".support-matrix-table tbody tr").length; + if(search_string.trim() == "") { + $("#support-matrix-filter-num").html("(all)"); + setURL("filter",[]); + return; + } + var list_search = search_string.split(" ").filter(i => i); + var nvisible = 0; + $(".support-matrix-table tbody tr").each( (index,item) => { + var name = $(item).find("td:first-child p").html(); + var modules = $(item).find("a.reference.internal"); + var matching_all = true; + // + list_search.forEach((sstring) => { + var matching = (sstring[0] == "-"); + for(var modi = 0; modi < modules.length; ++modi) { + module = modules[modi]; + var mod_name = module.firstChild.firstChild.textContent; + if(sstring[0] == "-") { + if(mod_name.match(sstring.substr(1))) { + matching = false; + break; + } + } else { + if(mod_name.match(sstring)) { + $(module).addClass("this_module"); + matching = true; + } + } + } + matching_all = matching_all && matching; + }); + if(!matching_all) { + $(item).addClass("board_hidden"); + } else { + nvisible += 1; + } + }); + $("#support-matrix-filter-num").html(`(${nvisible}/${nboards})`); + setURL("filter",list_search); + } + + function run_filter() { + var search_string = $("#support-matrix-filter").val(); + filter_boards(search_string); + } + $("#support-matrix-filter").on("keyup", run_filter); + // $(document).on("keyup", "#support-matrix-filter", run_filter); + handlePageLoad(); +}); diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI new file mode 160000 index 0000000000..669ab7b752 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -0,0 +1 @@ +Subproject commit 669ab7b752d6c863577312560faf505656e5e603 diff --git a/frozen/Adafruit_CircuitPython_SimpleMath b/frozen/Adafruit_CircuitPython_SimpleMath new file mode 160000 index 0000000000..cdf9944730 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_SimpleMath @@ -0,0 +1 @@ +Subproject commit cdf99447307473080b2f2e95e7c3667247095ac0 diff --git a/lib/protomatter b/lib/protomatter index c2c81ded11..98017c5734 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit c2c81ded118484f8925bf81e270b416739cd72d9 +Subproject commit 98017c57349e259fab70c6a7830436b19a55f6f4 diff --git a/locale/ID.po b/locale/ID.po index ad5700cb99..ea16feddb8 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -445,8 +445,8 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "Mencoba alokasi heap ketika MicroPython VM tidak berjalan." +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -899,6 +899,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "Channel EXTINT sedang digunakan" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Error pada regex" @@ -1028,6 +1033,10 @@ msgstr "Gagal melepaskan mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Gagal menulis flash internal." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "File sudah ada" @@ -1100,10 +1109,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1229,6 +1234,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "Pin DAC yang diberikan tidak valid" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1420,14 +1429,6 @@ msgstr "Nilai x maksimum ketika dicerminkan adalah %d" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "Lompatan NLR MicroPython gagal. Kemungkinan kerusakan memori." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Kesalahan fatal MicroPython." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Penundaan mulai mikrofon harus dalam kisaran 0,0 hingga 1,0" @@ -1479,6 +1480,10 @@ msgstr "Harus menyediakan pin MISO atau MOSI" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Harus menggunakan kelipatan 6 pin rgb, bukan %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1623,6 +1628,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -1847,8 +1853,8 @@ msgstr "Buffer awalan harus ada di heap" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" -"Tekan sembarang tombol untuk masuk ke REPL. Tekan CTRL-D untuk memuat ulang." -"\n" +"Tekan sembarang tombol untuk masuk ke REPL. Tekan CTRL-D untuk memuat " +"ulang.\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" @@ -2543,10 +2549,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2988,7 +2990,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3244,6 +3246,10 @@ msgstr "" msgid "invalid cert" msgstr "cert tidak valid" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "indeks dupterm tidak valid" @@ -3299,10 +3305,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3763,6 +3765,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3788,6 +3791,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4061,10 +4068,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4199,10 +4202,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4289,6 +4288,15 @@ msgstr "zi harus berjenis float" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "Mencoba alokasi heap ketika MicroPython VM tidak berjalan." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "Lompatan NLR MicroPython gagal. Kemungkinan kerusakan memori." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Kesalahan fatal MicroPython." + #~ msgid "Nordic Soft Device failure assertion." #~ msgstr "Pernyataan kegagalan Perangkat Lunak Nordic." diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1245f17840..2a43daf014 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -309,10 +309,6 @@ msgstr "" msgid "Address type out of range" msgstr "" -#: ports/nrf/common-hal/alarm/time/TimeAlarm.c -msgid "Alarm time must be < 512 seconds." -msgstr "" - #: ports/esp32s2/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" msgstr "" @@ -442,7 +438,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -884,6 +880,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "" @@ -1013,6 +1014,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1085,10 +1090,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1212,6 +1213,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1404,14 +1409,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1463,6 +1460,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1607,6 +1608,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2133,7 +2135,7 @@ msgid "Too many displays" msgstr "" #: ports/nrf/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than outgoing_packet_length" +msgid "Total data to write is larger than %q" msgstr "" #: py/obj.c @@ -2500,10 +2502,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2945,7 +2943,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3201,6 +3199,10 @@ msgstr "" msgid "invalid cert" msgstr "" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "" @@ -3256,10 +3258,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3719,6 +3717,8 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h +#: ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3744,6 +3744,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4017,10 +4021,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4155,10 +4155,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 654023f1f5..9bed9ec3c6 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -441,7 +441,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -882,6 +882,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "" @@ -1011,6 +1016,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1083,10 +1092,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1210,6 +1215,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1401,14 +1410,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1460,6 +1461,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1604,6 +1609,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2496,10 +2502,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2941,7 +2943,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3197,6 +3199,10 @@ msgstr "" msgid "invalid cert" msgstr "" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "" @@ -3252,10 +3258,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3715,6 +3717,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3740,6 +3743,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4013,10 +4020,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4151,10 +4154,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index e3e2ddbd45..3a64342366 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -447,10 +447,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Versuche %d Blöcke zu allokieren" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" -"Versuch einer Heap Reservierung, wenn die MicroPython-VM nicht ausgeführt " -"wird." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -899,6 +897,11 @@ msgstr "ESP-IDF Speicherallozierung fehlgeschlagen" msgid "EXTINT channel already in use" msgstr "EXTINT Kanal ist schon in Benutzung" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Fehler in regex" @@ -1029,6 +1032,10 @@ msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" msgid "Failed to write internal flash." msgstr "Interner Flash konnte nicht geschrieben werden." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "Datei existiert" @@ -1103,10 +1110,6 @@ msgstr "I2C Peripherie in Verwendung" msgid "I2SOut not available" msgstr "I2SOut nicht verfügbar" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOs 0, 2 & 4 unterstützen keinen internen Pull up im sleep-Modus" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1232,6 +1235,10 @@ msgstr "Ungültige BSSID" msgid "Invalid DAC pin supplied" msgstr "Ungültiger DAC-Pin angegeben" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1423,15 +1430,6 @@ msgstr "Maximaler x-Wert beim Spiegeln ist %d" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" -"MicroPython NLR-Sprung fehlgeschlagen. Wahrscheinlich Speicherbeschädigung." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Schwerwiegender MicroPython-Fehler." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1484,6 +1482,10 @@ msgstr "Muss MISO- oder MOSI-Pin bereitstellen" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Muss ein Vielfaches von 6 RGB-Pins verwenden, nicht %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1628,6 +1630,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2560,10 +2563,6 @@ msgstr "Zweig ist außerhalb der Reichweite" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "Puffer muss ein bytes-artiges Objekt sein" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -3017,7 +3016,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: einzelne '}' nicht erlaubt" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "Die Datei muss eine im Byte-Modus geöffnete Datei sein" @@ -3275,6 +3274,10 @@ msgstr "" msgid "invalid cert" msgstr "ungültiges cert" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "ungültiger dupterm index" @@ -3330,10 +3333,6 @@ msgstr "ungültige Syntax für integer mit Basis %d" msgid "invalid syntax for number" msgstr "ungültige Syntax für number" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 muss eine Klasse sein" @@ -3803,6 +3802,7 @@ msgstr "pow () mit 3 Argumenten erfordert Integer" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3828,6 +3828,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4104,10 +4108,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tupel/list hat falsche Länge" @@ -4246,10 +4246,6 @@ msgstr "Wert muss in %d Byte(s) passen" msgid "value_count must be > 0" msgstr "value_count muss größer als 0 sein" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4336,6 +4332,25 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOs 0, 2 & 4 unterstützen keinen internen Pull up im sleep-Modus" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "Puffer muss ein bytes-artiges Objekt sein" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "" +#~ "Versuch einer Heap Reservierung, wenn die MicroPython-VM nicht ausgeführt " +#~ "wird." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "" +#~ "MicroPython NLR-Sprung fehlgeschlagen. Wahrscheinlich " +#~ "Speicherbeschädigung." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Schwerwiegender MicroPython-Fehler." + #~ msgid "argument must be ndarray" #~ msgstr "Argument muss ein ndarray sein" diff --git a/locale/el.po b/locale/el.po index 1f7fabf381..c150ef8258 100644 --- a/locale/el.po +++ b/locale/el.po @@ -438,7 +438,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -879,6 +879,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "" @@ -1008,6 +1013,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1080,10 +1089,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1207,6 +1212,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1398,14 +1407,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1457,6 +1458,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1601,6 +1606,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2493,10 +2499,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2938,7 +2940,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3194,6 +3196,10 @@ msgstr "" msgid "invalid cert" msgstr "" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "" @@ -3249,10 +3255,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3712,6 +3714,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3737,6 +3740,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4010,10 +4017,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4148,10 +4151,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index 135f738872..d3859c7c9e 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2021-03-25 23:30+0000\n" -"Last-Translator: Gareth Coleman \n" +"PO-Revision-Date: 2021-04-11 01:30+0000\n" +"Last-Translator: Hugo Dahl \n" "Language-Team: none\n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5.2-dev\n" +"X-Generator: Weblate 4.6-dev\n" #: main.c msgid "" @@ -447,9 +447,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Attempt to allocate %d blocks" #: supervisor/shared/safe_mode.c -#, fuzzy -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "Attempted heap allocation when CircuitPython VM not running." +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -895,6 +894,11 @@ msgstr "ESP-IDF memory allocation failed" msgid "EXTINT channel already in use" msgstr "EXTINT channel already in use" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Error in regex" @@ -1024,6 +1028,10 @@ msgstr "Failed to release mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Failed to write internal flash." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "File exists" @@ -1096,10 +1104,6 @@ msgstr "I2C peripheral in use" msgid "I2SOut not available" msgstr "I2SOut not available" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOs 0, 2 & 4 do not support internal pullup in sleep" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1225,6 +1229,10 @@ msgstr "Invalid BSSID" msgid "Invalid DAC pin supplied" msgstr "Invalid DAC pin supplied" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1416,16 +1424,6 @@ msgstr "Maximum x value when mirrored is %d" msgid "Messages limited to 8 bytes" msgstr "Messages limited to 8 bytes" -#: supervisor/shared/safe_mode.c -#, fuzzy -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "CircuitPython NLR jump failed. Likely memory corruption." - -#: supervisor/shared/safe_mode.c -#, fuzzy -msgid "MicroPython fatal error." -msgstr "CircuitPython fatal error." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Microphone startup delay must be in range 0.0 to 1.0" @@ -1477,6 +1475,10 @@ msgstr "Must provide MISO or MOSI pin" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Must use a multiple of 6 rgb pins, not %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "NVS Error" @@ -1621,6 +1623,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "Not a valid IP string" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2540,10 +2543,6 @@ msgstr "Branch not in range" msgid "buffer is smaller than requested size" msgstr "Buffer is smaller than requested size" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "Buffer must be a bytes-like object" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "Buffer size must be a multiple of element size" @@ -2988,7 +2987,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: single '}' is not allowed" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "file must be a file opened in byte mode" @@ -3244,6 +3243,10 @@ msgstr "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgid "invalid cert" msgstr "invalid cert" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "invalid dupterm index" @@ -3300,10 +3303,6 @@ msgstr "invalid syntax for integer with base %d" msgid "invalid syntax for number" msgstr "invalid syntax for number" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "io must be rtc io" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 must be a class" @@ -3763,6 +3762,7 @@ msgstr "pow() with 3 arguments requires integers" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3788,6 +3788,10 @@ msgstr "pressing boot button at start up.\n" msgid "pressing both buttons at start up.\n" msgstr "pressing both buttons at start up.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "pull masks conflict with direction masks" @@ -4063,10 +4067,6 @@ msgstr "trapz is defined for 1D arrays" msgid "trapz is defined for 1D arrays of equal length" msgstr "trapz is defined for 1D arrays of equal length" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "trigger level must be 0 or 1" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tuple/list has wrong length" @@ -4201,10 +4201,6 @@ msgstr "value must fit in %d byte(s)" msgid "value_count must be > 0" msgstr "value_count must be > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "wakeup conflict" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "WatchDog not initialised" @@ -4291,6 +4287,31 @@ msgstr "zi must be of float type" msgid "zi must be of shape (n_section, 2)" msgstr "zi must be of shape (n_section, 2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOs 0, 2 & 4 do not support internal pullup in sleep" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "Buffer must be a bytes-like object" + +#~ msgid "io must be rtc io" +#~ msgstr "io must be rtc io" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "trigger level must be 0 or 1" + +#~ msgid "wakeup conflict" +#~ msgstr "wakeup conflict" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "Attempted heap allocation when MicroPython VM not running." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLR jump failed. Likely memory corruption." + +#, fuzzy +#~ msgid "MicroPython fatal error." +#~ msgstr "CircuitPython fatal error." + #~ msgid "argument must be ndarray" #~ msgstr "argument must be ndarray" diff --git a/locale/es.po b/locale/es.po index 2f7a7a7b9c..6339727b8c 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-05 22:35+0000\n" -"Last-Translator: Jose David M \n" +"PO-Revision-Date: 2021-04-15 14:26+0000\n" +"Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -426,7 +426,7 @@ msgstr "El pin proporcionado no soporta AnalogOut" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" -msgstr "" +msgstr "Otra salida PWMAudioOut esta ya activada" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c @@ -451,10 +451,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Tratando de localizar %d bloques" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "" -"Se intentó asignación del montículo, sin que la VM de MicroPython esté " -"ejecutando." +msgid "Attempted heap allocation when VM not running." +msgstr "Asignación del montículo mientras la VM no esta ejecutándose." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -905,6 +903,11 @@ msgstr "Fallo ESP-IDF al tomar la memoria" msgid "EXTINT channel already in use" msgstr "El canal EXTINT ya está siendo utilizado" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "Error en el flujo MIDI en la posición %d" + #: extmod/modure.c msgid "Error in regex" msgstr "Error en regex" @@ -1007,7 +1010,7 @@ msgstr "Fallo al tomar memoria para búsqueda wifi" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Failed to buffer the sample" -msgstr "" +msgstr "Fallo al hacer el búfer de la muestra" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to connect: internal error" @@ -1034,6 +1037,10 @@ msgstr "No se puede liberar el mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Error al escribir el flash interno." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "Error grave." + #: py/moduerrno.c msgid "File exists" msgstr "El archivo ya existe" @@ -1107,10 +1114,6 @@ msgstr "Dispositivo I2C en uso" msgid "I2SOut not available" msgstr "I2SOut no disponible" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOs 0, 2 y 4 no soportan pullup interno durante sleep" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1243,6 +1246,10 @@ msgstr "BSSID inválido" msgid "Invalid DAC pin supplied" msgstr "Pin suministrado inválido para DAC" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "Archivo MIDI inválido" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1434,14 +1441,6 @@ msgstr "Valor máximo de x cuando se refleja es %d" msgid "Messages limited to 8 bytes" msgstr "Mensajes limitados a 8 bytes" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "MicroPython NLR jump falló. Probable corrupción de la memoria." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Error fatal de MicroPython." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0" @@ -1497,6 +1496,10 @@ msgstr "Debe proporcionar un pin MISO o MOSI" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Debe usar un múltiplo de 6 pines rgb, no %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "Salto NLR falló. Probablemente corrupción de memoria." + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "Error NVS" @@ -1641,6 +1644,7 @@ msgstr "El firmware del sistema Nordic no tiene memoria" msgid "Not a valid IP string" msgstr "No es una cadena de IP válida" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2573,10 +2577,6 @@ msgstr "la rama no está dentro del rango" msgid "buffer is smaller than requested size" msgstr "El buffer es mas pequeño que el requerido" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "buffer debe de ser un objeto bytes-like" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "El tamaño del buffer debe ser un múltiplo del tamaño del elemento" @@ -3025,7 +3025,7 @@ msgid "f-string: single '}' is not allowed" msgstr "cadena-f: solo '}' no está permitido" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "el archivo deberia ser una archivo abierto en modo byte" @@ -3281,6 +3281,10 @@ msgstr "los bits_per_pixel %d no son validos, deben ser 1, 4, 8, 16, 24 o 32" msgid "invalid cert" msgstr "certificado inválido" +#: py/compile.c +msgid "invalid decorator" +msgstr "decorador invalido" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "index dupterm inválido" @@ -3336,10 +3340,6 @@ msgstr "sintaxis inválida para entero con base %d" msgid "invalid syntax for number" msgstr "sintaxis inválida para número" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "io debe ser rtc io" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 debe ser una clase" @@ -3806,6 +3806,7 @@ msgstr "pow() con 3 argumentos requiere enteros" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3831,6 +3832,10 @@ msgstr "presionando botón de arranque al inicio.\n" msgid "pressing both buttons at start up.\n" msgstr "presionando ambos botones al inicio.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "máscara de pull en conflicto con máscara de dirección" @@ -4107,10 +4112,6 @@ msgstr "trapz esta definido para matrices 1D" msgid "trapz is defined for 1D arrays of equal length" msgstr "trapz está definido para arreglos 1D de igual tamaño" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "nivel de accionamiento debe ser 0 o 1" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tupla/lista tiene una longitud incorrecta" @@ -4245,10 +4246,6 @@ msgstr "el valor debe caber en %d byte(s)" msgid "value_count must be > 0" msgstr "value_count debe ser > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "conflicto de wakeup" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog no inicializado" @@ -4335,6 +4332,32 @@ msgstr "zi debe ser de tipo flotante" msgid "zi must be of shape (n_section, 2)" msgstr "zi debe ser una forma (n_section,2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOs 0, 2 y 4 no soportan pullup interno durante sleep" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "buffer debe de ser un objeto bytes-like" + +#~ msgid "io must be rtc io" +#~ msgstr "io debe ser rtc io" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "nivel de accionamiento debe ser 0 o 1" + +#~ msgid "wakeup conflict" +#~ msgstr "conflicto de wakeup" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "" +#~ "Se intentó asignación del montículo, sin que la VM de MicroPython esté " +#~ "ejecutando." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLR jump falló. Probable corrupción de la memoria." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Error fatal de MicroPython." + #~ msgid "argument must be ndarray" #~ msgstr "argumento debe ser ndarray" diff --git a/locale/fil.po b/locale/fil.po index 23d1be9718..3248eb0ce2 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -441,7 +441,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -890,6 +890,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "Ginagamit na ang EXTINT channel" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "May pagkakamali sa REGEX" @@ -1021,6 +1026,10 @@ msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "Mayroong file" @@ -1093,10 +1102,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1222,6 +1227,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1413,14 +1422,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Ang delay ng startup ng mikropono ay dapat na nasa 0.0 hanggang 1.0" @@ -1472,6 +1473,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1616,6 +1621,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy @@ -2523,10 +2529,6 @@ msgstr "branch wala sa range" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "buffer ay dapat bytes-like object" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2980,7 +2982,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "file ay dapat buksan sa byte mode" @@ -3237,6 +3239,10 @@ msgstr "" msgid "invalid cert" msgstr "mali ang cert" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "mali ang dupterm index" @@ -3292,10 +3298,6 @@ msgstr "maling sintaks sa integer na may base %d" msgid "invalid syntax for number" msgstr "maling sintaks sa number" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 ay dapat na class" @@ -3761,6 +3763,7 @@ msgstr "pow() na may 3 argumento kailangan ng integers" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3786,6 +3789,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4063,10 +4070,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "mali ang haba ng tuple/list" @@ -4201,10 +4204,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4293,6 +4292,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "buffer ay dapat bytes-like object" + #~ msgid "Group full" #~ msgstr "Puno ang group" diff --git a/locale/fr.po b/locale/fr.po index 19d98f770a..eb56894ff2 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-03 21:57+0000\n" +"PO-Revision-Date: 2021-04-17 03:26+0000\n" "Last-Translator: Hugo Dahl \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -426,7 +426,7 @@ msgstr "'AnalogOut' n'est pas supporté sur la broche indiquée" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" -msgstr "" +msgstr "Un autre PWMAudioOut est déjà actif" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c @@ -435,11 +435,11 @@ msgstr "Un autre envoi est déjà actif" #: shared-bindings/pulseio/PulseOut.c msgid "Array must contain halfwords (type 'H')" -msgstr "Le tableau doit contenir des demi-mots (type 'H')" +msgstr "La matrice doit contenir des demi-mots (type 'H')" #: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." -msgstr "Les valeurs du tableau doivent être des octets singuliers." +msgstr "Les valeurs de la matrice doivent être des octets singuliers." #: shared-bindings/microcontroller/Pin.c msgid "At most %d %q may be specified (not %d)" @@ -451,10 +451,10 @@ msgid "Attempt to allocate %d blocks" msgstr "Tentative d'allocation de %d blocs" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" -"Tentative d'allocation de segments lorsque la machine virtuelle MicroPython " -"n'est pas en cours d'exécution." +"Tentative d'allocation à la pile quand la Machine Virtuelle n'est pas en " +"exécution." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -911,6 +911,11 @@ msgstr "ESP-IDF échec d'allocation de la mémoire" msgid "EXTINT channel already in use" msgstr "Canal EXTINT déjà utilisé" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "Erreur dans le flot MIDI à la position %d" + #: extmod/modure.c msgid "Error in regex" msgstr "Erreur dans l'expression régulière" @@ -973,7 +978,7 @@ msgstr "La FFT est définie uniquement pour les ndarrays" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is implemented for linear arrays only" -msgstr "FFT n'est implémenté que pour les tableaux linéaires" +msgstr "FFT n'est implémenté que pour les matrices linéaires" #: ports/esp32s2/common-hal/ssl/SSLSocket.c msgid "Failed SSL handshake" @@ -1014,7 +1019,7 @@ msgstr "Impossible d'allouer la mémoire pour le scan wifi" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Failed to buffer the sample" -msgstr "" +msgstr "Échec du tamponage de l'échantillon" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to connect: internal error" @@ -1041,6 +1046,10 @@ msgstr "Impossible de libérer mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Échec de l'écriture vers flash interne." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "Erreurre fatale." + #: py/moduerrno.c msgid "File exists" msgstr "Le fichier existe" @@ -1115,10 +1124,6 @@ msgstr "périphérique I2C utilisé" msgid "I2SOut not available" msgstr "I2SOut n'est pas disponible" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOs 0, 2 & 4 ne supportent pas l'éleveuse interne en mode someil" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1253,6 +1258,10 @@ msgstr "BSSID invalide" msgid "Invalid DAC pin supplied" msgstr "Broche DAC non valide fournie" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "Fichier MIDI invalide" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1444,14 +1453,6 @@ msgstr "La valeur maximale de x est %d lors d'une opération miroir" msgid "Messages limited to 8 bytes" msgstr "Messages limités à 8 octets" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "Échec du saut MicroPython NLR. Corruption de la mémoire probable." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Erreur fatale MicroPython." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0" @@ -1505,6 +1506,10 @@ msgstr "Doit fournir une broche MISO ou MOSI" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Doit utiliser un multiple de 6 broches RVB, pas %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "Saut NLR échoué. Corruption de mémoire probable." + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "Erreur NVS" @@ -1649,6 +1654,7 @@ msgstr "Logiciel systême Nordic hors de mémoire" msgid "Not a valid IP string" msgstr "Chaîne IP non valide" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2494,11 +2500,11 @@ msgstr "l'argument est une séquence vide" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "argsort argument must be an ndarray" -msgstr "L'argument argsort doit être un ndarray" +msgstr "Le paramêtre argsort doit être un ndarray" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "argsort is not implemented for flattened arrays" -msgstr "argsort n'est pas mis en œuvre pour les tableaux aplatis" +msgstr "argsort n'est pas mis en œuvre pour les matrices aplatis" #: py/runtime.c msgid "argument has wrong type" @@ -2520,12 +2526,12 @@ msgstr "les paramètres doivent être des ndarrays" #: extmod/ulab/code/ndarray.c msgid "array and index length must be equal" -msgstr "la longueur du tableau et de l'index doivent être égaux" +msgstr "la taille de la matrice et de l'index doivent être égaux" #: py/objarray.c shared-bindings/alarm/SleepMemory.c #: shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" -msgstr "tableau/octets requis à droite" +msgstr "matrice/octets requis à la droite" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "attempt to get (arg)min/(arg)max of empty sequence" @@ -2587,10 +2593,6 @@ msgstr "branche hors-bornes" msgid "buffer is smaller than requested size" msgstr "tampon est plus petit que la taille demandée" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "le tampon doit être un objet bytes-like" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "taille du tampon doit être un multiple de la taille de l'élement" @@ -2828,8 +2830,7 @@ msgstr "" #: shared-bindings/displayio/Palette.c msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" -"le tampon de couleur doit être un bytearray ou un tableau de type 'b' ou 'B'" +msgstr "tampon color doit être un bytearray ou une matrice de type 'b' ou 'B'" #: shared-bindings/displayio/Palette.c msgid "color must be between 0x000000 and 0xffffff" @@ -2861,11 +2862,11 @@ msgstr "conversion en objet" #: extmod/ulab/code/numpy/filter/filter.c msgid "convolve arguments must be linear arrays" -msgstr "les arguments convolve doivent être des tableaux linéaires" +msgstr "les paramêtres pour convolve doivent être des matrices linéaires" #: extmod/ulab/code/numpy/filter/filter.c msgid "convolve arguments must be ndarrays" -msgstr "les arguments convolve doivent être des ndarrays" +msgstr "les paramêtres pour convolve doivent être des ndarrays" #: extmod/ulab/code/numpy/filter/filter.c msgid "convolve arguments must not be empty" @@ -2881,7 +2882,7 @@ msgstr "impossible de déterminer la version de la carte SD" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "cross is defined for 1D arrays of length 3" -msgstr "cross est défini pour les tableaux 1D de longueur 3" +msgstr "cross est défini pour les matrices 1D de longueur 3" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "data must be iterable" @@ -2911,12 +2912,13 @@ msgstr "default n'est pas une fonction" msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -"le tampon de destination doit être un tableau de type 'B' pour bit_depth = 8" +"le tampon de destination doit être une matrice de type 'B' pour bit_depth = 8" #: shared-bindings/audiobusio/PDMIn.c msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -"le tampon de destination doit être un tableau de type 'H' pour bit_depth = 16" +"le tampon de destination doit être une matrice de type 'H' pour bit_depth = " +"16" #: shared-bindings/audiobusio/PDMIn.c msgid "destination_length must be an int >= 0" @@ -2928,7 +2930,7 @@ msgstr "la séquence de mise à jour de dict a une mauvaise longueur" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "diff argument must be an ndarray" -msgstr "l'argument diff doit être un ndarray" +msgstr "le paramêtre diff doit être un ndarray" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "differentiation order out of range" @@ -3047,7 +3049,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string : single '}' n'est pas autorisé" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "le fichier doit être un fichier ouvert en mode 'byte'" @@ -3065,11 +3067,11 @@ msgstr "le premier argument doit être une fonction" #: extmod/ulab/code/ulab_create.c msgid "first argument must be a tuple of ndarrays" -msgstr "le premier argument doit être un tuple de ndarrays" +msgstr "le premier paramêtre doit être un tuple de ndarrays" #: extmod/ulab/code/numpy/vector/vector.c msgid "first argument must be an ndarray" -msgstr "le premier argument doit être un ndarray" +msgstr "le premier paramêtre doit être un ndarray" #: py/objtype.c msgid "first argument to super() must be type" @@ -3081,7 +3083,7 @@ msgstr "l'ordre d'aplatissement doit être «C» ou «F»" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "flip argument must be an ndarray" -msgstr "l'argument flip doit être un ndarray" +msgstr "le paramêtre flip doit être un ndarray" #: py/objint.c msgid "float too big" @@ -3118,7 +3120,7 @@ msgstr "la fonction a le même signe aux extrémités de l’intervalle" #: extmod/ulab/code/ndarray.c msgid "function is defined for ndarrays only" -msgstr "La fonction n'est définie que pour les ndarrays" +msgstr "fonction définie que pour les ndarrays" #: py/argcheck.c #, c-format @@ -3224,11 +3226,11 @@ msgstr "Paramètre entrant doit être un chiffre entier, un tuple, ou une liste" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "input array length must be power of 2" -msgstr "la longueur du tableau d'entrée doit être une puissance de 2" +msgstr "longueur de la matrice d'entrée doit être une puissance de 2" #: extmod/ulab/code/ulab_create.c msgid "input arrays are not compatible" -msgstr "les tableaux d'entrée ne sont pas compatibles" +msgstr "les matrices d'entrée ne sont pas compatibles" #: extmod/ulab/code/numpy/poly/poly.c msgid "input data must be an iterable" @@ -3244,7 +3246,7 @@ msgstr "la matrice d'entrée est singulière" #: extmod/ulab/code/user/user.c msgid "input must be a dense ndarray" -msgstr "l'entrée doit être un tableau dense" +msgstr "l'entrée doit être un ndarray dense" #: extmod/ulab/code/ulab_create.c msgid "input must be a tensor of rank 2" @@ -3284,7 +3286,7 @@ msgstr "entier requis" #: extmod/ulab/code/numpy/approx/approx.c msgid "interp is defined for 1D arrays of equal length" -msgstr "interp est défini pour les tableaux 1D de longueur égale" +msgstr "interp est défini pour les matrices 1D de longueur égale" #: shared-bindings/_bleio/Adapter.c #, c-format @@ -3304,6 +3306,10 @@ msgstr "bits_per_pixel %d est invalid, doit être 1, 4, 8, 16, 24 ou 32" msgid "invalid cert" msgstr "certificat invalide" +#: py/compile.c +msgid "invalid decorator" +msgstr "décorateur invalide" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "index invalide pour dupterm" @@ -3359,10 +3365,6 @@ msgstr "syntaxe invalide pour un entier de base %d" msgid "invalid syntax for number" msgstr "syntaxe invalide pour un nombre" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "io doit être rtc io" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "l'argument 1 de issubclass() doit être une classe" @@ -3718,11 +3720,11 @@ msgstr "les opérandes ne pouvaient pas être diffusés ensemble" #: extmod/ulab/code/ndarray.c msgid "operation is implemented for 1D Boolean arrays only" -msgstr "opération implémentée que pour des tableaux 1D booléennes" +msgstr "opération implémentée que pour les matrices 1D booléennes" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "operation is not implemented on ndarrays" -msgstr "l'opération n'est pas implémentée sur les ndarrays" +msgstr "l'opération n'est pas implémentée pour les ndarrays" #: extmod/ulab/code/ndarray.c msgid "operation is not supported for given type" @@ -3741,11 +3743,11 @@ msgstr "" #: extmod/ulab/code/utils/utils.c msgid "out array is too small" -msgstr "" +msgstr "matrice de sortie est trop petite" #: extmod/ulab/code/utils/utils.c msgid "out must be a float dense array" -msgstr "" +msgstr "la matrice sortante doit être de type float" #: shared-bindings/displayio/Bitmap.c msgid "out of range of source" @@ -3831,6 +3833,7 @@ msgstr "pow() avec 3 arguments nécessite des entiers" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3856,6 +3859,10 @@ msgstr "bouton boot appuyé lors du démarrage.\n" msgid "pressing both buttons at start up.\n" msgstr "les deux boutons appuyés lors du démarrage.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "masque pull est en conflit avec les masques de direction" @@ -3924,8 +3931,8 @@ msgid "" "sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or " "'B'" msgstr "" -"le tampon de sample_source doit être un bytearray ou un tableau de type " -"'h','H', 'b' ou 'B'" +"tampon sample_source doit être un bytearray ou une matrice de type 'h', 'H', " +"'b' ou 'B'" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c @@ -3962,7 +3969,7 @@ msgstr "'}' seule rencontrée dans une chaîne de format" #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" -msgstr "la taille est définie pour les ndarrays uniquement" +msgstr "la taille n'est définie que pour les ndarrays" #: shared-bindings/time/__init__.c msgid "sleep length must be non-negative" @@ -3986,11 +3993,11 @@ msgstr "redémarrage logiciel\n" #: extmod/ulab/code/numpy/numerical/numerical.c msgid "sort argument must be an ndarray" -msgstr "l'argument de «sort» doit être un ndarray" +msgstr "le paramètre de «sort» doit être un ndarray" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos array must be of shape (n_section, 6)" -msgstr "le tableau sos doit être de forme (n_section, 6)" +msgstr "la matrice sos doit être de forme (n_section, 6)" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos[:, 3] should be all ones" @@ -4035,7 +4042,7 @@ msgstr "les indices d'une chaîne doivent être des entiers, pas %q" #: py/stream.c msgid "string not supported; use bytes or bytearray" msgstr "" -"chaîne de carac. non supportée ; utilisez des bytes ou un tableau de bytes" +"chaîne de carac. non supportée; utilisez des bytes ou une matrice de bytes" #: extmod/moductypes.c msgid "struct: cannot index" @@ -4105,7 +4112,7 @@ msgstr "timestamp hors bornes pour 'time_t' de la plateforme" #: extmod/ulab/code/ndarray.c msgid "tobytes can be invoked for dense arrays only" -msgstr "tobytes ne peut être appelé que pour des tableaux dense" +msgstr "tobytes ne peut être appelée que pour des matrices dense" #: shared-module/struct/__init__.c msgid "too many arguments provided with the given format" @@ -4126,15 +4133,11 @@ msgstr "trop de valeur à dégrouper (%d attendues)" #: extmod/ulab/code/numpy/approx/approx.c msgid "trapz is defined for 1D arrays" -msgstr "trapz est défini pour tableaux à une dimension" +msgstr "trapz est définie pour matrices à une dimension" #: extmod/ulab/code/numpy/approx/approx.c msgid "trapz is defined for 1D arrays of equal length" -msgstr "trapz n'est défini que pour des tableaux 1D de longueur égale" - -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "niveau du déclencheur doit être 0 ou 1" +msgstr "trapz n'est défini que pour des matrices 1D de longueur égales" #: py/obj.c msgid "tuple/list has wrong length" @@ -4270,10 +4273,6 @@ msgstr "la valeur doit tenir dans %d octet(s)" msgid "value_count must be > 0" msgstr "'value_count' doit être > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "conflit au réveil" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "chien de garde (watchdog) non initialisé" @@ -4350,7 +4349,7 @@ msgstr "'step' nul" #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be an ndarray" -msgstr "zi doit être ndarray" +msgstr "zi doit être un ndarray" #: extmod/ulab/code/scipy/signal/signal.c msgid "zi must be of float type" @@ -4360,6 +4359,32 @@ msgstr "zi doit être de type float" msgid "zi must be of shape (n_section, 2)" msgstr "zi doit être de forme (n_section, 2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOs 0, 2 & 4 ne supportent pas l'éleveuse interne en mode someil" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "le tampon doit être un objet bytes-like" + +#~ msgid "io must be rtc io" +#~ msgstr "io doit être rtc io" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "niveau du déclencheur doit être 0 ou 1" + +#~ msgid "wakeup conflict" +#~ msgstr "conflit au réveil" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "" +#~ "Tentative d'allocation de segments lorsque la machine virtuelle " +#~ "MicroPython n'est pas en cours d'exécution." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "Échec du saut MicroPython NLR. Corruption de la mémoire probable." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Erreur fatale MicroPython." + #~ msgid "argument must be ndarray" #~ msgstr "l'argument doit être un ndarray" diff --git a/locale/hi.po b/locale/hi.po index 388a85472b..b1a5c0d5dd 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -438,7 +438,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -879,6 +879,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "" @@ -1008,6 +1013,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1080,10 +1089,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1207,6 +1212,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1398,14 +1407,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1457,6 +1458,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1601,6 +1606,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2493,10 +2499,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2938,7 +2940,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3194,6 +3196,10 @@ msgstr "" msgid "invalid cert" msgstr "" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "" @@ -3249,10 +3255,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3712,6 +3714,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3737,6 +3740,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4010,10 +4017,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4148,10 +4151,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 241b07d7ec..a9865b99bf 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -450,8 +450,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Provo ad allocare %d blocchi" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "Provo l'allocazione quando MicroPython VM non è attivo." +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -899,6 +899,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "Canale EXTINT già in uso" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Errore nella regex" @@ -1030,6 +1035,10 @@ msgstr "Impossibile rilasciare il mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "File esistente" @@ -1102,10 +1111,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1231,6 +1236,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1425,14 +1434,6 @@ msgstr "Valore massimo di x quando rispachiato è %d" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1485,6 +1486,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1629,6 +1634,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c #, fuzzy @@ -2538,10 +2544,6 @@ msgstr "argomento di chr() non è in range(256)" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2991,7 +2993,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3248,6 +3250,10 @@ msgstr "" msgid "invalid cert" msgstr "certificato non valido" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "indice dupterm non valido" @@ -3303,10 +3309,6 @@ msgstr "sintassi invalida per l'intero con base %d" msgid "invalid syntax for number" msgstr "sintassi invalida per il numero" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "il primo argomento di issubclass() deve essere una classe" @@ -3778,6 +3780,7 @@ msgstr "pow() con 3 argomenti richiede interi" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3803,6 +3806,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4080,10 +4087,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tupla/lista ha la lunghezza sbagliata" @@ -4218,10 +4221,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4310,6 +4309,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "Provo l'allocazione quando MicroPython VM non è attivo." + #~ msgid "Group full" #~ msgstr "Gruppo pieno" diff --git a/locale/ja.po b/locale/ja.po index e2b5d926af..36b19d14c5 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -443,8 +443,8 @@ msgid "Attempt to allocate %d blocks" msgstr "%d個のブロックの確保を試みました" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "MicroPython VMの非実行時にヒープ確保を試みました" +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -890,6 +890,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "EXTINTチャネルはすでに使用されています" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "正規表現にエラーがあります" @@ -1019,6 +1024,10 @@ msgstr "ミューテックスの開放に失敗。エラー 0x%04x" msgid "Failed to write internal flash." msgstr "内部フラッシュ書き込みに失敗" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "ファイルが存在します" @@ -1091,10 +1100,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOutが利用できません" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1220,6 +1225,10 @@ msgstr "不正なBSSID" msgid "Invalid DAC pin supplied" msgstr "不正なDACピンが与えられました" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1411,14 +1420,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "MicroPython NLRジャンプ失敗。メモリ破壊の可能性あり" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "MicroPython致命的エラー" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "マイクのスタートアップディレイは 0.0 から 1.0 の間でなければなりません" @@ -1470,6 +1471,10 @@ msgstr "MISOピンまたはMOSIピンが必要" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "%d個でなく6の倍数個のrgbピンを使ってください" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1614,6 +1619,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "不正なIP文字列です" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2516,10 +2522,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "バッファはbytes-likeオブジェクトでなければなりません" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2965,7 +2967,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: 1つだけの'}'は許されません" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "fileはバイトモードで開かれたファイルでなければなりません" @@ -3222,6 +3224,10 @@ msgstr "" msgid "invalid cert" msgstr "不正な証明書" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "不正なduptermインデクス" @@ -3277,10 +3283,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "数字として不正な構文" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass()の第1引数はクラスでなければなりません" @@ -3742,6 +3744,7 @@ msgstr "pow()の第3引数には整数が必要" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3767,6 +3770,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4041,10 +4048,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "trapzは同じ長さの1次元arrayに対して定義されています" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "タプル/リストの長さが正しくありません" @@ -4179,10 +4182,6 @@ msgstr "値は%dバイトに収まらなければなりません" msgid "value_count must be > 0" msgstr "value_countは0より大きくなければなりません" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4269,6 +4268,18 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "バッファはbytes-likeオブジェクトでなければなりません" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "MicroPython VMの非実行時にヒープ確保を試みました" + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLRジャンプ失敗。メモリ破壊の可能性あり" + +#~ msgid "MicroPython fatal error." +#~ msgstr "MicroPython致命的エラー" + #~ msgid "argument must be ndarray" #~ msgstr "引数はndarrayでなければなりません" diff --git a/locale/ko.po b/locale/ko.po index 3b8eeebe6d..fe5ce58d9a 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -439,7 +439,7 @@ msgid "Attempt to allocate %d blocks" msgstr "" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" #: shared-bindings/wifi/Radio.c @@ -882,6 +882,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Regex에 오류가 있습니다." @@ -1011,6 +1016,10 @@ msgstr "" msgid "Failed to write internal flash." msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "" @@ -1083,10 +1092,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1210,6 +1215,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1401,14 +1410,6 @@ msgstr "" msgid "Messages limited to 8 bytes" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "" - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1460,6 +1461,10 @@ msgstr "" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1604,6 +1609,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2497,10 +2503,6 @@ msgstr "" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2942,7 +2944,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "" @@ -3198,6 +3200,10 @@ msgstr "" msgid "invalid cert" msgstr "cert가 유효하지 않습니다" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "Dupterm index가 유효하지 않습니다" @@ -3253,10 +3259,6 @@ msgstr "구문(syntax)가 정수가 유효하지 않습니다" msgid "invalid syntax for number" msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3716,6 +3718,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3741,6 +3744,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4014,10 +4021,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4152,10 +4155,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 3285f52150..27f12fba3a 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -441,8 +441,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Poging om %d blokken toe te wijzen" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "heap allocatie geprobeerd terwijl MicroPython VM niet draait." +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -890,6 +890,11 @@ msgstr "ESP-IDF geheugen toewijzing mislukt" msgid "EXTINT channel already in use" msgstr "EXTINT kanaal al in gebruik" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Fout in regex" @@ -1019,6 +1024,10 @@ msgstr "Mislukt mutex los te laten, err 0x%04x" msgid "Failed to write internal flash." msgstr "Schrijven naar interne flash mislukt." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "Bestand bestaat" @@ -1092,10 +1101,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOut is niet beschikbaar" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IO's 0, 2 en 4 ondersteunen geen interne pullup in slaapstand" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1221,6 +1226,10 @@ msgstr "Ongeldig BSSID" msgid "Invalid DAC pin supplied" msgstr "Ongeldige DAC pin opgegeven" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1412,14 +1421,6 @@ msgstr "Maximale x waarde indien gespiegeld is %d" msgid "Messages limited to 8 bytes" msgstr "Berichten zijn beperkt tot 8 bytes" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "MicroPython NLR sprong mislukt. Waarschijnlijk geheugen corruptie." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "MicroPython fatale fout." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Microfoon opstart vertraging moet in bereik van 0.0 tot 1.0 zijn" @@ -1471,6 +1472,10 @@ msgstr "MISO of MOSI moeten worden gegeven" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Een meervoud van 6 rgb pinnen moet worden gebruikt, niet %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "NVS-fout" @@ -1615,6 +1620,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "Geen geldige IP string" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2544,10 +2550,6 @@ msgstr "pad (branch) niet binnen bereik" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "buffer moet een byte-achtig object zijn" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2993,7 +2995,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: enkele '}' is niet toegestaan" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "bestand moet een bestand zijn geopend in byte modus" @@ -3250,6 +3252,10 @@ msgstr "" msgid "invalid cert" msgstr "ongeldig certificaat" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "ongeldige dupterm index" @@ -3305,10 +3311,6 @@ msgstr "ongeldige syntax voor integer met grondtal %d" msgid "invalid syntax for number" msgstr "ongeldige syntax voor nummer" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "io moet rtc io zijn" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() argument 1 moet een klasse zijn" @@ -3772,6 +3774,7 @@ msgstr "pow() met 3 argumenten vereist integers" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3797,6 +3800,10 @@ msgstr "druk bootknop in bij opstarten.\n" msgid "pressing both buttons at start up.\n" msgstr "druk beide knoppen in bij opstarten.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4072,10 +4079,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "trapz is gedefinieerd voor eendimensionale arrays van gelijke lengte" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "triggerniveau moet 0 of 1 zijn" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tuple of lijst heeft onjuiste lengte" @@ -4210,10 +4213,6 @@ msgstr "waarde moet in %d byte(s) passen" msgid "value_count must be > 0" msgstr "value_count moet groter dan 0 zijn" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "conflict bij ontwaken" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog niet geïnitialiseerd" @@ -4300,6 +4299,30 @@ msgstr "zi moet van type float zijn" msgid "zi must be of shape (n_section, 2)" msgstr "zi moet vorm (n_section, 2) hebben" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IO's 0, 2 en 4 ondersteunen geen interne pullup in slaapstand" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "buffer moet een byte-achtig object zijn" + +#~ msgid "io must be rtc io" +#~ msgstr "io moet rtc io zijn" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "triggerniveau moet 0 of 1 zijn" + +#~ msgid "wakeup conflict" +#~ msgstr "conflict bij ontwaken" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "heap allocatie geprobeerd terwijl MicroPython VM niet draait." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLR sprong mislukt. Waarschijnlijk geheugen corruptie." + +#~ msgid "MicroPython fatal error." +#~ msgstr "MicroPython fatale fout." + #~ msgid "argument must be ndarray" #~ msgstr "argument moet ndarray zijn" diff --git a/locale/pl.po b/locale/pl.po index 295901c994..234c2ba998 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -443,8 +443,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Próba przydzielenia %d bloków" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "Próba przydziału sterty, gdy MicroPython VM nie działa." +msgid "Attempted heap allocation when VM not running." +msgstr "" #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -890,6 +890,11 @@ msgstr "" msgid "EXTINT channel already in use" msgstr "Kanał EXTINT w użyciu" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "" + #: extmod/modure.c msgid "Error in regex" msgstr "Błąd w regex" @@ -1019,6 +1024,10 @@ msgstr "Nie udało się zwolnić blokady, błąd 0x%04x" msgid "Failed to write internal flash." msgstr "Nie udało się zapisać wewnętrznej pamięci flash." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "" + #: py/moduerrno.c msgid "File exists" msgstr "Plik istnieje" @@ -1091,10 +1100,6 @@ msgstr "" msgid "I2SOut not available" msgstr "I2SOut niedostępne" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1220,6 +1225,10 @@ msgstr "" msgid "Invalid DAC pin supplied" msgstr "" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1411,15 +1420,6 @@ msgstr "Największa wartość x przy odwróceniu to %d" msgid "Messages limited to 8 bytes" msgstr "Wiadomości ograniczone do 8 bajtów" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "" -"Skok MicroRython NLR nie powiódł się. Prawdopodobne uszkodzenie pamięci." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Błąd krytyczny MicroPython." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Opóźnienie włączenia mikrofonu musi być w zakresie od 0.0 do 1.0" @@ -1471,6 +1471,10 @@ msgstr "Należy podać pin MISO lub MOSI" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "" + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "" @@ -1615,6 +1619,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2513,10 +2518,6 @@ msgstr "skok poza zakres" msgid "buffer is smaller than requested size" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "bufor mysi być typu bytes" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "" @@ -2959,7 +2960,7 @@ msgid "f-string: single '}' is not allowed" msgstr "" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "file musi być otwarte w trybie bajtowym" @@ -3215,6 +3216,10 @@ msgstr "" msgid "invalid cert" msgstr "zły ceryfikat" +#: py/compile.c +msgid "invalid decorator" +msgstr "" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "zły indeks dupterm" @@ -3270,10 +3275,6 @@ msgstr "zła składnia dla liczby całkowitej w bazie %d" msgid "invalid syntax for number" msgstr "zła składnia dla liczby" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "argument 1 dla issubclass() musi być klasą" @@ -3734,6 +3735,7 @@ msgstr "trzyargumentowe pow() wymaga liczb całkowitych" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3759,6 +3761,10 @@ msgstr "" msgid "pressing both buttons at start up.\n" msgstr "" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "" @@ -4033,10 +4039,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "krotka/lista ma złą długość" @@ -4171,10 +4173,6 @@ msgstr "wartość musi mieścić się w %d bajtach" msgid "value_count must be > 0" msgstr "value_count musi być > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" @@ -4261,6 +4259,19 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "bufor mysi być typu bytes" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "Próba przydziału sterty, gdy MicroPython VM nie działa." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "" +#~ "Skok MicroRython NLR nie powiódł się. Prawdopodobne uszkodzenie pamięci." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Błąd krytyczny MicroPython." + #~ msgid "vectors must have same lengths" #~ msgstr "wektory muszą mieć identyczną długość" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 7643bcfb0d..adb54556be 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-07 12:23+0000\n" +"PO-Revision-Date: 2021-04-19 21:50+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: main.c msgid "" @@ -451,10 +451,9 @@ msgid "Attempt to allocate %d blocks" msgstr "Tentativa de alocar %d blocos" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." +msgid "Attempted heap allocation when VM not running." msgstr "" -"A tentativa da área de alocação dinâmica de variáveis (heap) quando o " -"MicroPython VM não está em execução." +"Tentativa de alocação das pilhas quando o VM não estiver em funcionamento." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -908,6 +907,11 @@ msgstr "Houve uma falha na alocação da memória ESP-IDF" msgid "EXTINT channel already in use" msgstr "Canal EXTINT em uso" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "Houve um erro no fluxo MIDI na posição %d" + #: extmod/modure.c msgid "Error in regex" msgstr "Erro no regex" @@ -1037,6 +1041,10 @@ msgstr "Houve uma falha ao liberar o mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Falha ao gravar o flash interno." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "Erro fatal." + #: py/moduerrno.c msgid "File exists" msgstr "Arquivo já existe" @@ -1110,10 +1118,6 @@ msgstr "Periférico I2C em uso" msgid "I2SOut not available" msgstr "O I2SOut não está disponível" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOs 0, 2 e 4 não suportam pullup interno em repouso (sleep)" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1245,6 +1249,10 @@ msgstr "BSSID Inválido" msgid "Invalid DAC pin supplied" msgstr "O pino DAC informado é inválido" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "O arquivo MIDI é inválido" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1436,14 +1444,6 @@ msgstr "O valor máximo de x quando espelhado é %d" msgid "Messages limited to 8 bytes" msgstr "As mensagens estão limitadas a 8 bytes" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "O salto do MicroPython NLR falhou. Possível corrupção de memória." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "Houve um erro fatal do MicroPython." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "O atraso na inicialização do microfone deve estar entre 0,0 e 1,0" @@ -1495,6 +1495,10 @@ msgstr "Deve informar os pinos MISO ou MOSI" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Deve utilizar um múltiplo de 6 pinos rgb, não %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "O salto NLR falhou. Possível corrupção da memória." + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "Erro NVS" @@ -1641,6 +1645,7 @@ msgstr "O firmware do sistema nórdico está sem memória" msgid "Not a valid IP string" msgstr "Não é uma sequência válida de IP" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2579,10 +2584,6 @@ msgstr "ramo fora do alcance" msgid "buffer is smaller than requested size" msgstr "o tamanho do buffer é menor do que o tamanho que foi solicitado" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "o buffer deve ser um objeto como bytes" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "o tamanho do buffer deve ser um múltiplo do tamanho do elemento" @@ -3033,7 +3034,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: um único '}' não é permitido" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "o arquivo deve ser um arquivo aberto no modo byte" @@ -3290,6 +3291,10 @@ msgstr "bits_per_pixel %d é inválido, deve ser, 1, 4, 8, 16, 24, ou 32" msgid "invalid cert" msgstr "certificado inválido" +#: py/compile.c +msgid "invalid decorator" +msgstr "decorador inválido" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "Índice de dupterm inválido" @@ -3345,10 +3350,6 @@ msgstr "sintaxe inválida para o número inteiro com base %d" msgid "invalid syntax for number" msgstr "sintaxe inválida para o número" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "O io deve ser rtc io" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 deve ser uma classe" @@ -3818,6 +3819,7 @@ msgstr "o pow() com 3 argumentos requer números inteiros" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3843,6 +3845,10 @@ msgstr "pressionando o botão de boot na inicialização.\n" msgid "pressing both buttons at start up.\n" msgstr "pressionando ambos os botões durante a inicialização.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "pressionando o botão esquerdo durante a inicialização\n" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "puxe as máscaras em conflito com as máscaras de direção" @@ -4118,10 +4124,6 @@ msgstr "Trapz está definido para arrays 1D" msgid "trapz is defined for 1D arrays of equal length" msgstr "o trapz está definido para 1D arrays de igual tamanho" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "nível do gatilho deve ser 0 ou 1" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "a tupla/lista está com tamanho incorreto" @@ -4256,10 +4258,6 @@ msgstr "o valor deve caber em %d byte(s)" msgid "value_count must be > 0" msgstr "o value_count deve ser > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "conflito de wakeup" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "o watchdog não foi inicializado" @@ -4346,6 +4344,32 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOs 0, 2 e 4 não suportam pullup interno em repouso (sleep)" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "o buffer deve ser um objeto como bytes" + +#~ msgid "io must be rtc io" +#~ msgstr "O io deve ser rtc io" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "nível do gatilho deve ser 0 ou 1" + +#~ msgid "wakeup conflict" +#~ msgstr "conflito de wakeup" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "" +#~ "A tentativa da área de alocação dinâmica de variáveis (heap) quando o " +#~ "MicroPython VM não está em execução." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "O salto do MicroPython NLR falhou. Possível corrupção de memória." + +#~ msgid "MicroPython fatal error." +#~ msgstr "Houve um erro fatal do MicroPython." + #~ msgid "argument must be ndarray" #~ msgstr "o argumento deve ser ndarray" diff --git a/locale/sv.po b/locale/sv.po index 5feb28845d..69fe35736d 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-06 14:41+0000\n" +"PO-Revision-Date: 2021-04-19 21:50+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: main.c msgid "" @@ -446,8 +446,8 @@ msgid "Attempt to allocate %d blocks" msgstr "Försök att tilldela %d block" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "Försökte tilldela heap när MicroPython VM inte körs." +msgid "Attempted heap allocation when VM not running." +msgstr "Försök till heap-allokering när den virtuella maskinen inte är igång." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -896,6 +896,11 @@ msgstr "ESP-IDF-minnetilldelning misslyckades" msgid "EXTINT channel already in use" msgstr "EXTINT-kanalen används redan" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "Fel i MIDI-ström vid position %d" + #: extmod/modure.c msgid "Error in regex" msgstr "Fel i regex" @@ -1025,6 +1030,10 @@ msgstr "Det gick inte att frigöra mutex, fel 0x%04x" msgid "Failed to write internal flash." msgstr "Det gick inte att skriva till intern flash." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "Fatalt fel." + #: py/moduerrno.c msgid "File exists" msgstr "Filen finns redan" @@ -1097,10 +1106,6 @@ msgstr "I2C-enhet används redan" msgid "I2SOut not available" msgstr "I2SOut är inte tillgängligt" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IO 0, 2 & 4 stöder inte intern pullup för sovläge" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1228,6 +1233,10 @@ msgstr "Ogiltig BSSID" msgid "Invalid DAC pin supplied" msgstr "Ogiltig DAC-pinne angiven" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "Ogiltig MIDI-fil" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1419,14 +1428,6 @@ msgstr "Maximum x-värde vid spegling är %d" msgid "Messages limited to 8 bytes" msgstr "Meddelanden begränsad till 8 byte" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "MicroPython NLR jump misslyckades. Troligen korrupt minne." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "MicroPython fatalt fel." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "" @@ -1479,6 +1480,10 @@ msgstr "Måste ange MISO- eller MOSI-pinne" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "Måste använda ett multipel av 6 rgb-pinnar, inte %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "NLR jump misslyckades. Troligen korrupt minne." + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "NVS-fel" @@ -1623,6 +1628,7 @@ msgstr "Nordic systemfirmware fick slut på minne" msgid "Not a valid IP string" msgstr "Inte en giltig IP-sträng" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2547,10 +2553,6 @@ msgstr "branch utanför räckvidd" msgid "buffer is smaller than requested size" msgstr "bufferten är mindre än begärd storlek" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "buffer måste vara en byte-liknande objekt" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "buffertstorlek måste vara en multipel av elementstorlek" @@ -2997,7 +2999,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: singel '}' är inte tillåten" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "filen måste vara en fil som öppnats i byte-läge" @@ -3253,6 +3255,10 @@ msgstr "ogiltig bits_per_pixel %d, måste vara 1, 4, 8, 16, 24 eller 32" msgid "invalid cert" msgstr "ogiltigt certifikat" +#: py/compile.c +msgid "invalid decorator" +msgstr "ogiltig dekorator" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "ogiltigt dupterm index" @@ -3308,10 +3314,6 @@ msgstr "ogiltig syntax för heltal med bas %d" msgid "invalid syntax for number" msgstr "ogiltig syntax för tal" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "io måste vara rtc io" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 måste vara en klass" @@ -3775,6 +3777,7 @@ msgstr "pow() med 3 argument kräver heltal" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3800,6 +3803,10 @@ msgstr "trycka på startknappen vid start.\n" msgid "pressing both buttons at start up.\n" msgstr "trycka båda knapparna vid uppstart.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "håll ner vänster knapp vid start\n" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "pull-mask är i konflikt med riktnings-mask" @@ -4075,10 +4082,6 @@ msgstr "trapz är definierat för 1D-matriser" msgid "trapz is defined for 1D arrays of equal length" msgstr "trapz är definierad för 1D-matriser med samma längd" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "triggernivå måste vara 0 eller 1" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "tupel/lista har fel längd" @@ -4213,10 +4216,6 @@ msgstr "värdet måste passa i %d byte(s)" msgid "value_count must be > 0" msgstr "value_count måste vara > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "wakeup-konflikt" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "watchdog är inte initierad" @@ -4303,6 +4302,30 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IO 0, 2 & 4 stöder inte intern pullup för sovläge" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "buffer måste vara en byte-liknande objekt" + +#~ msgid "io must be rtc io" +#~ msgstr "io måste vara rtc io" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "triggernivå måste vara 0 eller 1" + +#~ msgid "wakeup conflict" +#~ msgstr "wakeup-konflikt" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "Försökte tilldela heap när MicroPython VM inte körs." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLR jump misslyckades. Troligen korrupt minne." + +#~ msgid "MicroPython fatal error." +#~ msgstr "MicroPython fatalt fel." + #~ msgid "argument must be ndarray" #~ msgstr "argument måste vara ndarray" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 14c0a9eca0..c8a2d8cf83 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-03-29 08:26+0000\n" +"PO-Revision-Date: 2021-04-19 19:15+0000\n" "Last-Translator: hexthat \n" "Language-Team: Chinese Hanyu Pinyin\n" "Language: zh_Latn_pinyin\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.6-dev\n" +"X-Generator: Weblate 4.7-dev\n" #: main.c msgid "" @@ -423,7 +423,7 @@ msgstr "Wèi zhīchí zhǐdìng de yǐn jiǎo AnalogOut" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" -msgstr "" +msgstr "lìng yí gè PWMAudioOut yǐ jīng chǔ yú huó dòng zhuàng tài" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c @@ -448,8 +448,8 @@ msgid "Attempt to allocate %d blocks" msgstr "cháng shì fēn pèi %d kuài" #: supervisor/shared/safe_mode.c -msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "MicroPython VM zài wèi yùnxíng shí chángshì fēnpèi duī." +msgid "Attempted heap allocation when VM not running." +msgstr "dāng VM bú yùn xíng shí, cháng shì duī fēn pèi." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" @@ -895,6 +895,11 @@ msgstr "ESP-IDF nèicún fēnpèi shībài" msgid "EXTINT channel already in use" msgstr "EXTINT píndào yǐjīng shǐyòng" +#: shared-module/synthio/MidiTrack.c +#, c-format +msgid "Error in MIDI stream at position %d" +msgstr "wèi yú %d wèi zhì de MIDI liú zhōng de cuò wù" + #: extmod/modure.c msgid "Error in regex" msgstr "Zhèngzé biǎodá shì cuòwù" @@ -997,7 +1002,7 @@ msgstr "Wúfǎ fēnpèi wifi sǎomiáo nèicún" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Failed to buffer the sample" -msgstr "" +msgstr "wèi néng huǎn chōng yàng běn" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "Failed to connect: internal error" @@ -1024,6 +1029,10 @@ msgstr "Wúfǎ shìfàng mutex, err 0x%04x" msgid "Failed to write internal flash." msgstr "Wúfǎ xiě rù nèibù shǎncún." +#: supervisor/shared/safe_mode.c +msgid "Fatal error." +msgstr "zhì mìng cuò wù." + #: py/moduerrno.c msgid "File exists" msgstr "Wénjiàn cúnzài" @@ -1096,10 +1105,6 @@ msgstr "I2C wài shè zhèng zài shǐ yòng zhōng" msgid "I2SOut not available" msgstr "I2SOut bù kě yòng" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "IOS 0, 2 + 4 bù zhī chí shuì mián zhōng de nèi bù shàng lā" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1230,6 +1235,10 @@ msgstr "Wúxiào de BSSID" msgid "Invalid DAC pin supplied" msgstr "Tí gōng liǎo wúxiào de DAC yǐn jiǎo" +#: shared-bindings/synthio/__init__.c +msgid "Invalid MIDI file" +msgstr "wú xiào de MIDI wén jiàn" + #: ports/atmel-samd/common-hal/pwmio/PWMOut.c #: ports/cxd56/common-hal/pwmio/PWMOut.c #: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -1421,14 +1430,6 @@ msgstr "Jìngxiàng shí de zuìdà X zhí wèi%d" msgid "Messages limited to 8 bytes" msgstr "Yóujiàn xiànzhì wèi 8 gè zì jié" -#: supervisor/shared/safe_mode.c -msgid "MicroPython NLR jump failed. Likely memory corruption." -msgstr "MicroPython NLR tiào zhuǎn shībài. Kěnéng shì nèicún sǔnhuài." - -#: supervisor/shared/safe_mode.c -msgid "MicroPython fatal error." -msgstr "MicroPython zhìmìng cuòwù." - #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Màikèfēng qǐdòng yánchí bìxū zài 0.0 Dào 1.0 De fànwéi nèi" @@ -1481,6 +1482,10 @@ msgstr "Bìxū tígōng MISO huò MOSI yǐn jiǎo" msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "bì xū shǐ yòng 6 RGB yǐn jiǎo de bèi shù, ér bù shì %d" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "NLR tiào zhuǎn shī bài. kě néng shì nèi cún sǔn huài." + #: ports/esp32s2/common-hal/nvm/ByteArray.c msgid "NVS Error" msgstr "NVS cuò wù" @@ -1615,16 +1620,17 @@ msgstr "Méiyǒu jìshí qì" #: supervisor/shared/safe_mode.c msgid "Nordic system firmware failure assertion." -msgstr "" +msgstr "běi ōu xì tǒng gù jiàn gù zhàng duàn yán." #: ports/nrf/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" -msgstr "" +msgstr "běi ōu xì tǒng gù jiàn chū nèi cún" #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c msgid "Not a valid IP string" msgstr "Wúxiào de IP zìfú chuàn" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2288,7 +2294,7 @@ msgstr "Wèizhī de ānquán cuòwù: 0x%04x" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %04x" -msgstr "" +msgstr "wèi zhī xì tǒng gù jiàn cuò wù: %04x" #: shared-bindings/_pixelbuf/PixelBuf.c #, c-format @@ -2545,10 +2551,6 @@ msgstr "fēnzhī bùzài fànwéi nèi" msgid "buffer is smaller than requested size" msgstr "huǎn chōng qū xiǎo yú qǐng qiú de dà xiǎo" -#: shared-bindings/audiocore/RawSample.c -msgid "buffer must be a bytes-like object" -msgstr "huǎnchōng qū bìxū shì zì jié lèi duìxiàng" - #: extmod/ulab/code/ulab_create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" msgstr "huǎn chōng qū dà xiǎo bì xū shì yuán sù dà xiǎo de bèi shù" @@ -2996,7 +2998,7 @@ msgid "f-string: single '}' is not allowed" msgstr "f-string: bù yǔnxǔ shǐyòng dāngè '}'" #: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/synthio/__init__.c msgid "file must be a file opened in byte mode" msgstr "wénjiàn bìxū shì zài zì jié móshì xià dǎkāi de wénjiàn" @@ -3252,6 +3254,10 @@ msgstr "wú xiào bits_per_pixel %d, bì xū shì, 1, 4, 8, 16, 24, huò 32" msgid "invalid cert" msgstr "zhèngshū wúxiào" +#: py/compile.c +msgid "invalid decorator" +msgstr "wú xiào zhuāng shì" + #: extmod/uos_dupterm.c msgid "invalid dupterm index" msgstr "dupterm suǒyǐn wúxiào" @@ -3307,10 +3313,6 @@ msgstr "jīshù wèi %d de zhěng shǔ de yǔfǎ wúxiào" msgid "invalid syntax for number" msgstr "wúxiào de hàomǎ yǔfǎ" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "IO bì xū shì RTC IO" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() cānshù 1 bìxū shì yīgè lèi" @@ -3682,11 +3684,11 @@ msgstr "ord() yùqí zìfú, dàn chángdù zìfú chuàn %d" #: extmod/ulab/code/utils/utils.c msgid "out array is too small" -msgstr "" +msgstr "chū zhèn liè tài xiǎo" #: extmod/ulab/code/utils/utils.c msgid "out must be a float dense array" -msgstr "" +msgstr "chū bì xū shì yí gè fú dòng mì jí zhèn liè" #: shared-bindings/displayio/Bitmap.c msgid "out of range of source" @@ -3771,6 +3773,7 @@ msgstr "pow() yǒu 3 cānshù xūyào zhěngshù" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3796,6 +3799,10 @@ msgstr "Zài qǐdòng shí àn qǐdòng ànniǔ.\n" msgid "pressing both buttons at start up.\n" msgstr "zài qǐdòng shí tóngshí àn xià liǎng gè ànniǔ.\n" +#: ports/nrf/boards/aramcon2_badge/mpconfigboard.h +msgid "pressing the left button at start up\n" +msgstr "" + #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" msgstr "lā kǒu zhào yǔ fāng xiàng miàn mó chōng tū" @@ -4071,10 +4078,6 @@ msgstr "wéi 1D shù zǔ dìng yì xiàn jǐng" msgid "trapz is defined for 1D arrays of equal length" msgstr "Trapz shì wèi děng zhǎng de 1D shùzǔ dìngyì de" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "chù fā jí bié bì xū wéi 0 huò 1" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "yuán zǔ/lièbiǎo chángdù cuòwù" @@ -4209,10 +4212,6 @@ msgstr "Zhí bìxū fúhé %d zì jié" msgid "value_count must be > 0" msgstr "zhí jìshù bìxū wèi > 0" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "huàn xǐng chōng tū" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "wèi chū shǐ huà jiān shì qì" @@ -4299,6 +4298,30 @@ msgstr "zi bìxū wèi fú diǎn xíng" msgid "zi must be of shape (n_section, 2)" msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" +#~ msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +#~ msgstr "IOS 0, 2 + 4 bù zhī chí shuì mián zhōng de nèi bù shàng lā" + +#~ msgid "buffer must be a bytes-like object" +#~ msgstr "huǎnchōng qū bìxū shì zì jié lèi duìxiàng" + +#~ msgid "io must be rtc io" +#~ msgstr "IO bì xū shì RTC IO" + +#~ msgid "trigger level must be 0 or 1" +#~ msgstr "chù fā jí bié bì xū wéi 0 huò 1" + +#~ msgid "wakeup conflict" +#~ msgstr "huàn xǐng chōng tū" + +#~ msgid "Attempted heap allocation when MicroPython VM not running." +#~ msgstr "MicroPython VM zài wèi yùnxíng shí chángshì fēnpèi duī." + +#~ msgid "MicroPython NLR jump failed. Likely memory corruption." +#~ msgstr "MicroPython NLR tiào zhuǎn shībài. Kěnéng shì nèicún sǔnhuài." + +#~ msgid "MicroPython fatal error." +#~ msgstr "MicroPython zhìmìng cuòwù." + #~ msgid "argument must be ndarray" #~ msgstr "Cānshù bìxū shì ndarray" diff --git a/main.c b/main.c index 755f8d5362..7020ab3851 100755 --- a/main.c +++ b/main.c @@ -404,10 +404,10 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { new_status_color(BLACK); board_deinit(); if (!supervisor_workflow_active()) { - // Enter deep sleep. When we wake up we'll return from - // this loop. + // Enter true deep sleep. When we wake up we'll be back at the + // top of main(), not in this loop. common_hal_alarm_enter_deep_sleep(); - // Does not return. + // Does not return. } else { serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n")); } @@ -426,18 +426,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #if CIRCUITPY_ALARM common_hal_alarm_pretending_deep_sleep(); - bool serial_in = (serial_connected() && - serial_bytes_available()); - supervisor_set_run_reason(RUN_REASON_STARTUP); - board_init(); - if (serial_in) { - bool ctrl_d = serial_read() == CHAR_CTRL_D; - if (ctrl_d) { - supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); - } - return ctrl_d; - } - return true; #else port_idle_until_interrupt(); #endif diff --git a/ports/atmel-samd/boards/rotary_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c similarity index 100% rename from ports/atmel-samd/boards/rotary_trinkey_m0/board.c rename to ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/board.c diff --git a/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.h new file mode 100644 index 0000000000..3cd85ac1bc --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.h @@ -0,0 +1,58 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit NeoKey Trinkey M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA15) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA29 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB00 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 diff --git a/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.mk new file mode 100644 index 0000000000..56cbede39f --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/mpconfigboard.mk @@ -0,0 +1,34 @@ +USB_VID = 0x239A +USB_PID = 0x8100 +USB_PRODUCT = "NeoKey Trinkey M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 0 +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_BUSIO = 0 +CIRCUITPY_STORAGE = 1 + +CIRCUITPY_MATH = 1 +CIRCUITPY_PIXELBUF = 1 +CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_TOUCHIO = 1 +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID diff --git a/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/pins.c b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/pins.c new file mode 100644 index 0000000000..df8dfb0bfa --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_neokey_trinkey_m0/pins.c @@ -0,0 +1,8 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TOUCH), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_PA28) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c new file mode 100644 index 0000000000..cde441b3d9 --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft 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/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/shared/board.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h new file mode 100644 index 0000000000..a760fbe376 --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h @@ -0,0 +1,58 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit ProxLight Trinkey M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA15) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA06 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA29 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB00 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA17) +#define DEFAULT_I2C_BUS_SDA (&pin_PA16) diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk new file mode 100644 index 0000000000..92e7a17f3e --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk @@ -0,0 +1,33 @@ +USB_VID = 0x239A +USB_PID = 0x8104 +USB_PRODUCT = "ProxLight Trinkey M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 0 +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_BUSIO = 1 +CIRCUITPY_STORAGE = 1 + +CIRCUITPY_MATH = 1 +CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_TOUCHIO = 1 +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/pins.c b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/pins.c new file mode 100644 index 0000000000..21410f8ad1 --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/pins.c @@ -0,0 +1,15 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_INTERRUPT), MP_ROM_PTR(&pin_PA00) }, + + { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c new file mode 100644 index 0000000000..cde441b3d9 --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft 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/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/shared/board.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/rotary_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/mpconfigboard.h similarity index 100% rename from ports/atmel-samd/boards/rotary_trinkey_m0/mpconfigboard.h rename to ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/mpconfigboard.h diff --git a/ports/atmel-samd/boards/rotary_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/mpconfigboard.mk similarity index 97% rename from ports/atmel-samd/boards/rotary_trinkey_m0/mpconfigboard.mk rename to ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/mpconfigboard.mk index b071378c1d..29cc9ee195 100644 --- a/ports/atmel-samd/boards/rotary_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/mpconfigboard.mk @@ -18,7 +18,7 @@ CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_BUSIO = 0 -CIRCUITPY_STORAGE = 0 +CIRCUITPY_STORAGE = 1 CIRCUITPY_MATH = 0 CIRCUITPY_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/rotary_trinkey_m0/pins.c b/ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/pins.c similarity index 100% rename from ports/atmel-samd/boards/rotary_trinkey_m0/pins.c rename to ports/atmel-samd/boards/adafruit_rotary_trinkey_m0/pins.c diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c new file mode 100644 index 0000000000..cde441b3d9 --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft 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/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/shared/board.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.h new file mode 100644 index 0000000000..1d9a4122df --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.h @@ -0,0 +1,58 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Slide Trinkey M0" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA06) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 +#define IGNORE_PIN_PA02 1 +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA05 1 +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA09 1 +#define IGNORE_PIN_PA10 1 +#define IGNORE_PIN_PA11 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA16 1 +#define IGNORE_PIN_PA17 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA19 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA29 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB00 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.mk new file mode 100644 index 0000000000..2bc2def52e --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/mpconfigboard.mk @@ -0,0 +1,35 @@ +USB_VID = 0x239A +USB_PID = 0x8102 +USB_PRODUCT = "Slide Trinkey M0" +USB_MANUFACTURER = "Adafruit Industries LLC" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE + +CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAMD = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 0 +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_BUSIO = 0 +CIRCUITPY_STORAGE = 1 + +CIRCUITPY_MATH = 1 +CIRCUITPY_PIXELBUF = 1 +CIRCUITPY_USB_MIDI = 1 +CIRCUITPY_TOUCHIO = 1 +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SimpleMath +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/pins.c b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/pins.c new file mode 100644 index 0000000000..c48c69206a --- /dev/null +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/pins.c @@ -0,0 +1,8 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + //{ MP_ROM_QSTR(MP_QSTR_TOUCH), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_POTENTIOMETER), MP_ROM_PTR(&pin_PA07) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h index a0fde67ef6..704c0552d3 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h @@ -8,8 +8,8 @@ #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) -#define DEFAULT_I2C_BUS_SCL (&pin_PA22) -#define DEFAULT_I2C_BUS_SDA (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) #define DEFAULT_SPI_BUS_SCK (&pin_PB11) #define DEFAULT_SPI_BUS_MOSI (&pin_PB10) diff --git a/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk index 8607385d22..0f90dba6a1 100644 --- a/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk @@ -18,7 +18,7 @@ CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_BUSIO = 0 -CIRCUITPY_STORAGE = 0 +CIRCUITPY_STORAGE = 1 CIRCUITPY_MATH = 1 CIRCUITPY_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/sensebox_mcu/board.c b/ports/atmel-samd/boards/sensebox_mcu/board.c new file mode 100644 index 0000000000..7af05ba45a --- /dev/null +++ b/ports/atmel-samd/boards/sensebox_mcu/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft 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/board.h" +#include "mpconfigboard.h" +#include "hal/include/hal_gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.h b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.h new file mode 100644 index 0000000000..13aca289f6 --- /dev/null +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.h @@ -0,0 +1,24 @@ +#define MICROPY_HW_BOARD_NAME "senseBox MCU" +#define MICROPY_HW_MCU_NAME "senseBox" + +#define MICROPY_HW_LED_STATUS (&pin_PA27) + +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA09) +#define DEFAULT_I2C_BUS_SDA (&pin_PA08) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA19) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) + +#define SAMD21_BOD33_LEVEL (6) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk new file mode 100644 index 0000000000..f5ce4a5d13 --- /dev/null +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x04D8 +USB_PID = 0xEF67 +USB_PRODUCT = "senseBox MCU" +USB_MANUFACTURER = "senseBox" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/sensebox_mcu/pins.c b/ports/atmel-samd/boards/sensebox_mcu/pins.c new file mode 100644 index 0000000000..55afcc989e --- /dev/null +++ b/ports/atmel-samd/boards/sensebox_mcu/pins.c @@ -0,0 +1,71 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + // Analog pins + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA02) }, + + // Digital pins + // { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PA28) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB09) }, + + // UART pins + { MP_ROM_QSTR(MP_QSTR_UART_PWR), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA22) }, // alias of TX1 + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA23) }, // alias of RX1 + + // SPI pins + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, + + // I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_PWR), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA08) }, + + // LED pins + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA28) }, + + // XBEE pins + { MP_ROM_QSTR(MP_QSTR_XB1_PWR), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_XB2_PWR), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_XB1_CS), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_XB2_CS), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_XB1_INT), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_XB2_INT), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_XB1_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_XB1_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_XB2_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_XB2_TX), MP_ROM_PTR(&pin_PA10) }, + + + // Comm objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 2962035cb9..f04055d43b 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -41,6 +41,7 @@ CIRCUITPY_BUILTINS_POW3 ?= 0 CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 1 CIRCUITPY_FREQUENCYIO ?= 0 CIRCUITPY_JSON ?= 0 +CIRCUITPY_SYNTHIO ?= 0 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 # No room for HCI _bleio on SAMD21. @@ -87,3 +88,22 @@ CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) endif # samd51 ###################################################################### + +###################################################################### +# Put same51-only choices here. + +ifeq ($(CHIP_FAMILY),same51) + +# No native touchio on SAMD51. +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 + +# The ?='s allow overriding in mpconfigboard.mk. + +CIRCUITPY_NETWORK ?= 0 +CIRCUITPY_PS2IO ?= 1 +CIRCUITPY_SAMD ?= 1 +CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD) +CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) + +endif # same51 +###################################################################### diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/board.c b/ports/esp32s2/boards/atmegazero_esp32s2/board.c new file mode 100644 index 0000000000..d8fd3a0a2b --- /dev/null +++ b/ports/esp32s2/boards/atmegazero_esp32s2/board.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft 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/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART +#ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); +#endif /* DEBUG */ + + // SPI Flash and RAM + common_hal_never_reset_pin(&pin_GPIO26); + common_hal_never_reset_pin(&pin_GPIO27); + common_hal_never_reset_pin(&pin_GPIO28); + common_hal_never_reset_pin(&pin_GPIO29); + common_hal_never_reset_pin(&pin_GPIO30); + common_hal_never_reset_pin(&pin_GPIO31); + common_hal_never_reset_pin(&pin_GPIO32); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h b/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h new file mode 100644 index 0000000000..3ef4e7eede --- /dev/null +++ b/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft 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. + */ + +//Micropython setup + +#define MICROPY_HW_BOARD_NAME "ATMegaZero ESP32-S2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO40) diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.mk b/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.mk new file mode 100644 index 0000000000..9a5d947e6c --- /dev/null +++ b/ports/esp32s2/boards/atmegazero_esp32s2/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x239A +USB_PID = 0x8009 +USB_PRODUCT = "ATMegaZero ESP32-S2" +USB_MANUFACTURER = "ATMegaZero" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=qio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=16MB diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/pins.c b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c new file mode 100644 index 0000000000..cfc4ef6223 --- /dev/null +++ b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c @@ -0,0 +1,80 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_PD5), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_HWD), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/sdkconfig b/ports/esp32s2/boards/atmegazero_esp32s2/sdkconfig new file mode 100644 index 0000000000..f42e0784c4 --- /dev/null +++ b/ports/esp32s2/boards/atmegazero_esp32s2/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="ATMegaZero-Esp32s2" +# end of LWIP diff --git a/ports/nrf/boards/aramcon2_badge/board.c b/ports/nrf/boards/aramcon2_badge/board.c new file mode 100644 index 0000000000..1759822a2a --- /dev/null +++ b/ports/nrf/boards/aramcon2_badge/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Uri Shaked + * Copyright (c) 2021 Benjamin Meisels + * + * 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/board.h" +#include "common-hal/microcontroller/Pin.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/aramcon2_badge/mpconfigboard.h b/ports/nrf/boards/aramcon2_badge/mpconfigboard.h new file mode 100644 index 0000000000..7691d1e461 --- /dev/null +++ b/ports/nrf/boards/aramcon2_badge/mpconfigboard.h @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Uri Shaked + * Copyright (c) 2021 Benjamin Meisels + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "ARAMCON2 Badge" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define MICROPY_HW_LED_STATUS (&pin_P1_11) + +// Board does not have a 32kHz crystal. It does have a 32MHz crystal. +#define BOARD_HAS_32KHZ_XTAL (0) + +#ifdef QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 20) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 4) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 6) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 0) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 2) +#endif + +#ifdef SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_20 +#define SPI_FLASH_MISO_PIN &pin_P0_22 +#define SPI_FLASH_SCK_PIN &pin_P1_00 +#define SPI_FLASH_CS_PIN &pin_P1_02 +#endif + +#define CIRCUITPY_BOOT_BUTTON (&pin_P0_29) + +#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 BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_28) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_03) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_01) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_10) +#define DEFAULT_SPI_BUS_MISO (&pin_P1_09) diff --git a/ports/nrf/boards/aramcon2_badge/mpconfigboard.mk b/ports/nrf/boards/aramcon2_badge/mpconfigboard.mk new file mode 100644 index 0000000000..514712f489 --- /dev/null +++ b/ports/nrf/boards/aramcon2_badge/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x239A +USB_PID = 0x807C +USB_PRODUCT = "ARAMCON2 Badge" +USB_MANUFACTURER = "ARAMCON Badge Team" + +MCU_CHIP = nrf52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY_DISPLAYIO = 1 diff --git a/ports/nrf/boards/aramcon2_badge/pins.c b/ports/nrf/boards/aramcon2_badge/pins.c new file mode 100644 index 0000000000..0a44f0d5a9 --- /dev/null +++ b/ports/nrf/boards/aramcon2_badge/pins.c @@ -0,0 +1,42 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_UP_BUTTON), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_LEFT_BUTTON), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_DOWN_BUTTON), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_RIGHT_BUTTON), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_ACTION_BUTTON), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P1_11) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_03) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_09) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_P0_05) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_DISP_BUSY), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_DISP_CS), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_DISP_DC), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_DISP_RESET), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_VIBRATION_MOTOR), MP_ROM_PTR(&pin_P0_17) }, + + { MP_ROM_QSTR(MP_QSTR_BATTERY_SENSE), MP_ROM_PTR(&pin_P0_30) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index 74080a1ed9..dd59eb96c9 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -7,6 +7,7 @@ MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_ALARM = 0 CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITMAPTOOLS = 0 diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 005ec8af2f..e235fd1051 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -10,11 +10,13 @@ MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 +CIRCUITPY_ALARM = 0 CIRCUITPY_AESIO = 1 CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSIO = 1 +CIRCUITPY_COUNTIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_ERRNO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 @@ -23,10 +25,13 @@ CIRCUITPY_MSGPACK = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_NVM = 0 CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 1 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_SYNTHIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 CIRCUITPY_USB_CDC = 0 diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c index 4c5de3124e..f651b93b6b 100644 --- a/ports/nrf/common-hal/_bleio/Characteristic.c +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -131,6 +131,10 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel return 0; } +size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) { + return self->max_length; +} + void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { // Do GATT operations only if this characteristic has been added to a registered service. if (self->handle != BLE_GATT_HANDLE_INVALID) { diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c index 42fc3475d6..260e20514b 100644 --- a/ports/nrf/common-hal/_bleio/PacketBuffer.c +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c @@ -42,7 +42,8 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) { if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) { - // This shouldn't happen. + // This shouldn't happen but can if our buffer size was much smaller than + // the writes the client actually makes. return; } // Push all the data onto the ring buffer. @@ -189,7 +190,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) { void common_hal_bleio_packet_buffer_construct( bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, - size_t buffer_size) { + size_t buffer_size, size_t max_packet_size) { self->characteristic = characteristic; self->client = self->characteristic->service->is_remote; @@ -206,8 +207,11 @@ void common_hal_bleio_packet_buffer_construct( self->conn_handle = BLE_CONN_HANDLE_INVALID; } + // Cap the packet size to our implementation limits. + self->max_packet_size = MIN(max_packet_size, BLE_GATTS_VAR_ATTR_LEN_MAX - 3); + if (incoming) { - if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) { + if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + self->max_packet_size), false)) { mp_raise_ValueError(translate("Buffer too large and unable to allocate")); } } @@ -216,8 +220,8 @@ void common_hal_bleio_packet_buffer_construct( self->packet_queued = false; self->pending_index = 0; self->pending_size = 0; - self->outgoing[0] = m_malloc(characteristic->max_length, false); - self->outgoing[1] = m_malloc(characteristic->max_length, false); + self->outgoing[0] = m_malloc(self->max_packet_size, false); + self->outgoing[1] = m_malloc(self->max_packet_size, false); } else { self->outgoing[0] = NULL; self->outgoing[1] = NULL; @@ -296,10 +300,16 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, u } uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self); - if (len + header_len > outgoing_packet_length) { + uint16_t total_len = len + header_len; + if (total_len > outgoing_packet_length) { // Supplied data will not fit in a single BLE packet. - mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length")); + mp_raise_ValueError_varg(translate("Total data to write is larger than %q"), MP_QSTR_outgoing_packet_length); } + if (total_len > self->max_packet_size) { + // Supplied data will not fit in a single BLE packet. + mp_raise_ValueError_varg(translate("Total data to write is larger than %q"), MP_QSTR_max_packet_size); + } + outgoing_packet_length = MIN(outgoing_packet_length, self->max_packet_size); if (len + self->pending_size > outgoing_packet_length) { // No room to append len bytes to packet. Wait until we get a free buffer, @@ -390,8 +400,9 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) { bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle); if (connection) { - return MIN(common_hal_bleio_connection_get_max_packet_length(connection), - self->characteristic->max_length); + return MIN(MIN(common_hal_bleio_connection_get_max_packet_length(connection), + self->max_packet_size), + self->characteristic->max_length); } } // There's no current connection, so we don't know the MTU, and @@ -406,11 +417,12 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) { bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle); if (connection) { - return common_hal_bleio_connection_get_max_packet_length(connection); + return MIN(common_hal_bleio_connection_get_max_packet_length(connection), + self->max_packet_size); } } } - return self->characteristic->max_length; + return MIN(self->characteristic->max_length, self->max_packet_size); } bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.h b/ports/nrf/common-hal/_bleio/PacketBuffer.h index 94e0f11d80..6f2626565b 100644 --- a/ports/nrf/common-hal/_bleio/PacketBuffer.h +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.h @@ -44,6 +44,7 @@ typedef struct { // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client. // We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read). volatile uint16_t conn_handle; + uint16_t max_packet_size; uint8_t pending_index; uint8_t write_type; bool client; diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 367f305972..e20f893567 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -3,8 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 microDev - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -57,22 +56,22 @@ void set_memory_retention(void) { // nRF52833 has RAM[0..7].Section[0..1] and RAM[8].Section[0,1] for(int block = 0; block <= 7; ++block) { nrf_power_rampower_mask_on(NRF_POWER, block, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); }; #ifdef NRF52840 nrf_power_rampower_mask_on(NRF_POWER, 8, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK | - NRF_POWER_RAMPOWER_S2RETENTION_MASK | - NRF_POWER_RAMPOWER_S3RETENTION_MASK | - NRF_POWER_RAMPOWER_S4RETENTION_MASK | - NRF_POWER_RAMPOWER_S5RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK | + NRF_POWER_RAMPOWER_S2RETENTION_MASK | + NRF_POWER_RAMPOWER_S3RETENTION_MASK | + NRF_POWER_RAMPOWER_S4RETENTION_MASK | + NRF_POWER_RAMPOWER_S5RETENTION_MASK); #endif #ifdef NRF52833 nrf_power_rampower_mask_on(NRF_POWER, 8, - NRF_POWER_RAMPOWER_S0RETENTION_MASK | - NRF_POWER_RAMPOWER_S1RETENTION_MASK); + NRF_POWER_RAMPOWER_S0RETENTION_MASK | + NRF_POWER_RAMPOWER_S1RETENTION_MASK); #endif } @@ -93,7 +92,7 @@ void alarm_sleep_memory_reset(void) { if (!is_sleep_memory_valid()) { initialize_sleep_memory(); #ifdef NRF_DEBUG_PRINT - dbg_printf("sleep memory initialized\r\n"); + dbg_printf("sleep memory initialized\r\n"); #endif } } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index 11cc4a8fb9..8fd702ea83 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index f678b5f22b..4c00cc4216 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -102,7 +102,7 @@ static const char* cause_str[] = { void print_wakeup_cause(nrf_sleep_source_t cause) { if (cause >= 0 && cause < NRF_SLEEP_WAKEUP_ZZZ) { dbg_printf("wakeup cause = NRF_SLEEP_WAKEUP_%s\r\n", - cause_str[(int)cause]); + cause_str[(int)cause]); } } #endif @@ -115,14 +115,14 @@ bool common_hal_alarm_woken_from_sleep(void) { } #endif return (cause == NRF_SLEEP_WAKEUP_GPIO || cause == NRF_SLEEP_WAKEUP_TIMER - || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); + || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); } nrf_sleep_source_t alarm_woken_from_sleep_2(void) { nrf_sleep_source_t cause = _get_wakeup_cause(); if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { return cause; } else { @@ -160,6 +160,9 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); } +// TODO: this handles all possible types of wakeup, which is redundant with main. +// revise to extract all parts essential to enabling sleep wakeup, but leave the +// alarm/non-alarm sorting to the existing main loop. nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { bool have_timeout = false; uint64_t start_tick = 0, end_tick = 0; @@ -172,22 +175,22 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres if (timediff_ms != -1) { have_timeout = true; #if 0 - int64_t now = common_hal_time_monotonic_ms(); - dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); + int64_t now = common_hal_time_monotonic_ms(); + dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); #endif - if (timediff_ms < 0) timediff_ms = 0; - if (prescaler == 0) { - // 1 tick = 1/1024 sec = 1000/1024 ms - // -> 1 ms = 1024/1000 ticks - tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks - } - else { - // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms - // -> 1ms = 1024/(1000*prescaler) ticks - tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); - } - start_tick = port_get_raw_ticks(NULL); - end_tick = start_tick + tickdiff; + if (timediff_ms < 0) timediff_ms = 0; + if (prescaler == 0) { + // 1 tick = 1/1024 sec = 1000/1024 ms + // -> 1 ms = 1024/1000 ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks + } + else { + // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms + // -> 1ms = 1024/(1000*prescaler) ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); + } + start_tick = port_get_raw_ticks(NULL); + end_tick = start_tick + tickdiff; } #if 0 dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); @@ -207,30 +210,30 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres #endif while(1) { - if (mp_hal_is_interrupted()) { - WAKEUP_REASON('I'); - break; - } + if (mp_hal_is_interrupted()) { + WAKEUP_REASON('I'); + break; + } if (serial_connected() && serial_bytes_available()) { - WAKEUP_REASON('S'); - break; - } + WAKEUP_REASON('S'); + break; + } RUN_BACKGROUND_TASKS; - wakeup_cause = alarm_woken_from_sleep_2(); - if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { - WAKEUP_REASON('0'+wakeup_cause); - break; - } - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - // We break a bit early so we don't risk setting the alarm before the time when we call - // sleep. - if (remaining < 1) { - WAKEUP_REASON('t'); - break; - } - port_interrupt_after_ticks(remaining); - } + wakeup_cause = alarm_woken_from_sleep_2(); + if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + WAKEUP_REASON('0'+wakeup_cause); + break; + } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + // We break a bit early so we don't risk setting the alarm before the time when we call + // sleep. + if (remaining < 1) { + WAKEUP_REASON('t'); + break; + } + port_interrupt_after_ticks(remaining); + } // Idle until an interrupt happens. port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT @@ -239,15 +242,15 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres --ct; } #endif - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - if (remaining <= 0) { - wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; - sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; - WAKEUP_REASON('T'); - break; - } - } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + if (remaining <= 0) { + wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + WAKEUP_REASON('T'); + break; + } + } } #ifdef NRF_DEBUG_PRINT dbg_printf("%c\r\n", reason); @@ -324,7 +327,7 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { #endif nrf_sleep_source_t cause; cause = system_on_idle_until_alarm(timediff_ms, - PRESCALER_VALUE_IN_DEEP_SLEEP); + PRESCALER_VALUE_IN_DEEP_SLEEP); (void)cause; #ifdef NRF_DEBUG_PRINT @@ -375,13 +378,13 @@ void common_hal_alarm_pretending_deep_sleep(void) { print_wakeup_cause(cause); #endif - alarm_reset(); + // alarm_reset(); #if 0 // if one of Alarm event occurred, reset myself if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { reset_cpu(); } // else, just return and go into REPL diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 642fb7d93a..47051dbd72 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -31,13 +31,13 @@ #include "common-hal/alarm/SleepMemory.h" typedef enum { - NRF_SLEEP_WAKEUP_UNDEFINED, - NRF_SLEEP_WAKEUP_GPIO, - NRF_SLEEP_WAKEUP_TIMER, - NRF_SLEEP_WAKEUP_TOUCHPAD, - NRF_SLEEP_WAKEUP_VBUS, - NRF_SLEEP_WAKEUP_RESETPIN, - NRF_SLEEP_WAKEUP_ZZZ + NRF_SLEEP_WAKEUP_UNDEFINED, + NRF_SLEEP_WAKEUP_GPIO, + NRF_SLEEP_WAKEUP_TIMER, + NRF_SLEEP_WAKEUP_TOUCHPAD, + NRF_SLEEP_WAKEUP_VBUS, + NRF_SLEEP_WAKEUP_RESETPIN, + NRF_SLEEP_WAKEUP_ZZZ } nrf_sleep_source_t; extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index fcfd02f84c..59bb4a84a1 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -87,7 +87,7 @@ static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t bool alarm_pin_pinalarm_woke_us_up(void) { return (sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN && - sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); + sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); } mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { @@ -97,7 +97,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); - if (alarm->pin->number == sleepmem_wakeup_pin) { + if (alarm->pin->number == sleepmem_wakeup_pin) { return alarms[i]; } } @@ -130,8 +130,8 @@ void alarm_pin_pinalarm_reset(void) { continue; } reset_pin_number(i); - nrfx_gpiote_in_event_disable((nrfx_gpiote_pin_t)i); - nrfx_gpiote_in_uninit((nrfx_gpiote_pin_t)i); + nrfx_gpiote_in_event_disable((nrfx_gpiote_pin_t)i); + nrfx_gpiote_in_uninit((nrfx_gpiote_pin_t)i); } high_alarms = 0; @@ -178,15 +178,15 @@ static void configure_pins_for_sleep(void) { cfg.pull = NRF_GPIO_PIN_NOPULL; } err = nrfx_gpiote_in_init((nrfx_gpiote_pin_t)i, &cfg, - pinalarm_gpiote_handler); - assert(err == NRFX_SUCCESS); + pinalarm_gpiote_handler); + assert(err == NRFX_SUCCESS); nrfx_gpiote_in_event_enable((nrfx_gpiote_pin_t)i, true); if (((high_alarms & mask) != 0) && ((low_alarms & mask) == 0)) { nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_HIGH); - } + } if (((high_alarms & mask) == 0) && ((low_alarms & mask) != 0)) { nrf_gpio_cfg_sense_set((uint32_t)i, NRF_GPIO_PIN_SENSE_LOW); - } + } } } @@ -203,7 +203,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); pin_number = alarm->pin->number; - //dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); + //dbg_printf("alarm_pin_pinalarm_set_alarms(pin#=%d, val=%d, pull=%d)\r\n", pin_number, alarm->value, alarm->pull); if (alarm->value) { high_alarms |= 1ull << pin_number; high_count++; @@ -222,8 +222,8 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob else { // we don't setup gpio HW here but do them in // alarm_pin_pinalarm_prepare_for_deep_sleep() below - reset_reason_saved = 0; - pins_configured = false; + reset_reason_saved = 0; + pins_configured = false; } } else { @@ -234,9 +234,9 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob void alarm_pin_pinalarm_prepare_for_deep_sleep(void) { if (!pins_configured) { configure_pins_for_sleep(); - pins_configured = true; + pins_configured = true; #ifdef NRF_DEBUG_PRINT - //dbg_dump_GPIOregs(); + //dbg_dump_GPIOregs(); #endif } } diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.h b/ports/nrf/common-hal/alarm/pin/PinAlarm.h index 93672c1f2d..69684386fa 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.h +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index a824c52535..2f65764e19 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * Copyright (c) 2021 Junji Sakai * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index 4baa4eaace..bcad002ffe 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -141,9 +141,9 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { r = RESET_REASON_SOFTWARE; } else if ((reset_reason_saved & POWER_RESETREAS_OFF_Msk) || - (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || - (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || - (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { + (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || + (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || + (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { r = RESET_REASON_DEEP_SLEEP_ALARM; } return r; diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index a5766cf1fe..132aba208f 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -47,7 +47,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_WATCHDOG ?= 1 # Sleep and Wakeup -CIRCUITPY_ALARM = 1 +CIRCUITPY_ALARM ?= 1 # nRF52840-specific diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index f770b661fc..9cf33279f7 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -1,6 +1,27 @@ /* - * debug functions - * (will be removed) + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jun2Sak + * + * 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 @@ -33,11 +54,11 @@ static char _dbg_pbuf[DBG_PBUF_LEN+1]; void _debug_uart_uninit(void) { nrf_gpio_cfg(DEBUG_UART_TXPIN, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); nrfx_uarte_uninit(&_dbg_uart_inst); } @@ -59,11 +80,11 @@ void _debug_uart_init(void) { nrfx_uarte_init(&_dbg_uart_inst, &config, NULL); // drive config nrf_gpio_cfg(config.pseltxd, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_PULLUP, // orig=NOPULL - NRF_GPIO_PIN_H0H1, // orig=S0S1 - NRF_GPIO_PIN_NOSENSE); + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_PULLUP, // orig=NOPULL + NRF_GPIO_PIN_H0H1, // orig=S0S1 + NRF_GPIO_PIN_NOSENSE); _dbg_uart_initialized = 1; return; } @@ -73,16 +94,16 @@ void _debug_print_substr(const char* text, uint32_t length) { int siz; while(length != 0) { if (length <= DBG_PBUF_LEN) { - siz = length; - } - else { - siz = DBG_PBUF_LEN; - } - memcpy(_dbg_pbuf, data, siz); - _dbg_pbuf[siz] = 0; - nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); - data += siz; - length -= siz; + siz = length; + } + else { + siz = DBG_PBUF_LEN; + } + memcpy(_dbg_pbuf, data, siz); + _dbg_pbuf[siz] = 0; + nrfx_uarte_tx(&_dbg_uart_inst, (uint8_t const*)_dbg_pbuf, siz); + data += siz; + length -= siz; } } @@ -113,7 +134,7 @@ int dbg_check_RTCprescaler(void) { NRF_RTC_Type *r = rtc_instance.p_reg; if ((int)r->PRESCALER == 0) { dbg_printf("****** PRESCALER == 0\r\n"); - return -1; + return -1; } return 0; } @@ -135,20 +156,20 @@ void dbg_dump_GPIOregs(void) { const char cnf_sense_chr[] = "-?HL"; // sense high, sense low for(port=0, col=0; port<=1; ++port) { for(i=0; i<32; ++i) { - uint32_t cnf = gpio[port]->PIN_CNF[i]; - if (cnf != 0x0002) { // changed from default value - dbg_printf("[%d_%02d]:%c%c%c%d%c ", port, i, - (cnf & 1) ? 'O' : 'I', // output, input - (cnf & 2) ? 'd' : 'c', // disconnected, connected - cnf_pull_chr[(cnf >> 2) & 3], - (int)((cnf >> 8) & 7), // drive config 0-7 - cnf_sense_chr[(cnf >> 16) & 3]); - if (++col >= 6) { - dbg_printf("\r\n"); - col = 0; - } - } - } + uint32_t cnf = gpio[port]->PIN_CNF[i]; + if (cnf != 0x0002) { // changed from default value + dbg_printf("[%d_%02d]:%c%c%c%d%c ", port, i, + (cnf & 1) ? 'O' : 'I', // output, input + (cnf & 2) ? 'd' : 'c', // disconnected, connected + cnf_pull_chr[(cnf >> 2) & 3], + (int)((cnf >> 8) & 7), // drive config 0-7 + cnf_sense_chr[(cnf >> 16) & 3]); + if (++col >= 6) { + dbg_printf("\r\n"); + col = 0; + } + } + } } if (col > 0) dbg_printf("\r\n"); @@ -159,26 +180,26 @@ void dbg_dump_GPIOregs(void) { const char config_outinit_chr[] = "01"; // initial value is 0 or 1 for(i=0, col=0; i<8; ++i) { uint32_t conf = reg->CONFIG[i]; - if (conf != 0) { // changed from default value - dbg_printf("CONFIG[%d]:%d_%02d,%c%c%c ", i, - (int)((conf >> 13) & 1), (int)((conf >> 8) & 0x1F), - config_mode_chr[conf & 3], - config_pol_chr[(conf >> 16) & 3], - (conf & 3) == 3 ? - config_outinit_chr[(conf >> 20) & 1] : '-'); - if (++col >= 4) { - dbg_printf("\r\n"); - col = 0; - } - } + if (conf != 0) { // changed from default value + dbg_printf("CONFIG[%d]:%d_%02d,%c%c%c ", i, + (int)((conf >> 13) & 1), (int)((conf >> 8) & 0x1F), + config_mode_chr[conf & 3], + config_pol_chr[(conf >> 16) & 3], + (conf & 3) == 3 ? + config_outinit_chr[(conf >> 20) & 1] : '-'); + if (++col >= 4) { + dbg_printf("\r\n"); + col = 0; + } + } } if (col > 0) dbg_printf("\r\n"); for(i=0; i<8; ++i) { dbg_printf("EVENTS_IN[%d]:%X ", i, (int)(reg->EVENTS_IN[i])); - if ((i & 3) == 3) dbg_printf("\r\n"); + if ((i & 3) == 3) dbg_printf("\r\n"); } dbg_printf("EVENTS_PORT:%X INTENSET:%08X\r\n", - (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); + (int)(reg->EVENTS_PORT), (int)(reg->INTENSET)); } void dbg_dumpQSPIreg(void) { @@ -186,13 +207,13 @@ void dbg_dumpQSPIreg(void) { dbg_printf("QSPI\r\n"); r = NRF_QSPI->IFCONFIG0; dbg_printf("IFCONFIG0 READ=%ld write=%ld ADDR=%ld DPM=%ld PPSIZE=%ld\r\n", - r & 7, (r >> 3) & 7, (r >> 6) & 1, (r >> 7) & 1, (r >> 12) & 1); + r & 7, (r >> 3) & 7, (r >> 6) & 1, (r >> 7) & 1, (r >> 12) & 1); r = NRF_QSPI->IFCONFIG1; dbg_printf("IFCONFIG1 SCKDELAY=%ld SPIMODE=%ld SCKFREQ=%ld\r\n", - r & 0xFF, (r >> 25) & 1, (r >> 28) & 0xF); + r & 0xFF, (r >> 25) & 1, (r >> 28) & 0xF); r = NRF_QSPI->STATUS; dbg_printf("STATUS DPM=%ld READY=%ld SREG=0x%02lX\r\n", - (r >> 2) & 1, (r >> 3) & 1, (r >> 24) & 0xFF); + (r >> 2) & 1, (r >> 3) & 1, (r >> 24) & 0xFF); r = NRF_QSPI->DPMDUR; dbg_printf("DPMDUR ENTER=%ld EXIT=%ld\r\n", r & 0xFFFF, (r >> 16) & 0xFFFF); } diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index c984feb77d..e162c64837 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -109,7 +109,9 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { nrfx_rtc_cc_set(&rtc_instance, 0, 0, false); } else if (int_type == NRFX_RTC_INT_COMPARE1) { // used in light sleep + #if CIRCUITPY_ALARM sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + #endif nrfx_rtc_cc_set(&rtc_instance, 1, 0, false); } } @@ -185,7 +187,9 @@ safe_mode_t port_init(void) { NRF_POWER->RESETREAS = reset_reason_saved; // clear wakeup event/pin when reset by reset-pin if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { + #if CIRCUITPY_ALARM sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + #endif } // If the board was reset by the WatchDogTimer, we may diff --git a/ports/nrf/supervisor/qspi_flash.c b/ports/nrf/supervisor/qspi_flash.c index f2beb3e3a9..6d1bec4422 100644 --- a/ports/nrf/supervisor/qspi_flash.c +++ b/ports/nrf/supervisor/qspi_flash.c @@ -281,7 +281,7 @@ void qspi_flash_enter_sleep(void) { // set sck_delay tempolarily r = NRF_QSPI->IFCONFIG1; sck_delay_saved = (r & QSPI_IFCONFIG1_SCKDELAY_Msk) - >> QSPI_IFCONFIG1_SCKDELAY_Pos; + >> QSPI_IFCONFIG1_SCKDELAY_Pos; NRF_QSPI->IFCONFIG1 = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) | (SCK_DELAY << QSPI_IFCONFIG1_SCKDELAY_Pos); @@ -312,20 +312,20 @@ void qspi_flash_exit_sleep(void) { if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { // exit deep power-down mode NRF_QSPI->IFCONFIG1 &= ~QSPI_IFCONFIG1_DPMEN_Msk; - NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); + NRFX_DELAY_US(WAIT_AFTER_DPM_EXIT); - if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { + if (NRF_QSPI->STATUS & QSPI_STATUS_DPM_Msk) { #ifdef NRF_DEBUG_PRINT - dbg_printf("qspi flash: exiting DPM failed\r\n"); + dbg_printf("qspi flash: exiting DPM failed\r\n"); #endif - } - // restore sck_delay - if (sck_delay_saved == 0) { - sck_delay_saved = 10; // default - } - NRF_QSPI->IFCONFIG1 - = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) - | (sck_delay_saved << QSPI_IFCONFIG1_SCKDELAY_Pos); + } + // restore sck_delay + if (sck_delay_saved == 0) { + sck_delay_saved = 10; // default + } + NRF_QSPI->IFCONFIG1 + = (NRF_QSPI->IFCONFIG1 & ~QSPI_IFCONFIG1_SCKDELAY_Msk) + | (sck_delay_saved << QSPI_IFCONFIG1_SCKDELAY_Pos); } //dbg_dumpQSPIreg(); #endif diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c new file mode 100644 index 0000000000..67486d4c23 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft 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/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h new file mode 100644 index 0000000000..4261b9e006 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo (16MB)" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_VBUS_DETECT (&pin_GPIO24) +#define MICROPY_HW_BAT_SENSE (&pin_GPIO29) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.mk new file mode 100644 index 0000000000..129f408e5e --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x1003 +USB_PRODUCT = "Pimoroni Pico LiPo (16MB)" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pins.c b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pins.c new file mode 100644 index 0000000000..229d510ead --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_DETECT), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_BAT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c new file mode 100644 index 0000000000..67486d4c23 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft 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/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h new file mode 100644 index 0000000000..e34a05abf2 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo (4MB)" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_VBUS_DETECT (&pin_GPIO24) +#define MICROPY_HW_BAT_SENSE (&pin_GPIO29) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.mk new file mode 100644 index 0000000000..a82ee9c0ea --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x1002 +USB_PRODUCT = "Pimoroni Pico LiPo (4MB)" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pins.c b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pins.c new file mode 100644 index 0000000000..229d510ead --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_DETECT), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_BAT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c index e1927bc80c..057eaec2af 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c +++ b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c @@ -24,18 +24,28 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, }; diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c new file mode 100644 index 0000000000..c4021a83e9 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft 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/board.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h new file mode 100644 index 0000000000..d7dd7a6376 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h @@ -0,0 +1,12 @@ +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod ATP - RP2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk new file mode 100644 index 0000000000..2ed559d8db --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1B4F +USB_PID = 0x0024 +USB_PRODUCT = "MicroMod RP2040" +USB_MANUFACTURER = "SparkFun" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxM" diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c new file mode 100644 index 0000000000..00d6c30cb8 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c @@ -0,0 +1,105 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + // D (Digital only) pins (D0,D1) + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO7) }, // GPIO6 - D0 + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // GPIO7 - D1 + + // A (ADC) pins (A0,A1) + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, // GPIO26 - A0 | ADC0 + { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_GPIO26) }, // ADC0 alias + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, // GPIO27 - A1 | ADC1 + { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_GPIO27) }, // ADC1 alias + + // G (General/BUS) pins (G0-G7, G8 NC, G9-G10, G11 NC) + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO16) }, // GPIO16 - G0 | BUS0 + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_GPIO16) }, // BUS0 alias + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO17) }, // GPIO17 - G1 | BUS1 + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_GPIO17) }, // BUS1 alias + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO18) }, // GPIO18 - G2 | BUS2 + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_GPIO18) }, // BUS2 alias + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO19) }, // GPIO19 - G3 | BUS3 + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_GPIO19) }, // BUS3 alias + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - G4 | BUS4 | SPI_CIPO + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_GPIO20) }, // BUS4 alias + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - G5 | BUS5 | SPI_CS + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_GPIO21) }, // BUS5 alias + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - G6 | BUS6 | SPI_SCK + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_GPIO22) }, // BUS6 alias + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - G7 | BUS7 | SPI_COPI + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_GPIO23) }, // BUS7 alias + // NC - G8 + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO28) }, // GPIO28- G9 | BUS9 | ADC_D- | CAM_HSYNC + { MP_ROM_QSTR(MP_QSTR_BUS9), MP_ROM_PTR(&pin_GPIO28) }, // BUS9 alias + { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_GPIO28) }, // ADC_DM alias + { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_GPIO28) }, // CAM_HSYNC alias + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - G10 | BUS10 | ADC_D+ | CAM_VSYNC + { MP_ROM_QSTR(MP_QSTR_BUS10), MP_ROM_PTR(&pin_GPIO25) }, // BUS10 alias + { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_GPIO25) }, // ADC_DP alias + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO25) }, // CAM_VSYNC alias + // NC - G11 + + // PWM pins (PWM0,PWM1) + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO13) }, // GPIO13 - PWM0 + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - PWM1 | AUD_MCLK + + // AUD (audio) + { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - AUD_MCLK | PWM1 + { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_GPIO10) }, // GPIO10 - AUD_OUT | SDIO_DAT2 + { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_GPIO11) }, // GPIO11 - AUD_IN | SDIO_DAT1 + { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - AUD_LRCLK | CTS1 + { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - AUD_BCLK | UART_RTS1 + + // Battery Voltage Monitor + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_GPIO29) }, // GPIO29 - BATT_VIN/3 (ADC03) + + + // I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, // GPIO4 - SDA + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, // GPIO5 - SCL + + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_GPIO8) }, // GPIO9 - I2C_INT | TX2 + + // SPI + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - CIPO | SPI_CIPO | G4 + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, // MISO alias + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - COPI | SPI_COPI | G7 + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // MOSI alias + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - SCK | SPI_SCK | G6 + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - /CS | SPI_/CS | G5 + + // SDI/SPI1 + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO14) }, // GPIO14 - SDIO SCK | SDIO_CLK + { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_GPIO14) }, // SPI_SCK1 alias + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO15) }, // GPIO15 - SDIO CMD | SDIO_CMD + { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_GPIO15) },// SPI_COPI1 alias + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO12) },// GPIO12 - SDIO DATA0 | SDIO_DATA0 + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_GPIO12) }, // SPI_CIPO1 alias + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO11) },// GPIO11 - SDIO DATA1 | SDIO_DATA1 | AUD_IN + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO10) },// GPIO10 - SDIO DATA2 | SDIO_DATA2 | AUD_OUT + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO9) },// GPIO9 - SDIO DATA3 | SDIO_DATA3 | SPI_CS1 + { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_GPIO9) }, // SPI_CS1 alias + + // Status LED + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - LED_BUILTIN | STAT | Blue LED | G10 + + // UART + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, // GPIO1 - UART RX | UART_RX1 | RX1 + { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO1) }, // RX1 alias + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, // GPIO0 - UART TX | UART_TX1 | TX1 + { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO0) }, // TX1 alias + { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - UART CTS | CTS1 (TRACEDATA3) + { MP_ROM_QSTR(MP_QSTR_CTS1), MP_ROM_PTR(&pin_GPIO2) }, // CTS1 alias + { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - UART RTS | RTS1 + { MP_ROM_QSTR(MP_QSTR_RTS1), MP_ROM_PTR(&pin_GPIO3) }, // RTS1 alias + + { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO9) }, // GPIO9 - UART RX | UART_RX2 | RX2 | SDIO_DAT3 | SPI_CS1 + { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO8) }, // GPIO8 - UART TX | UART_TX2 | TX2 | I2C_INT + + // Board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index cece99afa9..635f1a75e7 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -43,8 +43,7 @@ CIRCUITPY_AUDIOBUSIO ?= 1 CIRCUITPY_AUDIOCORE ?= 1 CIRCUITPY_AUDIOPWMIO ?= 1 -# These libraries require Cortex M4+ for fancy math instructions. -CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_AUDIOMIXER = 1 INTERNAL_LIBM = 1 diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk index 76acd7ed1e..211a658967 100644 --- a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk @@ -16,3 +16,5 @@ MCU_PACKAGE = UFQFPN48 LD_COMMON = boards/common_default.ld LD_FILE = boards/STM32F411_nvm_nofs.ld + +CIRCUITPY_SYNTHIO = 0 diff --git a/py/binary.c b/py/binary.c index 846058525f..cd61d74fa8 100644 --- a/py/binary.c +++ b/py/binary.c @@ -371,11 +371,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** } } - if (val_type == 'x') { - memset(p, 0, 1); - } else { - mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val); - } + mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val); } void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) { diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 0eedfe5249..5745c4f1d2 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -280,6 +280,9 @@ endif ifeq ($(CIRCUITPY_SUPERVISOR),1) SRC_PATTERNS += supervisor/% endif +ifeq ($(CIRCUITPY_SYNTHIO),1) +SRC_PATTERNS += synthio/% +endif ifeq ($(CIRCUITPY_TERMINALIO),1) SRC_PATTERNS += terminalio/% fontio/% endif @@ -524,6 +527,8 @@ SRC_SHARED_MODULE_ALL = \ socket/__init__.c \ storage/__init__.c \ struct/__init__.c \ + synthio/MidiTrack.c \ + synthio/__init__.c \ terminalio/Terminal.c \ terminalio/__init__.c \ time/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index eedda7ad73..801e1867e7 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -728,6 +728,13 @@ extern const struct _mp_obj_module_t supervisor_module; #define SUPERVISOR_MODULE #endif +#if CIRCUITPY_SYNTHIO +#define SYNTHIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_synthio), (mp_obj_t)&synthio_module }, +extern const struct _mp_obj_module_t synthio_module; +#else +#define SYNTHIO_MODULE +#endif + #if CIRCUITPY_TIME extern const struct _mp_obj_module_t time_module; #define TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, @@ -897,6 +904,7 @@ extern const struct _mp_obj_module_t msgpack_module; STORAGE_MODULE \ STRUCT_MODULE \ SUPERVISOR_MODULE \ + SYNTHIO_MODULE \ TOUCHIO_MODULE \ UHEAP_MODULE \ USB_CDC_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 51b590dcf3..600e56ee23 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -311,6 +311,9 @@ CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT) CIRCUITPY_SUPERVISOR ?= 1 CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) +CIRCUITPY_SYNTHIO ?= $(CIRCUITPY_AUDIOCORE) +CFLAGS += -DCIRCUITPY_SYNTHIO=$(CIRCUITPY_SYNTHIO) + CIRCUITPY_TERMINALIO ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) diff --git a/py/compile.c b/py/compile.c index 4a9fdc7db8..7971690d6d 100644 --- a/py/compile.c +++ b/py/compile.c @@ -768,7 +768,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ } if (name_len != 2) { - compile_syntax_error(comp, name_nodes[0], translate("invalid micropython decorator")); + compile_syntax_error(comp, name_nodes[0], translate("invalid decorator")); return true; } diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 0ad749005c..6a6125fe20 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -12,7 +12,6 @@ from __future__ import print_function import re import sys -from math import log import collections import gettext import os.path @@ -167,7 +166,7 @@ def compute_huffman_coding(translations, compression_filename): sum_len = 0 while True: # Until the dictionary is filled to capacity, use a heuristic to find - # the best "word" (2- to 9-gram) to add to it. + # the best "word" (3- to 9-gram) to add to it. # # The TextSplitter allows us to avoid considering parts of the text # that are already covered by a previously chosen word, for example @@ -179,32 +178,25 @@ def compute_huffman_coding(translations, compression_filename): for t in texts: for (found, word) in extractor.iter_words(t): if not found: - for substr in iter_substrings(word, minlen=2, maxlen=9): + for substr in iter_substrings(word, minlen=3, maxlen=9): counter[substr] += 1 # Score the candidates we found. This is an empirical formula only, # chosen for its effectiveness. scores = sorted( - ((s, (len(s) - 1) ** log(max(occ - 2, 1)), occ) for (s, occ) in counter.items()), + ((s, (len(s) - 1) ** (occ + 4)) for (s, occ) in counter.items() if occ > 4), key=lambda x: x[1], reverse=True, ) - # Do we have a "word" that occurred 5 times and got a score of at least - # 5? Horray. Pick the one with the highest score. - word = None - for (s, score, occ) in scores: - if occ < 5: - continue - if score < 5: - break - word = s + # Pick the one with the highest score. + if not scores: break + word = scores[0][0] + # If we can successfully add it to the dictionary, do so. Otherwise, # we've filled the dictionary to capacity and are done. - if not word: - break if sum_len + len(word) - 2 > max_words_len: break if len(words) == max_words: @@ -456,27 +448,24 @@ def parse_input_headers(infiles): return qcfgs, qstrs, i18ns +def escape_bytes(qstr): + if all(32 <= ord(c) <= 126 and c != "\\" and c != '"' for c in qstr): + # qstr is all printable ASCII so render it as-is (for easier debugging) + return qstr + else: + # qstr contains non-printable codes so render entire thing as hex pairs + qbytes = bytes_cons(qstr, "utf8") + return "".join(("\\x%02x" % b) for b in qbytes) def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): qbytes = bytes_cons(qstr, "utf8") qlen = len(qbytes) qhash = compute_hash(qbytes, cfg_bytes_hash) - if all(32 <= ord(c) <= 126 and c != "\\" and c != '"' for c in qstr): - # qstr is all printable ASCII so render it as-is (for easier debugging) - qdata = qstr - else: - # qstr contains non-printable codes so render entire thing as hex pairs - qdata = "".join(("\\x%02x" % b) for b in qbytes) if qlen >= (1 << (8 * cfg_bytes_len)): print("qstr is too long:", qstr) assert False - qlen_str = ("\\x%02x" * cfg_bytes_len) % tuple( - ((qlen >> (8 * i)) & 0xFF) for i in range(cfg_bytes_len) - ) - qhash_str = ("\\x%02x" * cfg_bytes_hash) % tuple( - ((qhash >> (8 * i)) & 0xFF) for i in range(cfg_bytes_hash) - ) - return '(const byte*)"%s%s" "%s"' % (qhash_str, qlen_str, qdata) + qdata = escape_bytes(qstr) + return '%d, %d, "%s"' % (qhash, qlen, qdata) def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns): @@ -489,10 +478,7 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns): print("") # add NULL qstr with no hash or data - print( - 'QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' - % ("\\x00" * cfg_bytes_hash, "\\x00" * cfg_bytes_len) - ) + print('QDEF(MP_QSTR_NULL, 0, 0, "")') total_qstr_size = 0 total_qstr_compressed_size = 0 diff --git a/py/modstruct.c b/py/modstruct.c index 1c5319608d..8f78fa234a 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -214,9 +214,11 @@ STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, c p += cnt; } else { while (cnt--) { - mp_binary_set_val(fmt_type, *fmt, args[i], &p); // Pad bytes don't have a corresponding argument. - if (*fmt != 'x') { + if (*fmt == 'x') { + mp_binary_set_val(fmt_type, *fmt, MP_OBJ_NEW_SMALL_INT(0), &p); + } else { + mp_binary_set_val(fmt_type, *fmt, args[i], &p); i++; } } diff --git a/py/mpstate.h b/py/mpstate.h index 139f23cb4f..1f6a2d00a1 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -197,7 +197,7 @@ typedef struct _mp_state_vm_t { // pointer and sizes to store interned string data // (qstr_last_chunk can be root pointer but is also stored in qstr pool) - byte *qstr_last_chunk; + char *qstr_last_chunk; size_t qstr_last_alloc; size_t qstr_last_used; diff --git a/py/qstr.c b/py/qstr.c index 2ae65379c7..af5ea58686 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -37,7 +37,6 @@ // NOTE: we are using linear arrays to store and search for qstr's (unique strings, interned strings) // ultimately we will replace this with a static hash table of some kind -// also probably need to include the length in the string data, to allow null bytes in the string #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_printf DEBUG_printf @@ -46,34 +45,9 @@ #endif // A qstr is an index into the qstr pool. -// The data for a qstr contains (hash, length, data): -// - hash (configurable number of bytes) -// - length (configurable number of bytes) -// - data ("length" number of bytes) -// - \0 terminated (so they can be printed using printf) +// The data for a qstr is \0 terminated (so they can be printed using printf) -#if MICROPY_QSTR_BYTES_IN_HASH == 1 - #define Q_HASH_MASK (0xff) - #define Q_GET_HASH(q) ((mp_uint_t)(q)[0]) - #define Q_SET_HASH(q, hash) do { (q)[0] = (hash); } while (0) -#elif MICROPY_QSTR_BYTES_IN_HASH == 2 - #define Q_HASH_MASK (0xffff) - #define Q_GET_HASH(q) ((mp_uint_t)(q)[0] | ((mp_uint_t)(q)[1] << 8)) - #define Q_SET_HASH(q, hash) do { (q)[0] = (hash); (q)[1] = (hash) >> 8; } while (0) -#else - #error unimplemented qstr hash decoding -#endif -#define Q_GET_ALLOC(q) (MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + Q_GET_LENGTH(q) + 1) -#define Q_GET_DATA(q) ((q) + MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN) -#if MICROPY_QSTR_BYTES_IN_LEN == 1 - #define Q_GET_LENGTH(q) ((q)[MICROPY_QSTR_BYTES_IN_HASH]) - #define Q_SET_LENGTH(q, len) do { (q)[MICROPY_QSTR_BYTES_IN_HASH] = (len); } while (0) -#elif MICROPY_QSTR_BYTES_IN_LEN == 2 - #define Q_GET_LENGTH(q) ((q)[MICROPY_QSTR_BYTES_IN_HASH] | ((q)[MICROPY_QSTR_BYTES_IN_HASH + 1] << 8)) - #define Q_SET_LENGTH(q, len) do { (q)[MICROPY_QSTR_BYTES_IN_HASH] = (len); (q)[MICROPY_QSTR_BYTES_IN_HASH + 1] = (len) >> 8; } while (0) -#else - #error unimplemented qstr length decoding -#endif +#define Q_HASH_MASK ((1 << (8 * MICROPY_QSTR_BYTES_IN_HASH)) - 1) #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL #define QSTR_ENTER() mp_thread_mutex_lock(&MP_STATE_VM(qstr_mutex), 1) @@ -98,14 +72,25 @@ mp_uint_t qstr_compute_hash(const byte *data, size_t len) { return hash; } +const qstr_attr_t mp_qstr_const_attr[] = { + #ifndef NO_QSTR +#define QDEF(id, hash, len, str) { hash, len }, +#define TRANSLATION(id, length, compressed ...) + #include "genhdr/qstrdefs.generated.h" +#undef TRANSLATION +#undef QDEF + #endif +}; + const qstr_pool_t mp_qstr_const_pool = { NULL, // no previous pool 0, // no previous pool 10, // set so that the first dynamically allocated pool is twice this size; must be <= the len (just below) MP_QSTRnumber_of, // corresponds to number of strings in array just below + (qstr_attr_t *)mp_qstr_const_attr, { #ifndef NO_QSTR -#define QDEF(id, str) str, +#define QDEF(id, hash, len, str) str, #define TRANSLATION(id, length, compressed ...) #include "genhdr/qstrdefs.generated.h" #undef TRANSLATION @@ -130,20 +115,22 @@ void qstr_init(void) { #endif } -STATIC const byte *find_qstr(qstr q) { +STATIC const char *find_qstr(qstr q, qstr_attr_t *attr) { // search pool for this qstr // total_prev_len==0 in the final pool, so the loop will always terminate qstr_pool_t *pool = MP_STATE_VM(last_pool); while (q < pool->total_prev_len) { pool = pool->prev; } - assert(q - pool->total_prev_len < pool->len); - return pool->qstrs[q - pool->total_prev_len]; + q -= pool->total_prev_len; + assert(q < pool->len); + *attr = pool->attrs[q]; + return pool->qstrs[q]; } // qstr_mutex must be taken while in this function -STATIC qstr qstr_add(const byte *q_ptr) { - DEBUG_printf("QSTR: add hash=%d len=%d data=%.*s\n", Q_GET_HASH(q_ptr), Q_GET_LENGTH(q_ptr), Q_GET_LENGTH(q_ptr), Q_GET_DATA(q_ptr)); +STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) { + DEBUG_printf("QSTR: add hash=%d len=%d data=%.*s\n", hash, len, len, q_ptr); // make sure we have room in the pool for a new qstr if (MP_STATE_VM(last_pool)->len >= MP_STATE_VM(last_pool)->alloc) { @@ -151,11 +138,14 @@ STATIC qstr qstr_add(const byte *q_ptr) { if (new_pool_length > MICROPY_QSTR_POOL_MAX_ENTRIES) { new_pool_length = MICROPY_QSTR_POOL_MAX_ENTRIES; } - qstr_pool_t *pool = m_new_ll_obj_var_maybe(qstr_pool_t, const char *, new_pool_length); - if (pool == NULL) { + mp_uint_t pool_size = sizeof(qstr_pool_t) + sizeof(const char *) * new_pool_length; + void *chunk = m_malloc_maybe(pool_size + sizeof(qstr_attr_t) * new_pool_length, true); + if (chunk == NULL) { QSTR_EXIT(); m_malloc_fail(new_pool_length); } + qstr_pool_t *pool = (qstr_pool_t *)chunk; + pool->attrs = (qstr_attr_t *)(void *)((char *)chunk + pool_size); pool->prev = MP_STATE_VM(last_pool); pool->total_prev_len = MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len; pool->alloc = new_pool_length; @@ -165,10 +155,14 @@ STATIC qstr qstr_add(const byte *q_ptr) { } // add the new qstr - MP_STATE_VM(last_pool)->qstrs[MP_STATE_VM(last_pool)->len++] = q_ptr; + mp_uint_t at = MP_STATE_VM(last_pool)->len; + MP_STATE_VM(last_pool)->attrs[at].hash = hash; + MP_STATE_VM(last_pool)->attrs[at].len = len; + MP_STATE_VM(last_pool)->qstrs[at] = q_ptr; + MP_STATE_VM(last_pool)->len++; // return id for the newly-added qstr - return MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len - 1; + return MP_STATE_VM(last_pool)->total_prev_len + at; } qstr qstr_find_strn(const char *str, size_t str_len) { @@ -177,9 +171,10 @@ qstr qstr_find_strn(const char *str, size_t str_len) { // search pools for the data for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL; pool = pool->prev) { - for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) { - if (Q_GET_HASH(*q) == str_hash && Q_GET_LENGTH(*q) == str_len && memcmp(Q_GET_DATA(*q), str, str_len) == 0) { - return pool->total_prev_len + (q - pool->qstrs); + qstr_attr_t *attrs = pool->attrs; + for (mp_uint_t at = 0, top = pool->len; at < top; at++) { + if (attrs[at].hash == str_hash && attrs[at].len == str_len && memcmp(pool->qstrs[at], str, str_len) == 0) { + return pool->total_prev_len + at; } } } @@ -200,14 +195,14 @@ qstr qstr_from_strn(const char *str, size_t len) { // qstr does not exist in interned pool so need to add it // compute number of bytes needed to intern this string - size_t n_bytes = MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len + 1; + size_t n_bytes = len + 1; if (MP_STATE_VM(qstr_last_chunk) != NULL && MP_STATE_VM(qstr_last_used) + n_bytes > MP_STATE_VM(qstr_last_alloc)) { // not enough room at end of previously interned string so try to grow - byte *new_p = m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_alloc) + n_bytes, false); + char *new_p = m_renew_maybe(char, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_alloc) + n_bytes, false); if (new_p == NULL) { // could not grow existing memory; shrink it to fit previous - (void)m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used), false); + (void)m_renew_maybe(char, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used), false); MP_STATE_VM(qstr_last_chunk) = NULL; } else { // could grow existing memory @@ -221,10 +216,10 @@ qstr qstr_from_strn(const char *str, size_t len) { if (al < MICROPY_ALLOC_QSTR_CHUNK_INIT) { al = MICROPY_ALLOC_QSTR_CHUNK_INIT; } - MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(byte, al); + MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(char, al); if (MP_STATE_VM(qstr_last_chunk) == NULL) { // failed to allocate a large chunk so try with exact size - MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(byte, n_bytes); + MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(char, n_bytes); if (MP_STATE_VM(qstr_last_chunk) == NULL) { QSTR_EXIT(); m_malloc_fail(n_bytes); @@ -236,39 +231,41 @@ qstr qstr_from_strn(const char *str, size_t len) { } // allocate memory from the chunk for this new interned string's data - byte *q_ptr = MP_STATE_VM(qstr_last_chunk) + MP_STATE_VM(qstr_last_used); + char *q_ptr = MP_STATE_VM(qstr_last_chunk) + MP_STATE_VM(qstr_last_used); MP_STATE_VM(qstr_last_used) += n_bytes; // store the interned strings' data mp_uint_t hash = qstr_compute_hash((const byte *)str, len); - Q_SET_HASH(q_ptr, hash); - Q_SET_LENGTH(q_ptr, len); - memcpy(q_ptr + MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN, str, len); - q_ptr[MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len] = '\0'; - q = qstr_add(q_ptr); + memcpy(q_ptr, str, len); + q_ptr[len] = '\0'; + q = qstr_add(hash, len, q_ptr); } QSTR_EXIT(); return q; } mp_uint_t PLACE_IN_ITCM(qstr_hash)(qstr q) { - return Q_GET_HASH(find_qstr(q)); + qstr_attr_t attr; + find_qstr(q, &attr); + return attr.hash; } size_t qstr_len(qstr q) { - const byte *qd = find_qstr(q); - return Q_GET_LENGTH(qd); + qstr_attr_t attr; + find_qstr(q, &attr); + return attr.len; } const char *qstr_str(qstr q) { - const byte *qd = find_qstr(q); - return (const char *)Q_GET_DATA(qd); + qstr_attr_t attr; + return find_qstr(q, &attr); } const byte *qstr_data(qstr q, size_t *len) { - const byte *qd = find_qstr(q); - *len = Q_GET_LENGTH(qd); - return Q_GET_DATA(qd); + qstr_attr_t attr; + const char *qd = find_qstr(q, &attr); + *len = attr.len; + return (byte *)qd; } void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, size_t *n_total_bytes) { @@ -280,13 +277,14 @@ void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, si for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &CONST_POOL; pool = pool->prev) { *n_pool += 1; *n_qstr += pool->len; - for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) { - *n_str_data_bytes += Q_GET_ALLOC(*q); + for (const qstr_attr_t *q = pool->attrs, *q_top = pool->attrs + pool->len; q < q_top; q++) { + *n_str_data_bytes += sizeof(*q) + q->len + 1; } #if MICROPY_ENABLE_GC - *n_total_bytes += gc_nbytes(pool); // this counts actual bytes used in heap + // this counts actual bytes used in heap + *n_total_bytes += gc_nbytes(pool) - sizeof(qstr_attr_t) * pool->alloc; #else - *n_total_bytes += sizeof(qstr_pool_t) + sizeof(qstr) * pool->alloc; + *n_total_bytes += sizeof(qstr_pool_t) + sizeof(const char *) * pool->alloc; #endif } *n_total_bytes += *n_str_data_bytes; @@ -297,8 +295,8 @@ void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, si void qstr_dump_data(void) { QSTR_ENTER(); for (qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &CONST_POOL; pool = pool->prev) { - for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) { - mp_printf(&mp_plat_print, "Q(%s)\n", Q_GET_DATA(*q)); + for (const char **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) { + mp_printf(&mp_plat_print, "Q(%s)\n", *q); } } QSTR_EXIT(); diff --git a/py/qstr.h b/py/qstr.h index c86e74324c..288bf5dbac 100644 --- a/py/qstr.h +++ b/py/qstr.h @@ -47,12 +47,30 @@ enum { typedef size_t qstr; +typedef struct _qstr_attr_t { + #if MICROPY_QSTR_BYTES_IN_HASH == 1 + uint8_t hash; + #elif MICROPY_QSTR_BYTES_IN_HASH == 2 + uint16_t hash; + #else + #error unimplemented qstr hash decoding + #endif + #if MICROPY_QSTR_BYTES_IN_LEN == 1 + uint8_t len; + #elif MICROPY_QSTR_BYTES_IN_LEN == 2 + uint16_t len; + #else + #error unimplemented qstr length decoding + #endif +} qstr_attr_t; + typedef struct _qstr_pool_t { struct _qstr_pool_t *prev; size_t total_prev_len; size_t alloc; size_t len; - const byte *qstrs[]; + qstr_attr_t *attrs; + const char *qstrs[]; } qstr_pool_t; #define QSTR_FROM_STR_STATIC(s) (qstr_from_strn((s), strlen(s))) diff --git a/py/repl.c b/py/repl.c index ccc8dd5c6b..6cc10bb007 100644 --- a/py/repl.c +++ b/py/repl.c @@ -281,6 +281,12 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print ++str; } + // after "import", suggest built-in modules + static const char import_str[] = "import "; + if (len >= 7 && !memcmp(org_str, import_str, 7)) { + obj = MP_OBJ_NULL; + } + // look for matches size_t match_len; qstr q_first, q_last; @@ -291,19 +297,12 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print if (q_first == 0) { // If there're no better alternatives, and if it's first word // in the line, try to complete "import". - static const char import_str[] = "import "; if (s_start == org_str && s_len > 0) { if (memcmp(s_start, import_str, s_len) == 0) { *compl_str = import_str + s_len; return sizeof(import_str) - 1 - s_len; } } - // after "import", suggest built-in modules - if (len >= 7 && !memcmp(org_str, import_str, 7)) { - obj = NULL; - match_str = find_completions( - s_start, s_len, obj, &match_len, &q_first, &q_last); - } if (q_first == 0) { *compl_str = " "; return s_len ? 0 : 4; diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index 0aa832cf21..b69b71d0c9 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -219,6 +219,23 @@ const mp_obj_property_t bleio_characteristic_value_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| max_length: int +//| """The max length of this characteristic.""" +//| +STATIC mp_obj_t bleio_characteristic_get_max_length(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_max_length(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_max_length_obj, bleio_characteristic_get_max_length); + +const mp_obj_property_t bleio_characteristic_max_length_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_max_length_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + //| descriptors: Descriptor //| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)""" //| diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h index a8486866f9..878d998a2d 100644 --- a/shared-bindings/_bleio/Characteristic.h +++ b/shared-bindings/_bleio/Characteristic.h @@ -40,6 +40,7 @@ extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_pro extern mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self); extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self); extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self); +extern size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self); extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len); extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor); extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo); diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c index 9412dee5d7..b54a48230b 100644 --- a/shared-bindings/_bleio/PacketBuffer.c +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -44,7 +44,7 @@ //| When we're the server, we ignore all connections besides the first to subscribe to //| notifications.""" //| -//| def __init__(self, characteristic: Characteristic, *, buffer_size: int) -> None: +//| def __init__(self, characteristic: Characteristic, *, buffer_size: int, max_packet_size: Optional[int] = None) -> None: //| """Monitor the given Characteristic. Each time a new value is written to the Characteristic //| add the newly-written bytes to a FIFO buffer. //| @@ -55,14 +55,17 @@ //| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic //| in a remote Service that a Central has connected to. //| :param int buffer_size: Size of ring buffer (in packets of the Characteristic's maximum -//| length) that stores incoming packets coming from the peer.""" +//| length) that stores incoming packets coming from the peer. +//| :param int max_packet_size: Maximum size of packets. Overrides value from the characteristic. +//| (Remote characteristics may not have the correct length.)""" //| ... //| STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_characteristic, ARG_buffer_size }; + enum { ARG_characteristic, ARG_buffer_size, ARG_max_packet_size }; static const mp_arg_t allowed_args[] = { { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_max_packet_size, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none}}, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -79,10 +82,15 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n mp_raise_TypeError(translate("Expected a Characteristic")); } + size_t max_packet_size = common_hal_bleio_characteristic_get_max_length(characteristic); + if (args[ARG_max_packet_size].u_obj != mp_const_none) { + max_packet_size = mp_obj_get_int(args[ARG_max_packet_size].u_obj); + } + bleio_packet_buffer_obj_t *self = m_new_obj(bleio_packet_buffer_obj_t); self->base.type = &bleio_packet_buffer_type; - common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size); + common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size, max_packet_size); return MP_OBJ_FROM_PTR(self); } @@ -133,7 +141,7 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_ enum { ARG_data, ARG_header }; static const mp_arg_t allowed_args[] = { { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + { MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none}}, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -147,7 +155,7 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_ mp_buffer_info_t header_bufinfo; header_bufinfo.len = 0; - if (args[ARG_header].u_obj != MP_OBJ_NULL) { + if (args[ARG_header].u_obj != mp_const_none) { mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ); } diff --git a/shared-bindings/_bleio/PacketBuffer.h b/shared-bindings/_bleio/PacketBuffer.h index 65ce3ded1f..b300cb0215 100644 --- a/shared-bindings/_bleio/PacketBuffer.h +++ b/shared-bindings/_bleio/PacketBuffer.h @@ -33,7 +33,7 @@ extern const mp_obj_type_t bleio_packet_buffer_type; extern void common_hal_bleio_packet_buffer_construct( bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, - size_t buffer_size); + size_t buffer_size, size_t max_packet_size); mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t *header, size_t header_len); mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len); mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self); diff --git a/shared-bindings/_typing/__init__.pyi b/shared-bindings/_typing/__init__.pyi index 9a6e963ea5..d1bf853f71 100644 --- a/shared-bindings/_typing/__init__.pyi +++ b/shared-bindings/_typing/__init__.pyi @@ -38,7 +38,7 @@ WriteableBuffer = Union[ """ AudioSample = Union[ - audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer, audiomp3.MP3Decoder + audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer, audiomp3.MP3Decoder, synthio.MidiTrack ] """Classes that implement the audiosample protocol @@ -46,6 +46,7 @@ AudioSample = Union[ - `audiocore.RawSample` - `audiomixer.Mixer` - `audiomp3.MP3Decoder` + - `synthio.MidiTrack` You can play these back with `audioio.AudioOut`, `audiobusio.I2SOut` or `audiopwmio.PWMAudioOut`. """ diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index 23a2d3f0be..13339222c1 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -30,7 +30,6 @@ #include "py/binary.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "shared-bindings/audiocore/RawSample.h" #include "supervisor/shared/translate.h" @@ -83,26 +82,23 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a audioio_rawsample_obj_t *self = m_new_obj(audioio_rawsample_obj_t); self->base.type = &audioio_rawsample_type; mp_buffer_info_t bufinfo; - if (mp_get_buffer(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ)) { - uint8_t bytes_per_sample = 1; - bool signed_samples = bufinfo.typecode == 'b' || bufinfo.typecode == 'h'; - if (bufinfo.typecode == 'h' || bufinfo.typecode == 'H') { - bytes_per_sample = 2; - } else if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { - mp_raise_ValueError(translate("sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or 'B'")); - } - common_hal_audioio_rawsample_construct(self, ((uint8_t *)bufinfo.buf), bufinfo.len, - bytes_per_sample, signed_samples, args[ARG_channel_count].u_int, - args[ARG_sample_rate].u_int); - } else { - mp_raise_TypeError(translate("buffer must be a bytes-like object")); + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + uint8_t bytes_per_sample = 1; + bool signed_samples = bufinfo.typecode == 'b' || bufinfo.typecode == 'h'; + if (bufinfo.typecode == 'h' || bufinfo.typecode == 'H') { + bytes_per_sample = 2; + } else if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("sample_source buffer must be a bytearray or array of type 'h', 'H', 'b' or 'B'")); } + common_hal_audioio_rawsample_construct(self, ((uint8_t *)bufinfo.buf), bufinfo.len, + bytes_per_sample, signed_samples, args[ARG_channel_count].u_int, + args[ARG_sample_rate].u_int); return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: -//| """Deinitialises the AudioOut and releases any hardware resources for reuse.""" +//| """Deinitialises the RawSample and releases any hardware resources for reuse.""" //| ... //| STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { diff --git a/shared-bindings/audiocore/RawSample.h b/shared-bindings/audiocore/RawSample.h index b07add2dd1..71056f30c3 100644 --- a/shared-bindings/audiocore/RawSample.h +++ b/shared-bindings/audiocore/RawSample.h @@ -27,7 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H -#include "common-hal/microcontroller/Pin.h" #include "shared-module/audiocore/RawSample.h" extern const mp_obj_type_t audioio_rawsample_type; diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 73943f980f..5cf6deb2ed 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -44,7 +44,7 @@ //| """Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| //| :param typing.BinaryIO file: Already opened wave file -//| :param ~_typing.WriteableBuffer buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated internally. +//| :param ~_typing.WriteableBuffer buffer: Optional pre-allocated buffer, that will be split in half and used for double-buffering of the data. If not provided, two 256 byte buffers are allocated internally. //| //| //| Playing a wave file from flash:: diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst index a2fb7987d2..2d2172122a 100644 --- a/shared-bindings/support_matrix.rst +++ b/shared-bindings/support_matrix.rst @@ -6,6 +6,11 @@ Module Support Matrix - Which Modules Are Available on Which Boards The following table lists the available built-in modules for each CircuitPython capable board. +.. raw:: html + +

(all)

+ +.. rst-class:: support-matrix-table .. list-table:: :header-rows: 1 :widths: 7, 50 diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c new file mode 100644 index 0000000000..65fc7a4ee1 --- /dev/null +++ b/shared-bindings/synthio/MidiTrack.c @@ -0,0 +1,169 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-bindings/synthio/MidiTrack.h" +#include "supervisor/shared/translate.h" + +//| class MidiTrack: +//| """Simple square-wave MIDI synth""" +//| +//| def __init__(self, buffer: ReadableBuffer, tempo: int, *, sample_rate: int = 11025) -> None: +//| """Create a MidiTrack from the given stream of MIDI events. Only "Note On" and "Note Off" events +//| are supported; channel numbers and key velocities are ignored. Up to two notes may be on at the +//| same time. +//| +//| :param ~_typing.ReadableBuffer buffer: Stream of MIDI events, as stored in a MIDI file track chunk +//| :param int tempo: Tempo of the streamed events, in MIDI ticks per second +//| :param int sample_rate: The desired playback sample rate; higher sample rate requires more memory +//| +//| Simple melody:: +//| +//| import audioio +//| import board +//| import synthio +//| +//| dac = audioio.AudioOut(board.SPEAKER) +//| melody = synthio.MidiTrack(b"\\0\\x90H\\0*\\x80H\\0\\6\\x90J\\0*\\x80J\\0\\6\\x90L\\0*\\x80L\\0\\6\\x90J\\0" + +//| b"*\\x80J\\0\\6\\x90H\\0*\\x80H\\0\\6\\x90J\\0*\\x80J\\0\\6\\x90L\\0T\\x80L\\0" + +//| b"\\x0c\\x90H\\0T\\x80H\\0\\x0c\\x90H\\0T\\x80H\\0", tempo=640) +//| dac.play(melody) +//| print("playing") +//| while dac.playing: +//| pass +//| print("stopped")""" +//| ... +//| +STATIC mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_tempo, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_tempo, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 11025} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + synthio_miditrack_obj_t *self = m_new_obj(synthio_miditrack_obj_t); + self->base.type = &synthio_miditrack_type; + + common_hal_synthio_miditrack_construct(self, + (uint8_t *)bufinfo.buf, bufinfo.len, + args[ARG_tempo].u_int, + args[ARG_sample_rate].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the MidiTrack and releases any hardware resources for reuse.""" +//| ... +//| +STATIC mp_obj_t synthio_miditrack_deinit(mp_obj_t self_in) { + synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_synthio_miditrack_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_deinit_obj, synthio_miditrack_deinit); + +STATIC void check_for_deinit(synthio_miditrack_obj_t *self) { + if (common_hal_synthio_miditrack_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __enter__(self) -> MidiTrack: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +STATIC mp_obj_t synthio_miditrack_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_synthio_miditrack_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(synthio_miditrack___exit___obj, 4, 4, synthio_miditrack_obj___exit__); + +//| sample_rate: Optional[int] +//| """32 bit value that tells how quickly samples are played in Hertz (cycles per second).""" +//| +STATIC mp_obj_t synthio_miditrack_obj_get_sample_rate(mp_obj_t self_in) { + synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_synthio_miditrack_get_sample_rate(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_get_sample_rate_obj, synthio_miditrack_obj_get_sample_rate); + +const mp_obj_property_t synthio_miditrack_sample_rate_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&synthio_miditrack_get_sample_rate_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t synthio_miditrack_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&synthio_miditrack_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&synthio_miditrack___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&synthio_miditrack_sample_rate_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(synthio_miditrack_locals_dict, synthio_miditrack_locals_dict_table); + +STATIC const audiosample_p_t synthio_miditrack_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .sample_rate = (audiosample_sample_rate_fun)common_hal_synthio_miditrack_get_sample_rate, + .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_synthio_miditrack_get_bits_per_sample, + .channel_count = (audiosample_channel_count_fun)common_hal_synthio_miditrack_get_channel_count, + .reset_buffer = (audiosample_reset_buffer_fun)synthio_miditrack_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)synthio_miditrack_get_buffer, + .get_buffer_structure = (audiosample_get_buffer_structure_fun)synthio_miditrack_get_buffer_structure, +}; + +const mp_obj_type_t synthio_miditrack_type = { + { &mp_type_type }, + .name = MP_QSTR_MidiTrack, + .make_new = synthio_miditrack_make_new, + .locals_dict = (mp_obj_dict_t *)&synthio_miditrack_locals_dict, + .protocol = &synthio_miditrack_proto, +}; diff --git a/shared-bindings/synthio/MidiTrack.h b/shared-bindings/synthio/MidiTrack.h new file mode 100644 index 0000000000..d44d4c3bb7 --- /dev/null +++ b/shared-bindings/synthio/MidiTrack.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO_MIDITRACK_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO_MIDITRACK_H + +#include "shared-module/synthio/MidiTrack.h" + +extern const mp_obj_type_t synthio_miditrack_type; + +void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, + const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate); + +void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self); +bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self); +uint32_t common_hal_synthio_miditrack_get_sample_rate(synthio_miditrack_obj_t *self); +uint8_t common_hal_synthio_miditrack_get_bits_per_sample(synthio_miditrack_obj_t *self); +uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO_MIDITRACK_H diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c new file mode 100644 index 0000000000..d5165001fc --- /dev/null +++ b/shared-bindings/synthio/__init__.c @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 + +#include "py/mperrno.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "extmod/vfs_fat.h" + +#include "shared-bindings/synthio/__init__.h" +#include "shared-bindings/synthio/MidiTrack.h" + +//| """Support for MIDI synthesis""" +//| +//| def from_file(file: typing.BinaryIO, *, sample_rate: int = 11025) -> MidiTrack: +//| """Create an AudioSample from an already opened MIDI file. +//| Currently, only single-track MIDI (type 0) is supported. +//| +//| :param typing.BinaryIO file: Already opened MIDI file +//| :param int sample_rate: The desired playback sample rate; higher sample rate requires more memory +//| +//| +//| Playing a MIDI file from flash:: +//| +//| import audioio +//| import board +//| import synthio +//| +//| data = open("single-track.midi", "rb") +//| midi = synthio.from_file(data) +//| a = audioio.AudioOut(board.A0) +//| +//| print("playing") +//| a.play(midi) +//| while a.playing: +//| pass +//| print("stopped")""" +//| ... +//| +STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_file, ARG_sample_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 11025} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + if (!MP_OBJ_IS_TYPE(args[ARG_file].u_obj, &mp_type_fileio)) { + mp_raise_TypeError(translate("file must be a file opened in byte mode")); + } + pyb_file_obj_t *file = MP_OBJ_TO_PTR(args[ARG_file].u_obj); + + uint8_t chunk_header[14]; + f_rewind(&file->fp); + UINT bytes_read; + if (f_read(&file->fp, chunk_header, sizeof(chunk_header), &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != sizeof(chunk_header) || + memcmp(chunk_header, "MThd\0\0\0\6\0\0\0\1", 12)) { + mp_raise_ValueError(translate("Invalid MIDI file")); + // TODO: for a multi-track MIDI (type 1), return an AudioMixer + } + + uint16_t tempo; + if (chunk_header[12] & 0x80) { + tempo = -(int8_t)chunk_header[12] * chunk_header[13]; + } else { + tempo = 2 * ((chunk_header[12] << 8) | chunk_header[13]); + } + + if (f_read(&file->fp, chunk_header, 8, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 8 || memcmp(chunk_header, "MTrk", 4)) { + mp_raise_ValueError(translate("Invalid MIDI file")); + } + uint32_t track_size = (chunk_header[4] << 24) | + (chunk_header[5] << 16) | (chunk_header[6] << 8) | chunk_header[7]; + uint8_t *buffer = m_malloc(track_size, false); + if (f_read(&file->fp, buffer, track_size, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != track_size) { + mp_raise_ValueError(translate("Invalid MIDI file")); + } + + synthio_miditrack_obj_t *result = m_new_obj(synthio_miditrack_obj_t); + result->base.type = &synthio_miditrack_type; + + common_hal_synthio_miditrack_construct(result, buffer, track_size, + tempo, args[ARG_sample_rate].u_int); + + m_free(buffer); + + return MP_OBJ_FROM_PTR(result); +} +MP_DEFINE_CONST_FUN_OBJ_KW(synthio_from_file_obj, 1, synthio_from_file); + + +STATIC const mp_rom_map_elem_t synthio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_synthio) }, + { MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) }, + { MP_ROM_QSTR(MP_QSTR_from_file), MP_ROM_PTR(&synthio_from_file_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(synthio_module_globals, synthio_module_globals_table); + +const mp_obj_module_t synthio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&synthio_module_globals, +}; diff --git a/shared-bindings/synthio/__init__.h b/shared-bindings/synthio/__init__.h new file mode 100644 index 0000000000..14af1a5805 --- /dev/null +++ b/shared-bindings/synthio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SYNTHIO___INIT___H diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index fdcd2dbfbf..20731933c4 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -103,11 +103,28 @@ void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t *self, __attribute__((always_inline)) static inline uint32_t add16signed(uint32_t a, uint32_t b) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __QADD16(a, b); + #else + uint32_t result = 0; + for (int8_t i = 0; i < 2; i++) { + int16_t ai = a >> (sizeof(int16_t) * 8 * i); + int16_t bi = b >> (sizeof(int16_t) * 8 * i); + int32_t intermediate = (int32_t)ai + bi; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t)intermediate) & 0xffff) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif } __attribute__((always_inline)) static inline uint32_t mult16signed(uint32_t val, int32_t mul) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) mul <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits @@ -118,18 +135,46 @@ static inline uint32_t mult16signed(uint32_t val, int32_t mul) { asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); asm volatile ("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack return val; + #else + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1 << 15) - 1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + intermediate &= 0x0000FFFF; + result |= (((uint32_t)intermediate)) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif } static inline uint32_t tounsigned8(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD8(val, 0x80808080); + #else + return val ^ 0x80808080; + #endif } static inline uint32_t tounsigned16(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD16(val, 0x80008000); + #else + return val ^ 0x80008000; + #endif } static inline uint32_t tosigned16(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) return __UADD16(val, 0x80008000); + #else + return val ^ 0x80008000; + #endif } static inline uint32_t unpack8(uint16_t val) { diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index 7a7ea845e7..258036c93b 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -153,9 +153,11 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size p += sz; } else { while (sz--) { - mp_binary_set_val(fmt_type, *fmt, args[i], &p); // Pad bytes don't have a corresponding argument. - if (*fmt != 'x') { + if (*fmt == 'x') { + mp_binary_set_val(fmt_type, *fmt, MP_OBJ_NEW_SMALL_INT(0), &p); + } else { + mp_binary_set_val(fmt_type, *fmt, args[i], &p); i++; } } diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c new file mode 100644 index 0000000000..0827945ab5 --- /dev/null +++ b/shared-module/synthio/MidiTrack.c @@ -0,0 +1,212 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 "py/runtime.h" +#include "shared-bindings/synthio/MidiTrack.h" + +#define LOUDNESS 0x4000 // 0.5 +#define BITS_PER_SAMPLE 16 +#define BYTES_PER_SAMPLE (BITS_PER_SAMPLE / 8) +#define SILENCE 0x80 + +STATIC uint8_t parse_note(const uint8_t *buffer, uint32_t len, uint32_t *pos) { + if (*pos + 1 >= len) { + mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), *pos); + } + uint8_t note = buffer[(*pos)++]; + if (note > 127 || buffer[(*pos)++] > 127) { + mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), *pos); + } + return note; +} + +STATIC void terminate_span(synthio_miditrack_obj_t *self, uint16_t *dur, uint16_t *max_dur) { + if (*dur) { + self->track[self->total_spans - 1].dur = *dur; + if (*dur > *max_dur) { + *max_dur = *dur; + } + *dur = 0; + } else { + self->total_spans--; + } +} + +STATIC void add_span(synthio_miditrack_obj_t *self, uint8_t note1, uint8_t note2) { + synthio_midi_span_t span = { 0, {note1, note2} }; + self->track = m_realloc(self->track, + (self->total_spans + 1) * sizeof(synthio_midi_span_t)); + self->track[self->total_spans++] = span; +} + +void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, + const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate) { + + synthio_midi_span_t initial = { 0, {SILENCE, SILENCE} }; + self->sample_rate = sample_rate; + self->track = m_malloc(sizeof(synthio_midi_span_t), false); + self->next_span = 0; + self->total_spans = 1; + *self->track = initial; + + uint16_t dur = 0, max_dur = 0; + uint32_t pos = 0; + while (pos < len) { + uint8_t c; + uint32_t delta = 0; + do { + c = buffer[pos++]; + delta <<= 7; + delta |= c & 0x7f; + } while ((c & 0x80) && (pos < len)); + + if (c & 0x80) { + mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), pos); + } + + dur += delta * sample_rate / tempo; + + switch (buffer[pos++] >> 4) { + case 8: { // Note Off + uint8_t note = parse_note(buffer, len, &pos); + + // Ignore if not a note which is playing + synthio_midi_span_t last_span = self->track[self->total_spans - 1]; + if (last_span.note[0] == note || last_span.note[1] == note) { + terminate_span(self, &dur, &max_dur); + if (last_span.note[0] == note) { + add_span(self, last_span.note[1], SILENCE); + } else { + add_span(self, last_span.note[0], SILENCE); + } + } + break; + } + case 9: { // Note On + uint8_t note = parse_note(buffer, len, &pos); + + // Ignore if two notes are already playing + synthio_midi_span_t last_span = self->track[self->total_spans - 1]; + if (last_span.note[1] == SILENCE) { + terminate_span(self, &dur, &max_dur); + if (last_span.note[0] == SILENCE) { + add_span(self, note, SILENCE); + } else { + add_span(self, last_span.note[0], note); + } + } + break; + } + case 10: + case 11: + case 14: // two data bytes to ignore + parse_note(buffer, len, &pos); + break; + case 12: + case 13: // one data byte to ignore + if (pos >= len || buffer[pos++] > 127) { + mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), pos); + } + break; + case 15: // the full syntax is too complicated, just assume it's "End of Track" event + pos = len; + break; + default: // invalid event + mp_raise_ValueError_varg(translate("Error in MIDI stream at position %d"), pos); + } + } + terminate_span(self, &dur, &max_dur); + + self->buffer_length = max_dur * BYTES_PER_SAMPLE; + self->buffer = m_malloc(self->buffer_length, false); +} + +void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self) { + m_free(self->buffer); + self->buffer = NULL; + m_free(self->track); + self->track = NULL; +} +bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self) { + return self->buffer == NULL; +} + +uint32_t common_hal_synthio_miditrack_get_sample_rate(synthio_miditrack_obj_t *self) { + return self->sample_rate; +} +uint8_t common_hal_synthio_miditrack_get_bits_per_sample(synthio_miditrack_obj_t *self) { + return BITS_PER_SAMPLE; +} +uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t *self) { + return 1; +} + +void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, + bool single_channel, uint8_t channel) { + + self->next_span = 0; +} + +STATIC const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840, + 12544, 13290, 14080, 14917, 15804}; // 9th octave + +audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t *self, + bool single_channel, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { + + if (self->next_span >= self->total_spans) { + *buffer_length = 0; + return GET_BUFFER_DONE; + } + + synthio_midi_span_t span = self->track[self->next_span++]; + *buffer_length = span.dur * BYTES_PER_SAMPLE; + uint8_t octave1 = span.note[0] / 12; // 0..10 + uint8_t octave2 = span.note[1] / 12; // 0..10 + int32_t base_freq1 = notes[span.note[0] % 12]; + int32_t base_freq2 = notes[span.note[1] % 12]; + int32_t sample_rate = self->sample_rate; + + for (uint16_t i = 0; i < span.dur; i++) { + int16_t semiperiod1 = span.note[0] == SILENCE ? 0 : + ((base_freq1 * i * 2) / sample_rate) >> (10 - octave1); + int16_t semiperiod2 = span.note[1] == SILENCE ? semiperiod1 : + ((base_freq2 * i * 2) / sample_rate) >> (10 - octave2); + self->buffer[i] = ((semiperiod1 % 2 + semiperiod2 % 2) - 1) * LOUDNESS; + } + *buffer = (uint8_t *)self->buffer; + + return self->next_span >= self->total_spans ? + GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; +} + +void synthio_miditrack_get_buffer_structure(synthio_miditrack_obj_t *self, bool single_channel, + bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { + + *single_buffer = true; + *samples_signed = true; + *max_buffer_length = self->buffer_length; + *spacing = 1; +} diff --git a/shared-module/synthio/MidiTrack.h b/shared-module/synthio/MidiTrack.h new file mode 100644 index 0000000000..bd058daaee --- /dev/null +++ b/shared-module/synthio/MidiTrack.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO_MIDITRACK_H +#define MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO_MIDITRACK_H + +#include "py/obj.h" + +#include "shared-module/synthio/__init__.h" + +typedef struct { + uint16_t dur; + uint8_t note[2]; +} synthio_midi_span_t; + +typedef struct { + mp_obj_base_t base; + uint32_t sample_rate; + uint16_t *buffer; + uint16_t buffer_length; + synthio_midi_span_t *track; + uint16_t next_span; + uint16_t total_spans; +} synthio_miditrack_obj_t; + + +// These are not available from Python because it may be called in an interrupt. +void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, + bool single_channel, + uint8_t channel); + +audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t *self, + bool single_channel, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes + +void synthio_miditrack_get_buffer_structure(synthio_miditrack_obj_t *self, bool single_channel, + bool *single_buffer, bool *samples_signed, + uint32_t *max_buffer_length, uint8_t *spacing); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO_MIDITRACK_H diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/synthio/__init__.h b/shared-module/synthio/__init__.h new file mode 100644 index 0000000000..d9d98a5341 --- /dev/null +++ b/shared-module/synthio/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Artyom Skrobov + * + * 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 MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H + +#include "shared-module/audiocore/__init__.h" + +#endif // MICROPY_INCLUDED_SHARED_MODULE_SYNTHIO__INIT__H diff --git a/supervisor/shared/cpu.c b/supervisor/shared/cpu.c new file mode 100644 index 0000000000..510225d197 --- /dev/null +++ b/supervisor/shared/cpu.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft 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 + +#include "supervisor/shared/cpu.h" + +bool cpu_interrupt_active(void) { + #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) + // Check VECTACTIVE in ICSR. We don't need to disable interrupts because if + // one occurs after we read, we won't continue until it is resolved. + return (*((volatile uint32_t *)0xE000ED04) & 0x1ff) != 0; + #else + // We don't know. + return false; + #endif +} diff --git a/supervisor/shared/cpu.h b/supervisor/shared/cpu.h new file mode 100644 index 0000000000..9e2bed1e55 --- /dev/null +++ b/supervisor/shared/cpu.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft 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 MICROPY_INCLUDED_SUPERVISOR_SHARED_CPU_H +#define MICROPY_INCLUDED_SUPERVISOR_SHARED_CPU_H + +#include +#include + +// True when we're in an interrupt handler. +bool cpu_interrupt_active(void); + +#endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_CPU_H diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index f9e787c159..cd73e1b9f9 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -170,13 +170,13 @@ void print_safe_mode_message(safe_mode_t reason) { 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.")); + serial_write_compressed(translate("NLR jump failed. Likely memory corruption.")); return; case MICROPY_FATAL_ERROR: - serial_write_compressed(translate("MicroPython fatal error.")); + serial_write_compressed(translate("Fatal error.")); break; case GC_ALLOC_OUTSIDE_VM: - serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.")); + serial_write_compressed(translate("Attempted heap allocation when VM not running.")); break; #ifdef SOFTDEVICE_PRESENT // defined in ports/nrf/bluetooth/bluetooth_common.mk diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index c73d702c9c..beb2541a15 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -28,6 +28,7 @@ #include "py/mpconfig.h" +#include "supervisor/shared/cpu.h" #include "supervisor/shared/display.h" #include "shared-bindings/terminalio/Terminal.h" #include "supervisor/serial.h" @@ -77,9 +78,9 @@ void serial_early_init(void) { void serial_init(void) { usb_init(); -#ifdef NRF_DEBUG_PRINT + #ifdef NRF_DEBUG_PRINT _debug_uart_init(); -#endif + #endif } bool serial_connected(void) { @@ -149,13 +150,17 @@ void serial_write_substring(const char *text, uint32_t length) { uint32_t count = 0; while (count < length && tud_cdc_connected()) { count += tud_cdc_write(text + count, length - count); + // If we're in an interrupt, then don't wait for more room. Queue up what we can. + if (cpu_interrupt_active()) { + break; + } usb_background(); } #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) int uart_errcode; - common_hal_busio_uart_write(&debug_uart, (const uint8_t *) text, length, &uart_errcode); + common_hal_busio_uart_write(&debug_uart, (const uint8_t *)text, length, &uart_errcode); #endif #ifdef NRF_DEBUG_PRINT diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index c99cbf180d..7afbd43e21 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -129,7 +129,7 @@ __attribute__((always_inline)) #endif const compressed_string_t *translate(const char *original) { #ifndef NO_QSTR - #define QDEF(id, str) + #define QDEF(id, hash, len, str) #define TRANSLATION(id, firstbyte, ...) if (strcmp(original, id) == 0) { static const compressed_string_t v = { .data = firstbyte, .tail = { __VA_ARGS__ } }; return &v; } else #include "genhdr/qstrdefs.generated.h" #undef TRANSLATION diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 1744c4f47f..c206ff96be 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -4,6 +4,7 @@ SRC_SUPERVISOR = \ supervisor/shared/autoreload.c \ supervisor/shared/background_callback.c \ supervisor/shared/board.c \ + supervisor/shared/cpu.c \ supervisor/shared/filesystem.c \ supervisor/shared/flash.c \ supervisor/shared/micropython.c \ diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index 107006cc3f..ec29ea9080 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -121,3 +121,5 @@ except: # check padding bytes print(struct.pack("xb", 3)) +# Make sure pack doesn't reuse a larger value and error +print(struct.pack("xH", 0x100)) diff --git a/tests/circuitpython-manual/audiocore/single-track.midi b/tests/circuitpython-manual/audiocore/single-track.midi new file mode 100755 index 0000000000000000000000000000000000000000..3b3dcea8221ff6e7592c835a25e6ea2789e04324 GIT binary patch literal 5123 zcmZ{oeM=)*7RGBs2q8$2UTH)mh=_zBStn$Ioy6i=9m=inm7xmCuwL*W)_Xqm?Vp?j?>7TXW`@!`JD47&S^C}TeQ+M zGs;e{8aO7|+0{qR>1Jl8Ej&kAf6_?%D9qvu=d_gd@aV~7u?p1&a)7}x2IpBs=!noE zAwzd=a~@>l#br7+N7--^r9;!nqR9jDE$kxfIFour>ci=u4QJ3>oDj&6S{{giAqHl0 zK%g4{8aO0bxY$8{PfY?$H>jaW4KdBwqoxnp*>88MX)80Nq!eFjnm(zffcE8~CMS51 z`>+pWpHOWK283z>Jwoo=8cjmZU20lVQ;nSSnrND{yUOjRyPWT`cUM6+{Pg@lU7P7U z^EK<(^R#1*vlDxqo{&-3w$d&EdbUo@v+UIRn!EN8`JD6bB=$24txv3L50Kw*wj^rN z`^3Apfjr@ymT`C_P(+{(ff@u#2-L(NCQyEh0G?9mn&TS;_iK^rILtVwRYH9N`uPzH z3v?Iga1GkW?vY!M+)fFpk?Pt#5SUGy{$J>~KrgZA;t}HEW8$%m-~*vf2xSP>q>31W zRl6F5Qn_vH2J4Pn2=2(*U&N}s&^{4~8~?=ycs^=lQvHh6FIA7WVpriDXZYO{yW*=Q0-Hfw(@&~dlZ0@ru`YHMe z*E`{Qr%s<9p{%0l0Coq^Zgx)Z>EyH`vBtA4O*^6ORx(gC+V>o=pq85s{Zft-WNq z%Ium9uF2raeoL=R1-k?6Zm@$w?H4c#RJ?(_jeLL|Eg7PW8HX!#k3q$?B(hp@Z?gey z7`Pq=*$9AKkr>}UIv95showk0at#7g! zp=WMjf^1HQ=I9fUuX%je6u+Pua|UZ+>gW>A0lu<@NXA_h-}qf2#V#p^dDtfbk=`acrFfJBZsJ=* z7n7P#aUtSf07jiCT5BopbDlXvrAdl=q_~CQCJG_aH4pOuf(k66)JG9F+2bZxoFuLZ zxk=AS+YrG3!f3zT_==NsIUSp78VeZD;Gl0%PX(Y6oYZop1^H^zmQWmnWI+nxqysqV z#u>0!Dj4jd&}RQeDnjs|1U?nfqd2JsK-1Yp%u2+Kh5&^CDU}|VHRe`(Zb(D-K86Gw z5-{RZBw{&<vq8hFu-K=x~)m3;D>spE30&WScO8%J`c8j7`Fb)sf#J-^DIM z*Krw(sK&e^Dn_<}zJO1Jy~r_*Q9Qrp*GGPAlgR^_Y=Q6@>o;UlBa@{=8r!dUZ=h?U zi;=-dVrp@Mn0f5_Q4%o&(npqVxaN#`c*^^=A5HoZb52Ei6+)QYyNPE^h;M|bU~qu0 zip|IYyf$P9{XHrC%nKS(&<1vgIr#=K@f|j0NO%i73uXb^pZpeMZ=&1f9AhW47MuUM zfpHOK0cG-1&e({N%NSV_Dx-TtQo23e#Oj9n$orgKPu`G;)@hK>NP#vy0#a2^_BqJF z&x4wF4vk-$&-7$NJ$Z{#ZSUtPc((Q7D}>oW*TQC>aK7s?0Eto0ipXrvJ1u%rbeZ^t zq@MU4tR7q$^-i^0d^RY%CjbBK39k*s77oUN&zQa$j-H3B1lz%>LNKwWUj<6S^YLTO zN@dC~tm(P=g^N}~VcZR(u7iW06RvpvNSnp;a6F29o^NuPQm{ww7xd zJ!@1{yZZ0|f`73yp3{uyGU(s-wF~INfsJU*O3uJu(7X5WSOTfP4&?LFMSxR@qD{Bj2L221 zl>`rY@N-w1c9-8to*mBNZk{LNf*3!ZQMYZm8Rxi91r)KSJy9IWBgXI&Y-5tVLn_FvQD zVL12z<4u&B`6B|Z_L7J$B8e(x)mSJr=G)69$A0R$ngj+m!UEX+|HMi zWc0a(KIU`$-%_0df$a9AYM1b}^e(=S%pU&>=Rn$ z^=-#rWB%at`>~em^>>%{s#d)cR;7x!!WVySBkSh=O@0Sp#MnOTkna8aZ^3^606o9) literal 0 HcmV?d00001 diff --git a/tools/build_board_info.py b/tools/build_board_info.py index 94f6e50af1..66ca48a02d 100644 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -266,7 +266,7 @@ def generate_download_info(): # Delete the release we are replacing for board in current_info: info = current_info[board] - for version in info["versions"]: + for version in list(info["versions"]): previous_releases.add(version["version"]) previous_languages.update(version["languages"]) if version["stable"] == new_stable or ( diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index c989b63007..42d62fdf11 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -607,6 +607,20 @@ def freeze_mpy(base_qstrs, raw_codes): print(" MP_QSTR_%s," % new[i][1]) print("};") + print() + print("const qstr_attr_t mp_qstr_frozen_const_attr[] = {") + qstr_size = {"metadata": 0, "data": 0} + for _, _, qstr in new: + qbytes = qstrutil.bytes_cons(qstr, "utf8") + print(" {%d, %d}," % ( + qstrutil.compute_hash(qbytes, config.MICROPY_QSTR_BYTES_IN_HASH), + len(qbytes) + )) + qstr_size["metadata"] += ( + config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH + ) + qstr_size["data"] += len(qbytes) + print("};") print() print("extern const qstr_pool_t mp_qstr_const_pool;") print("const qstr_pool_t mp_qstr_frozen_const_pool = {") @@ -614,19 +628,10 @@ def freeze_mpy(base_qstrs, raw_codes): print(" MP_QSTRnumber_of, // previous pool size") print(" %u, // allocated entries" % len(new)) print(" %u, // used entries" % len(new)) + print(" (qstr_attr_t *)mp_qstr_frozen_const_attr,") print(" {") - qstr_size = {"metadata": 0, "data": 0} for _, _, qstr in new: - qstr_size["metadata"] += ( - config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH - ) - qstr_size["data"] += len(qstr) - print( - " %s," - % qstrutil.make_bytes( - config.MICROPY_QSTR_BYTES_IN_LEN, config.MICROPY_QSTR_BYTES_IN_HASH, qstr - ) - ) + print(" \"%s\"," % qstrutil.escape_bytes(qstr)) print(" },") print("};") From 7daba64cb11fba0ab978cd84f4d58034906ccd93 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 25 Apr 2021 20:12:20 +0900 Subject: [PATCH 54/69] merge. --- lib/protomatter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/protomatter b/lib/protomatter index 98017c5734..c2c81ded11 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit 98017c57349e259fab70c6a7830436b19a55f6f4 +Subproject commit c2c81ded118484f8925bf81e270b416739cd72d9 From 872fff7fbbb8ca1297f7c5ec7760fa6536e9c233 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 25 Apr 2021 23:59:21 +0900 Subject: [PATCH 55/69] simplify system_on_idle_until_alarm() --- ports/nrf/common-hal/alarm/__init__.c | 121 ++++++++------------------ 1 file changed, 37 insertions(+), 84 deletions(-) diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 4c00cc4216..fb2938aebb 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -118,18 +118,6 @@ bool common_hal_alarm_woken_from_sleep(void) { || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); } -nrf_sleep_source_t alarm_woken_from_sleep_2(void) { - nrf_sleep_source_t cause = _get_wakeup_cause(); - if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { - return cause; - } - else { - return NRF_SLEEP_WAKEUP_UNDEFINED; - } -} - STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); switch (cause) { @@ -163,7 +151,7 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t // TODO: this handles all possible types of wakeup, which is redundant with main. // revise to extract all parts essential to enabling sleep wakeup, but leave the // alarm/non-alarm sorting to the existing main loop. -nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { +void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { bool have_timeout = false; uint64_t start_tick = 0, end_tick = 0; int64_t tickdiff; @@ -197,7 +185,6 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres #endif int64_t remaining; - nrf_sleep_source_t wakeup_cause = NRF_SLEEP_WAKEUP_UNDEFINED; sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; @@ -210,30 +197,29 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres #endif while(1) { - if (mp_hal_is_interrupted()) { - WAKEUP_REASON('I'); - break; - } - if (serial_connected() && serial_bytes_available()) { - WAKEUP_REASON('S'); - break; - } - RUN_BACKGROUND_TASKS; - wakeup_cause = alarm_woken_from_sleep_2(); - if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { - WAKEUP_REASON('0'+wakeup_cause); - break; - } - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - // We break a bit early so we don't risk setting the alarm before the time when we call - // sleep. - if (remaining < 1) { - WAKEUP_REASON('t'); + if (mp_hal_is_interrupted()) { + WAKEUP_REASON('I'); break; } - port_interrupt_after_ticks(remaining); - } + if (serial_connected() && serial_bytes_available()) { + WAKEUP_REASON('S'); + break; + } + RUN_BACKGROUND_TASKS; + if (common_hal_alarm_woken_from_sleep()) { + WAKEUP_REASON('W'); + break; + } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + // We break a bit early so we don't risk setting the alarm before the time when we call + // sleep. + if (remaining < 1) { + WAKEUP_REASON('t'); + break; + } + port_interrupt_after_ticks(remaining); + } // Idle until an interrupt happens. port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT @@ -242,16 +228,15 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres --ct; } #endif - if (have_timeout) { - remaining = end_tick - port_get_raw_ticks(NULL); - if (remaining <= 0) { - wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; - sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; - WAKEUP_REASON('T'); - break; + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + if (remaining <= 0) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + WAKEUP_REASON('T'); + break; + } } } - } #ifdef NRF_DEBUG_PRINT dbg_printf("%c\r\n", reason); #endif @@ -271,12 +256,10 @@ nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t pres } dbg_printf("lapse %6.1f sec\r\n", sec); #endif - - return wakeup_cause; } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { - mp_obj_t r_obj = mp_const_none; + mp_obj_t wake_alarm; alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(false, n_alarms, alarms); @@ -285,25 +268,16 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj #endif int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); - nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); - (void)cause; - -#ifdef NRF_DEBUG_PRINT - //dbg_printf("wakeup! "); - print_wakeup_cause(cause); -#endif + system_on_idle_until_alarm(timediff_ms, 0); if (mp_hal_is_interrupted()) { -#ifdef NRF_DEBUG_PRINT - dbg_printf("mp_hal_is_interrupted\r\n"); -#endif - r_obj = mp_const_none; + wake_alarm = mp_const_none; } else { - r_obj = _get_wake_alarm(n_alarms, alarms); + wake_alarm = _get_wake_alarm(n_alarms, alarms); } alarm_reset(); - return r_obj; + return wake_alarm; } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { @@ -325,14 +299,9 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { #ifdef NRF_DEBUG_PRINT dbg_check_RTCprescaler(); //XXX #endif - nrf_sleep_source_t cause; - cause = system_on_idle_until_alarm(timediff_ms, - PRESCALER_VALUE_IN_DEEP_SLEEP); - (void)cause; + system_on_idle_until_alarm(timediff_ms, PRESCALER_VALUE_IN_DEEP_SLEEP); #ifdef NRF_DEBUG_PRINT - dbg_printf("wakeup! "); - print_wakeup_cause(cause); dbg_printf("RESET...\r\n\r\n"); #endif @@ -370,25 +339,9 @@ void common_hal_alarm_pretending_deep_sleep(void) { #endif int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); - nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); - (void)cause; + system_on_idle_until_alarm(timediff_ms, 0); -#ifdef NRF_DEBUG_PRINT - dbg_printf("wakeup! "); - print_wakeup_cause(cause); -#endif - - // alarm_reset(); - -#if 0 - // if one of Alarm event occurred, reset myself - if (cause == NRF_SLEEP_WAKEUP_GPIO || - cause == NRF_SLEEP_WAKEUP_TIMER || - cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { - reset_cpu(); - } - // else, just return and go into REPL -#endif + alarm_reset(); } void common_hal_alarm_gc_collect(void) { From 30f31639d3b4a8309d5b035c99608c04a294b3a3 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sun, 25 Apr 2021 11:58:22 -0500 Subject: [PATCH 56/69] Added statemachine deinit --- .../raspberrypi/common-hal/pulseio/PulseIn.c | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 278c0cd662..95e38d6522 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -62,10 +62,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, self->len = 0; save_self = self; - // Set everything up. - rp2pio_statemachine_obj_t state_machine; - - bool ok = rp2pio_statemachine_construct(&state_machine, + bool ok = rp2pio_statemachine_construct(&self->state_machine, pulsein_program, sizeof(pulsein_program) / sizeof(pulsein_program[0]), 1000000, NULL, 0, @@ -80,29 +77,26 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, false, true, 32, true, // RX auto-push every 32 bits false); // claim pins - pio_sm_set_enabled(state_machine.pio,state_machine.state_machine, false); - self->state_machine.pio = state_machine.pio; - self->state_machine.state_machine = state_machine.state_machine; - self->state_machine.sm_config = state_machine.sm_config; - self->state_machine.offset = state_machine.offset; + + pio_sm_set_enabled(self->state_machine.pio,self->state_machine.state_machine, false); pio_sm_clear_fifos(self->state_machine.pio,self->state_machine.state_machine); last_level = self->idle_state; level_count = 0; result = 0; buf_index = 0; - pio_sm_set_in_pins(state_machine.pio,state_machine.state_machine,pin->number); - common_hal_rp2pio_statemachine_set_interrupt_handler(&state_machine,&common_hal_pulseio_pulsein_interrupt,NULL,PIO_IRQ0_INTE_SM0_RXNEMPTY_BITS); + pio_sm_set_in_pins(self->state_machine.pio,self->state_machine.state_machine,pin->number); + common_hal_rp2pio_statemachine_set_interrupt_handler(&(self->state_machine),&common_hal_pulseio_pulsein_interrupt,NULL,PIO_IRQ0_INTE_SM0_RXNEMPTY_BITS); // exec a set pindirs to 0 for input - pio_sm_exec(state_machine.pio,state_machine.state_machine,0xe080); + pio_sm_exec(self->state_machine.pio,self->state_machine.state_machine,0xe080); // exec the appropriate wait for pin if (self->idle_state == true) { pio_sm_exec(self->state_machine.pio,self->state_machine.state_machine,0x2020); } else { pio_sm_exec(self->state_machine.pio,self->state_machine.state_machine,0x20a0); } - pio_sm_set_enabled(state_machine.pio, state_machine.state_machine, true); + pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, true); } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t *self) { @@ -114,8 +108,9 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { return; } pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, false); - pio_sm_unclaim(self->state_machine.pio, self->state_machine.state_machine); + common_hal_rp2pio_statemachine_deinit(&self->state_machine); m_free(self->buffer); + reset_pin_number(self->pin); self->pin = NO_PIN; } From 889da596ff706d95efb011f25a0e6227d1cb76da Mon Sep 17 00:00:00 2001 From: zapwizard Date: Sun, 25 Apr 2021 13:10:52 -0500 Subject: [PATCH 57/69] Update pins.c Both D0 and D1 were assigned to pin_GPIO7, fixed D0 to pin_GPIO6, which also matches the comment. --- ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c index 00d6c30cb8..5414dd3e2b 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c @@ -2,7 +2,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { // D (Digital only) pins (D0,D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO7) }, // GPIO6 - D0 + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO6) }, // GPIO6 - D0 { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // GPIO7 - D1 // A (ADC) pins (A0,A1) From 9700295ebe880da1daa04a3462e73165a330a49e Mon Sep 17 00:00:00 2001 From: Alvaro Figueroa Date: Sun, 25 Apr 2021 18:21:13 +0000 Subject: [PATCH 58/69] Translated using Weblate (Spanish) Currently translated at 100.0% (974 of 974 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/es/ --- locale/es.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/es.po b/locale/es.po index 0970910e8e..18c6f56821 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-23 20:32+0000\n" -"Last-Translator: Jose David M \n" +"PO-Revision-Date: 2021-04-25 18:43+0000\n" +"Last-Translator: Alvaro Figueroa \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -1293,7 +1293,7 @@ msgstr "Cuenta de canales inválida" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_count %d" -msgstr "" +msgstr "data_count inválido %d" #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." @@ -2188,11 +2188,11 @@ msgstr "" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for DRDY" -msgstr "" +msgstr "Tiempo de espera agotado esperado por DRDY" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for VSYNC" -msgstr "" +msgstr "Tiempo de espera agotado esperando por VSYNC" #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " @@ -2890,7 +2890,7 @@ msgstr "los datos deben ser de igual tamaño" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "data pin #%d in use" -msgstr "" +msgstr "pin de datos #%d en uso" #: extmod/ulab/code/ndarray.c msgid "data type not understood" From 38f6b9c96907083adaddd5003d9193f45c47595d Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Sat, 24 Apr 2021 19:54:31 +0000 Subject: [PATCH 59/69] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (974 of 974 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 1f5b691c79..3ca69c24e2 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-04-23 20:32+0000\n" +"PO-Revision-Date: 2021-04-25 18:43+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -1296,7 +1296,7 @@ msgstr "A contagem do canal é inválido" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_count %d" -msgstr "" +msgstr "data_count %d inválido" #: shared-bindings/digitalio/DigitalInOut.c msgid "Invalid direction." @@ -2194,11 +2194,11 @@ msgstr "" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for DRDY" -msgstr "" +msgstr "Esgotou-se o tempo limite de espera pelo DRDY" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c msgid "Timeout waiting for VSYNC" -msgstr "" +msgstr "Esgotou-se o tempo de espera pelo VSYNC" #: supervisor/shared/safe_mode.c msgid "To exit, please reset the board without " @@ -2898,7 +2898,7 @@ msgstr "os dados devem ser de igual comprimento" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "data pin #%d in use" -msgstr "" +msgstr "o pino de dados #%d está em uso" #: extmod/ulab/code/ndarray.c msgid "data type not understood" From d1861a6b9c9f1a4624e13f6253254709b0fcd8d4 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 25 Apr 2021 14:24:21 -0500 Subject: [PATCH 60/69] Reset buffer index in PulseIn clear --- ports/raspberrypi/common-hal/pulseio/PulseIn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 278c0cd662..878439a532 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -180,6 +180,7 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t *self) { self->start = 0; self->len = 0; + buf_index = 0; } uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { From 4bafbca0c3571af11163b491994a3a8a7c24ea03 Mon Sep 17 00:00:00 2001 From: ajs256 <67526318+ajs256@users.noreply.github.com> Date: Sun, 25 Apr 2021 12:58:52 -0700 Subject: [PATCH 61/69] Trinkeys: Clear neopixels on board reset --- ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c | 1 + ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c | 1 + ports/atmel-samd/boards/neopixel_trinkey_m0/board.c | 1 + 3 files changed, 3 insertions(+) diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c index cde441b3d9..5cf1b0a345 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/board.c @@ -37,4 +37,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { + board_reset_user_neopixels(&pin_PA15, 2); } diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c index cde441b3d9..0a82c4b402 100644 --- a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c @@ -37,4 +37,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { + board_reset_user_neopixels(&pin_PA06, 2) } diff --git a/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c b/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c index cde441b3d9..1568a2823c 100644 --- a/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/neopixel_trinkey_m0/board.c @@ -37,4 +37,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { + board_reset_user_neopixels(&pin_PA05, 4); } From de3c5ff976620902055ac502aee57f3bb5226a30 Mon Sep 17 00:00:00 2001 From: ajs256 <67526318+ajs256@users.noreply.github.com> Date: Sun, 25 Apr 2021 16:42:58 -0700 Subject: [PATCH 62/69] oh crud, i forgot a semicolon --- ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c index 0a82c4b402..095750731b 100644 --- a/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c +++ b/ports/atmel-samd/boards/adafruit_slide_trinkey_m0/board.c @@ -37,5 +37,5 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { - board_reset_user_neopixels(&pin_PA06, 2) + board_reset_user_neopixels(&pin_PA06, 2); } From 5bd1da21a29b4083cec50de08778aaa4b7c83456 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 25 Apr 2021 21:38:57 -0500 Subject: [PATCH 63/69] Increased possible pulsein length to 32 ms. --- ports/raspberrypi/common-hal/pulseio/PulseIn.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 278c0cd662..0495cb1b1b 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -39,6 +39,8 @@ pulseio_pulsein_obj_t *save_self; #define NO_PIN 0xff +#define MAX_PULSE 32678 +#define MIN_PULSE 10 volatile bool last_level; volatile uint16_t level_count = 0; volatile uint16_t result = 0; @@ -139,15 +141,15 @@ void common_hal_pulseio_pulsein_interrupt() { last_level = level; level_count = 1; // ignore pulses that are too long and too short - if (result < 4000 && result > 10) { + if (result < MAX_PULSE && result > MIN_PULSE) { self->buffer[buf_index] = result; buf_index++; self->len++; } } } -// check for a pulse thats too long (4000 us) or maxlen reached, and reset - if ((level_count > 4000) || (buf_index >= self->maxlen)) { +// check for a pulse thats too long (MAX_PULSE us) or maxlen reached, and reset + if ((level_count > MAX_PULSE) || (buf_index >= self->maxlen)) { pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, false); pio_sm_init(self->state_machine.pio, self->state_machine.state_machine, self->state_machine.offset, &self->state_machine.sm_config); pio_sm_restart(self->state_machine.pio,self->state_machine.state_machine); @@ -180,6 +182,7 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t *self) { self->start = 0; self->len = 0; + buf_index = 0; } uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { From 43840363c2ac1709ff0ed456f042a7b31c82db41 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Mon, 26 Apr 2021 17:59:21 -0400 Subject: [PATCH 64/69] Fix submodule --- lib/protomatter | 2 +- ports/nrf/common-hal/alarm/__init__.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/protomatter b/lib/protomatter index c2c81ded11..98017c5734 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit c2c81ded118484f8925bf81e270b416739cd72d9 +Subproject commit 98017c57349e259fab70c6a7830436b19a55f6f4 diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index fb2938aebb..3ce963f0d6 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -121,16 +121,16 @@ bool common_hal_alarm_woken_from_sleep(void) { STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); switch (cause) { - case NRF_SLEEP_WAKEUP_TIMER: { - return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); - } - case NRF_SLEEP_WAKEUP_TOUCHPAD: { - return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms); - } - case NRF_SLEEP_WAKEUP_GPIO: { - return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); - } - default: + case NRF_SLEEP_WAKEUP_TIMER: { + return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms); + } + case NRF_SLEEP_WAKEUP_TOUCHPAD: { + return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms); + } + case NRF_SLEEP_WAKEUP_GPIO: { + return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms); + } + default: break; } return mp_const_none; From 76033d5115889d779debfddc14c6990df31de799 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 22 Apr 2021 17:55:39 -0700 Subject: [PATCH 65/69] Merge MicroPython v1.11 into CircuitPython --- .gitmodules | 2 +- LICENSE | 2 +- devices/ble_hci/common-hal/_bleio/Adapter.c | 4 +- devices/ble_hci/common-hal/_bleio/Attribute.c | 6 +- .../common-hal/_bleio/Characteristic.c | 4 +- .../ble_hci/common-hal/_bleio/Connection.c | 2 +- devices/ble_hci/common-hal/_bleio/att.c | 24 +- docs/library/re.rst | 2 +- extmod/misc.h | 1 + extmod/modubinascii.c | 2 +- extmod/moductypes.c | 38 +- extmod/moduhashlib.c | 10 +- extmod/moduheapq.c | 2 +- extmod/modujson.c | 2 +- extmod/modurandom.c | 11 + extmod/moduselect.c | 13 +- extmod/modussl_axtls.c | 244 -- extmod/modussl_mbedtls.c | 330 -- extmod/modutimeq.c | 2 +- extmod/moduwebsocket.h | 10 + extmod/modwebrepl.c | 19 +- extmod/modwebsocket.c | 294 -- extmod/modwebsocket.h | 14 - extmod/ulab | 2 +- extmod/uos_dupterm.c | 25 + extmod/vfs.c | 4 +- extmod/vfs_fat.c | 17 +- extmod/vfs_fat_diskio.c | 14 +- extmod/vfs_posix.c | 2 +- extmod/vfs_posix_file.c | 2 +- lib/netutils/netutils.h | 6 + lib/netutils/trace.c | 170 + lib/oofatfs/diskio.h | 12 +- lib/oofatfs/ff.c | 3814 +++++++++-------- lib/oofatfs/ff.h | 220 +- lib/oofatfs/ffconf.h | 242 +- lib/oofatfs/{option/ccsbcs.c => ffunicode.c} | 578 ++- lib/oofatfs/option/unicode.c | 17 - lib/utils/gchelper.h | 34 + lib/utils/gchelper_m0.s | 61 + lib/utils/gchelper_m3.s | 67 + lib/utils/interrupt_char.c | 2 +- lib/utils/pyexec.c | 56 +- lib/utils/pyexec.h | 3 +- locale/circuitpython.pot | 32 +- mpy-cross/Makefile | 2 + mpy-cross/gccollect.c | 3 - mpy-cross/main.c | 63 +- mpy-cross/mpconfigport.h | 20 +- ports/atmel-samd/Makefile | 13 +- .../feather_m0_supersized/mpconfigboard.mk | 18 +- .../hallowing_m0_express/mpconfigboard.mk | 1 + .../itsybitsy_m0_express/mpconfigboard.mk | 1 + .../boards/metro_m0_express/mpconfigboard.mk | 1 + .../boards/pewpew_m4/mpconfigboard.mk | 1 + .../boards/qtpy_m0_haxpress/mpconfigboard.mk | 1 + .../boards/serpente/mpconfigboard.mk | 3 +- .../sparkfun_lumidrive/mpconfigboard.mk | 3 +- .../stackrduino_m0_pro/mpconfigboard.mk | 1 + .../trinket_m0_haxpress/mpconfigboard.mk | 16 +- ports/cxd56/Makefile | 13 +- ports/esp32s2/Makefile | 15 +- ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 4 +- .../esp32s2/common-hal/alarm/time/TimeAlarm.c | 4 +- .../common-hal/alarm/touch/TouchAlarm.c | 4 +- ports/esp32s2/common-hal/wifi/__init__.c | 2 +- ports/litex/Makefile | 15 +- ports/mimxrt10xx/Makefile | 14 +- ports/nrf/Makefile | 15 +- ports/nrf/boards/simmel/mpconfigboard.mk | 1 + ports/nrf/common-hal/_bleio/Connection.c | 2 +- ports/raspberrypi/Makefile | 13 +- .../bindings/rp2pio/StateMachine.c | 2 +- ports/stm/Makefile | 17 +- ports/unix/Makefile | 11 +- ports/unix/coverage.c | 3 +- ports/unix/file.c | 2 +- ports/unix/gccollect.c | 9 +- ports/unix/main.c | 5 + ports/unix/modffi.c | 11 +- ports/unix/modjni.c | 4 +- ports/unix/modmachine.c | 6 +- ports/unix/modos.c | 4 +- ports/unix/modtermios.c | 4 +- ports/unix/modtime.c | 3 +- ports/unix/moduselect.c | 4 +- ports/unix/modusocket.c | 48 +- ports/unix/mpconfigport.h | 4 +- ports/unix/mpconfigport_coverage.h | 4 + ports/unix/mpthreadport.c | 64 +- ports/unix/mpthreadport.h | 1 + py/asmarm.c | 16 +- py/asmarm.h | 7 +- py/asmthumb.c | 27 +- py/asmthumb.h | 6 +- py/asmx64.c | 4 +- py/asmx64.h | 3 + py/asmx86.c | 4 +- py/asmx86.h | 4 +- py/asmxtensa.c | 24 +- py/asmxtensa.h | 8 +- py/bc.c | 10 +- py/bc.h | 3 +- py/bc0.h | 3 +- py/binary.c | 7 +- py/binary.h | 3 +- py/builtin.h | 6 +- py/builtinevex.c | 6 +- py/builtinhelp.c | 4 +- py/builtinimport.c | 10 +- py/circuitpy_defns.mk | 13 + py/circuitpy_mpconfig.h | 4 +- py/compile.c | 175 +- py/emit.h | 18 +- py/emitbc.c | 19 +- py/emitglue.c | 52 +- py/emitglue.h | 46 +- py/emitinlinethumb.c | 5 + py/emitinlinextensa.c | 5 + py/emitnative.c | 165 +- py/enum.c | 2 +- py/frozenmod.h | 3 +- py/gc.c | 1 + py/gc_long_lived.c | 16 +- py/makemoduledefs.py | 4 +- py/makeqstrdata.py | 187 +- py/makeqstrdefs.py | 3 +- py/makeversionhdr.py | 1 + py/map.c | 14 +- py/misc.h | 4 +- py/mkenv.mk | 2 + py/mkrules.mk | 4 +- py/modarray.c | 2 + py/modbuiltins.c | 23 +- py/modio.c | 2 + py/modmath.c | 2 +- py/modthread.c | 2 +- py/moduerrno.c | 2 +- py/mpconfig.h | 61 +- py/mpprint.c | 22 +- py/mpstate.h | 4 +- py/nativeglue.c | 36 +- py/obj.c | 54 +- py/obj.h | 69 +- py/objarray.c | 60 +- py/objcomplex.c | 10 +- py/objdict.c | 35 +- py/objenumerate.c | 2 +- py/objexcept.c | 5 +- py/objfilter.c | 2 +- py/objfloat.c | 2 +- py/objfun.c | 32 +- py/objgenerator.c | 26 +- py/objint.c | 14 +- py/objint_longlong.c | 18 +- py/objint_mpz.c | 34 +- py/objlist.c | 34 +- py/objmap.c | 2 +- py/objmodule.c | 17 +- py/objnamedtuple.c | 2 +- py/objobject.c | 2 +- py/objproperty.c | 2 +- py/objrange.c | 4 +- py/objreversed.c | 2 +- py/objset.c | 28 +- py/objslice.c | 4 +- py/objstr.c | 56 +- py/objstr.h | 7 +- py/objstringio.c | 4 +- py/objstrunicode.c | 6 +- py/objtuple.c | 11 +- py/objtype.c | 50 +- py/objzip.c | 2 +- py/parse.c | 10 +- py/persistentcode.c | 592 ++- py/persistentcode.h | 16 + py/py.mk | 34 +- py/runtime.c | 67 +- py/runtime.h | 11 +- py/scheduler.c | 27 +- py/showbc.c | 11 +- py/stream.c | 6 +- py/stream.h | 1 + py/vm.c | 75 +- py/vmentrytable.h | 3 +- py/vstr.c | 1 + py/warning.c | 12 +- shared-bindings/_bleio/Adapter.c | 8 +- shared-bindings/_bleio/Address.c | 2 +- shared-bindings/_bleio/Characteristic.c | 4 +- shared-bindings/_bleio/CharacteristicBuffer.c | 2 +- shared-bindings/_bleio/Descriptor.c | 4 +- shared-bindings/_bleio/PacketBuffer.c | 2 +- shared-bindings/_bleio/ScanResults.c | 2 +- shared-bindings/_bleio/Service.c | 2 +- shared-bindings/_bleio/UUID.c | 6 +- shared-bindings/_bleio/__init__.c | 2 +- shared-bindings/_pew/PewPew.c | 6 +- shared-bindings/_pixelbuf/PixelBuf.c | 4 +- shared-bindings/_pixelbuf/__init__.c | 2 +- shared-bindings/_stage/__init__.c | 2 +- shared-bindings/aesio/aes.c | 8 +- shared-bindings/alarm/SleepMemory.c | 10 +- shared-bindings/alarm/__init__.c | 6 +- shared-bindings/audiobusio/PDMIn.c | 4 +- shared-bindings/audiocore/WaveFile.c | 2 +- shared-bindings/audiomp3/MP3Decoder.c | 4 +- shared-bindings/bitmaptools/__init__.c | 8 +- shared-bindings/busio/SPI.c | 2 +- shared-bindings/digitalio/DigitalInOut.c | 2 +- shared-bindings/displayio/Bitmap.c | 4 +- shared-bindings/displayio/Group.c | 2 +- shared-bindings/displayio/I2CDisplay.c | 2 +- shared-bindings/displayio/OnDiskBitmap.c | 2 +- shared-bindings/displayio/Palette.c | 6 +- shared-bindings/displayio/ParallelBus.c | 2 +- shared-bindings/displayio/TileGrid.c | 14 +- shared-bindings/gamepad/GamePad.c | 2 +- shared-bindings/gamepadshift/GamePadShift.c | 2 +- shared-bindings/gnss/GNSS.c | 6 +- shared-bindings/i2cperipheral/I2CPeripheral.c | 22 +- shared-bindings/ipaddress/IPv4Address.c | 4 +- shared-bindings/ipaddress/__init__.c | 2 +- .../memorymonitor/AllocationSize.c | 2 +- shared-bindings/microcontroller/Pin.c | 2 +- shared-bindings/msgpack/__init__.c | 6 +- shared-bindings/neopixel_write/__init__.c | 2 +- shared-bindings/nvm/ByteArray.c | 10 +- shared-bindings/ps2io/Ps2.c | 2 +- shared-bindings/pulseio/PulseIn.c | 2 +- shared-bindings/pulseio/PulseOut.c | 2 +- shared-bindings/storage/__init__.c | 2 +- shared-bindings/synthio/__init__.c | 2 +- shared-bindings/terminalio/Terminal.c | 4 +- shared-bindings/time/__init__.c | 4 +- shared-bindings/vectorio/Polygon.c | 2 +- shared-bindings/vectorio/VectorShape.c | 18 +- shared-bindings/wifi/ScannedNetworks.c | 2 +- shared-module/_pixelbuf/PixelBuf.c | 8 +- shared-module/displayio/TileGrid.c | 28 +- shared-module/displayio/display_core.c | 6 +- shared-module/gamepad/__init__.c | 2 +- shared-module/gamepadshift/__init__.c | 2 +- shared-module/msgpack/__init__.c | 14 +- shared-module/uheap/__init__.c | 32 +- shared-module/vectorio/VectorShape.c | 12 +- supervisor/shared/filesystem.c | 2 +- supervisor/shared/usb/usb_msc_flash.c | 4 +- supervisor/supervisor.mk | 1 + tests/basics/async_with.py | 10 + tests/basics/async_with.py.exp | 3 + tests/basics/builtin_next_arg2.py | 34 + tests/basics/bytearray_decode.py | 6 + tests/basics/gen_yield_from_throw.py | 22 +- tests/basics/generator_throw.py | 14 +- tests/basics/memoryview1.py | 54 + tests/basics/memoryview_itemsize.py | 15 + tests/basics/sys1.py | 5 + tests/basics/try_else.py | 76 + tests/basics/try_else_finally.py | 94 + tests/basics/try_finally_break.py | 99 + tests/basics/try_return.py | 9 + tests/cmdline/cmd_showbc.py | 1 + tests/cmdline/cmd_showbc.py.exp | 36 +- tests/cmdline/repl_autocomplete.py | 3 - tests/cmdline/repl_autocomplete.py.exp | 6 - tests/extmod/ucryptolib_aes128_ctr.py | 28 + tests/extmod/ucryptolib_aes128_ctr.py.exp | 3 + tests/extmod/ujson_loads_float.py | 1 + tests/extmod/ussl_basic.py | 13 +- tests/extmod/ussl_basic.py.exp | 1 - tests/extmod/vfs_fat_ramdisklarge.py | 70 + tests/extmod/vfs_fat_ramdisklarge.py.exp | 3 + tests/extmod/websocket_basic.py | 62 - tests/import/mpy_invalid.py | 1 + tests/import/mpy_invalid.py.exp | 5 +- tests/import/mpy_native.py | 96 + tests/import/mpy_native.py.exp | 2 + tests/micropython/heapalloc_fail_bytearray.py | 93 + .../heapalloc_fail_bytearray.py.exp | 11 + tests/micropython/heapalloc_fail_dict.py | 21 + tests/micropython/heapalloc_fail_dict.py.exp | 2 + tests/micropython/heapalloc_fail_list.py | 39 + tests/micropython/heapalloc_fail_list.py.exp | 4 + .../micropython/heapalloc_fail_memoryview.py | 28 + .../heapalloc_fail_memoryview.py.exp | 2 + tests/micropython/heapalloc_fail_set.py | 23 + tests/micropython/heapalloc_fail_set.py.exp | 2 + tests/micropython/heapalloc_fail_tuple.py | 12 + tests/micropython/heapalloc_fail_tuple.py.exp | 1 + tests/micropython/viper_types.py | 32 + tests/micropython/viper_types.py.exp | 8 + tests/run-tests | 15 +- tests/unix/extra_coverage.py.exp | 7 +- tools/mpy-tool.py | 584 ++- tools/pyboard.py | 8 +- tools/upip.py | 22 +- 297 files changed, 6821 insertions(+), 4591 deletions(-) delete mode 100644 extmod/modussl_axtls.c delete mode 100644 extmod/modussl_mbedtls.c create mode 100644 extmod/moduwebsocket.h delete mode 100644 extmod/modwebsocket.c delete mode 100644 extmod/modwebsocket.h create mode 100644 lib/netutils/trace.c rename lib/oofatfs/{option/ccsbcs.c => ffunicode.c} (58%) delete mode 100644 lib/oofatfs/option/unicode.c create mode 100644 lib/utils/gchelper.h create mode 100644 lib/utils/gchelper_m0.s create mode 100644 lib/utils/gchelper_m3.s create mode 100644 tests/basics/builtin_next_arg2.py create mode 100644 tests/basics/bytearray_decode.py create mode 100644 tests/basics/memoryview_itemsize.py create mode 100644 tests/basics/try_else.py create mode 100644 tests/basics/try_else_finally.py create mode 100644 tests/basics/try_finally_break.py create mode 100644 tests/extmod/ucryptolib_aes128_ctr.py create mode 100644 tests/extmod/ucryptolib_aes128_ctr.py.exp create mode 100644 tests/extmod/vfs_fat_ramdisklarge.py create mode 100644 tests/extmod/vfs_fat_ramdisklarge.py.exp delete mode 100644 tests/extmod/websocket_basic.py create mode 100644 tests/import/mpy_native.py create mode 100644 tests/import/mpy_native.py.exp create mode 100644 tests/micropython/heapalloc_fail_bytearray.py create mode 100644 tests/micropython/heapalloc_fail_bytearray.py.exp create mode 100644 tests/micropython/heapalloc_fail_dict.py create mode 100644 tests/micropython/heapalloc_fail_dict.py.exp create mode 100644 tests/micropython/heapalloc_fail_list.py create mode 100644 tests/micropython/heapalloc_fail_list.py.exp create mode 100644 tests/micropython/heapalloc_fail_memoryview.py create mode 100644 tests/micropython/heapalloc_fail_memoryview.py.exp create mode 100644 tests/micropython/heapalloc_fail_set.py create mode 100644 tests/micropython/heapalloc_fail_set.py.exp create mode 100644 tests/micropython/heapalloc_fail_tuple.py create mode 100644 tests/micropython/heapalloc_fail_tuple.py.exp create mode 100644 tests/micropython/viper_types.py create mode 100644 tests/micropython/viper_types.py.exp diff --git a/.gitmodules b/.gitmodules index da5b5835a6..24ba2e2f6f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -113,7 +113,7 @@ url = https://github.com/adafruit/Adafruit_CircuitPython_Register.git [submodule "extmod/ulab"] path = extmod/ulab - url = https://github.com/v923z/micropython-ulab + url = https://github.com/adafruit/circuitpython-ulab [submodule "frozen/Adafruit_CircuitPython_ESP32SPI"] path = frozen/Adafruit_CircuitPython_ESP32SPI url = https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI diff --git a/LICENSE b/LICENSE index e3474e33dd..e6a54cf269 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013, 2014 Damien P. George +Copyright (c) 2013-2019 Damien P. George Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index 7f0b088c4e..14938e8a1d 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -886,10 +886,10 @@ uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *att uint16_t handle = (uint16_t)adapter->attributes->len; mp_obj_list_append(adapter->attributes, attribute); - if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) { + if (mp_obj_is_type(attribute, &bleio_service_type)) { adapter->last_added_service_handle = handle; } - if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) { + if (mp_obj_is_type(attribute, &bleio_characteristic_type)) { adapter->last_added_characteristic_handle = handle; } diff --git a/devices/ble_hci/common-hal/_bleio/Attribute.c b/devices/ble_hci/common-hal/_bleio/Attribute.c index 26fabed098..b1b31d604f 100644 --- a/devices/ble_hci/common-hal/_bleio/Attribute.c +++ b/devices/ble_hci/common-hal/_bleio/Attribute.c @@ -33,15 +33,15 @@ bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute) { - if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) { + if (mp_obj_is_type(attribute, &bleio_characteristic_type)) { bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute); return characteristic->uuid; } - if (MP_OBJ_IS_TYPE(attribute, &bleio_descriptor_type)) { + if (mp_obj_is_type(attribute, &bleio_descriptor_type)) { bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute); return descriptor->uuid; } - if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) { + if (mp_obj_is_type(attribute, &bleio_service_type)) { bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute); return service->uuid; } diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.c b/devices/ble_hci/common-hal/_bleio/Characteristic.c index db1317f4c8..940fdfc755 100644 --- a/devices/ble_hci/common-hal/_bleio/Characteristic.c +++ b/devices/ble_hci/common-hal/_bleio/Characteristic.c @@ -213,9 +213,9 @@ bool bleio_characteristic_set_local_value(bleio_characteristic_obj_t *self, mp_b self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len); - if (MP_OBJ_IS_TYPE(self->observer, &bleio_characteristic_buffer_type)) { + if (mp_obj_is_type(self->observer, &bleio_characteristic_buffer_type)) { bleio_characteristic_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo); - } else if (MP_OBJ_IS_TYPE(self->observer, &bleio_packet_buffer_type)) { + } else if (mp_obj_is_type(self->observer, &bleio_packet_buffer_type)) { bleio_packet_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo); } else { return false; diff --git a/devices/ble_hci/common-hal/_bleio/Connection.c b/devices/ble_hci/common-hal/_bleio/Connection.c index a27c243f44..fd041ca002 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.c +++ b/devices/ble_hci/common-hal/_bleio/Connection.c @@ -644,7 +644,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); // mp_obj_t uuid_obj; // while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { -// if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { +// if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { // mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist")); // } // bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c index 5a3eb94737..5767045481 100644 --- a/devices/ble_hci/common-hal/_bleio/att.c +++ b/devices/ble_hci/common-hal/_bleio/att.c @@ -539,7 +539,7 @@ void att_remove_connection(uint16_t conn_handle, uint8_t reason) { .len = sizeof(zero), }; - if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) { + if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) { bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj); if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == BLE_UUID_CCCD) { common_hal_bleio_descriptor_set_value(descriptor, &zero_cccd_value); @@ -800,7 +800,7 @@ STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl // Fetch the uuid for the given attribute, which might be a characteristic or a descriptor. bleio_uuid_obj_t *uuid; - if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) { + if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) { bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); if (characteristic->handle != handle) { // If the handles don't match, this is the characteristic definition attribute. @@ -971,7 +971,7 @@ void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, ui } mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle); - if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) { + if (mp_obj_is_type(attribute_obj, &bleio_service_type)) { bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj); // Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute @@ -1083,7 +1083,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui size_t rsp_length = sizeof(rsp_t); mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle); - if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) { + if (mp_obj_is_type(attribute_obj, &bleio_service_type)) { if (offset) { send_error(conn_handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG, handle, BT_ATT_ERR_INVALID_PDU); return; @@ -1095,7 +1095,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui common_hal_bleio_uuid_pack_into(service->uuid, rsp->r.value); rsp_length += sizeof_service_uuid; - } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) { + } else if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) { bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); if (characteristic->decl_handle == handle) { // Read characteristic declaration. Return properties, value handle, and uuid. @@ -1135,7 +1135,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui memcpy(rsp->r.value, bufinfo.buf + offset, value_length); rsp_length += value_length; } - } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) { + } else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) { bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj); mp_buffer_info_t bufinfo; @@ -1203,7 +1203,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle); if (type_uuid == BLE_UUID_CHARACTERISTIC && - MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) { + mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) { // Request is for characteristic declarations. bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); @@ -1250,7 +1250,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl rsp_length += data_length; no_data = false; - } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) { + } else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) { // See if request is for a descriptor value with a 16-bit UUID, such as the CCCD. bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj); if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) { @@ -1271,7 +1271,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl break; } - } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) { + } else if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) { // See if request is for a characteristic value with a 16-bit UUID. bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) { @@ -1359,7 +1359,7 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, req->handle); - if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) { + if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) { bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj); // Don't write the characteristic declaration. @@ -1377,7 +1377,7 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t // Just change the local value. Don't fire off notifications, etc. bleio_characteristic_set_local_value(characteristic, &bufinfo); - } else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) { + } else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) { bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj); // Only CCCD's are writable. if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) != BLE_UUID_CCCD) { @@ -1427,7 +1427,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_ mp_obj_t *attribute = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle); - if (!MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) { + if (!mp_obj_is_type(attribute, &bleio_characteristic_type)) { send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG); return; } diff --git a/docs/library/re.rst b/docs/library/re.rst index 9c266a6d8f..8cbd43e83b 100644 --- a/docs/library/re.rst +++ b/docs/library/re.rst @@ -174,7 +174,7 @@ Match objects Match objects as returned by `match()` and `search()` methods, and passed to the replacement function in `sub()`. -.. method:: match.group([index]) +.. method:: match.group(index) Return matching (sub)string. *index* is 0 for entire match, 1 and above for each capturing group. Only numeric groups are supported. diff --git a/extmod/misc.h b/extmod/misc.h index 3e12e56719..6ff9bd8c87 100644 --- a/extmod/misc.h +++ b/extmod/misc.h @@ -15,6 +15,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj); #if MICROPY_PY_OS_DUPTERM +bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream); int mp_uos_dupterm_rx_chr(void); void mp_uos_dupterm_tx_strn(const char *str, size_t len); void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc); diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 91df02317e..3fae9e9e4d 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -13,7 +13,7 @@ static void check_not_unicode(const mp_obj_t arg) { #if MICROPY_CPYTHON_COMPAT - if (MP_OBJ_IS_STR(arg)) { + if (mp_obj_is_str(arg)) { mp_raise_TypeError(translate("a bytes-like object is required")); } #endif diff --git a/extmod/moductypes.c b/extmod/moductypes.c index d093d39787..ec698bf65c 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -118,13 +118,13 @@ STATIC void uctypes_struct_print(const mp_print_t *print, mp_obj_t self_in, mp_p (void)kind; mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); const char *typen = "unk"; - if (MP_OBJ_IS_TYPE(self->desc, &mp_type_dict) + if (mp_obj_is_type(self->desc, &mp_type_dict) #if MICROPY_PY_COLLECTIONS_ORDEREDDICT - || MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict) + || mp_obj_is_type(self->desc, &mp_type_ordereddict) #endif ) { typen = "STRUCT"; - } else if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) { + } else if (mp_obj_is_type(self->desc, &mp_type_tuple)) { mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]); uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS); @@ -195,14 +195,14 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_ } STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size) { - if (!MP_OBJ_IS_TYPE(desc_in, &mp_type_dict) + if (!mp_obj_is_type(desc_in, &mp_type_dict) #if MICROPY_PY_COLLECTIONS_ORDEREDDICT - && !MP_OBJ_IS_TYPE(desc_in, &mp_type_ordereddict) + && !mp_obj_is_type(desc_in, &mp_type_ordereddict) #endif ) { - if (MP_OBJ_IS_TYPE(desc_in, &mp_type_tuple)) { + if (mp_obj_is_type(desc_in, &mp_type_tuple)) { return uctypes_struct_agg_size((mp_obj_tuple_t *)MP_OBJ_TO_PTR(desc_in), layout_type, max_field_size); - } else if (MP_OBJ_IS_SMALL_INT(desc_in)) { + } else if (mp_obj_is_small_int(desc_in)) { // We allow sizeof on both type definitions and structures/structure fields, // but scalar structure field is lowered into native Python int, so all // type info is lost. So, we cannot say if it's scalar type description, @@ -216,9 +216,9 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_ mp_uint_t total_size = 0; for (mp_uint_t i = 0; i < d->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&d->map, i)) { + if (mp_map_slot_is_filled(&d->map, i)) { mp_obj_t v = d->map.table[i].value; - if (MP_OBJ_IS_SMALL_INT(v)) { + if (mp_obj_is_small_int(v)) { mp_uint_t offset = MP_OBJ_SMALL_INT_VALUE(v); mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS); offset &= VALUE_MASK(VAL_TYPE_BITS); @@ -233,7 +233,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_ total_size = offset + s; } } else { - if (!MP_OBJ_IS_TYPE(v, &mp_type_tuple)) { + if (!mp_obj_is_type(v, &mp_type_tuple)) { syntax_error(); } mp_obj_tuple_t *t = MP_OBJ_TO_PTR(v); @@ -257,13 +257,13 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_ STATIC mp_obj_t uctypes_struct_sizeof(size_t n_args, const mp_obj_t *args) { mp_obj_t obj_in = args[0]; mp_uint_t max_field_size = 0; - if (MP_OBJ_IS_TYPE(obj_in, &mp_type_bytearray)) { + if (mp_obj_is_type(obj_in, &mp_type_bytearray)) { return mp_obj_len(obj_in); } int layout_type = LAYOUT_NATIVE; // We can apply sizeof either to structure definition (a dict) // or to instantiated structure - if (MP_OBJ_IS_TYPE(obj_in, &uctypes_struct_type)) { + if (mp_obj_is_type(obj_in, &uctypes_struct_type)) { if (n_args != 1) { mp_raise_TypeError(NULL); } @@ -400,16 +400,16 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) { STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set_val) { mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); - if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict) + if (!mp_obj_is_type(self->desc, &mp_type_dict) #if MICROPY_PY_COLLECTIONS_ORDEREDDICT - && !MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict) + && !mp_obj_is_type(self->desc, &mp_type_ordereddict) #endif ) { mp_raise_TypeError(translate("struct: no fields")); } mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr)); - if (MP_OBJ_IS_SMALL_INT(deref)) { + if (mp_obj_is_small_int(deref)) { mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(deref); mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS); offset &= VALUE_MASK(VAL_TYPE_BITS); @@ -470,7 +470,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set return MP_OBJ_NULL; } - if (!MP_OBJ_IS_TYPE(deref, &mp_type_tuple)) { + if (!mp_obj_is_type(deref, &mp_type_tuple)) { syntax_error(); } @@ -537,7 +537,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob return MP_OBJ_NULL; // op not supported } else { // load / store - if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) { + if (!mp_obj_is_type(self->desc, &mp_type_tuple)) { mp_raise_TypeError(translate("struct: cannot index")); } @@ -588,7 +588,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob } else if (agg_type == PTR) { byte *p = *(void **)self->addr; - if (MP_OBJ_IS_SMALL_INT(t->items[1])) { + if (mp_obj_is_small_int(t->items[1])) { uint val_type = GET_TYPE(MP_OBJ_SMALL_INT_VALUE(t->items[1]), VAL_TYPE_BITS); return get_aligned(val_type, p, index); } else { @@ -612,7 +612,7 @@ STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) { mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); switch (op) { case MP_UNARY_OP_INT: - if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) { + if (mp_obj_is_type(self->desc, &mp_type_tuple)) { mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc); mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]); uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS); diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 7069cc4792..379ba8c285 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -88,12 +88,16 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { static void check_not_unicode(const mp_obj_t arg) { #if MICROPY_CPYTHON_COMPAT - if (MP_OBJ_IS_STR(arg)) { + if (mp_obj_is_str(arg)) { mp_raise_TypeError(translate("a bytes-like object is required")); } #endif } +#if MICROPY_PY_UHASHLIB_SHA256 +#include "crypto-algorithms/sha256.c" +#endif + STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); @@ -336,8 +340,4 @@ const mp_obj_module_t mp_module_uhashlib = { .globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals, }; -#if MICROPY_PY_UHASHLIB_SHA256 -#include "crypto-algorithms/sha256.c" -#endif - #endif // MICROPY_PY_UHASHLIB diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c index 9e02d367a2..880b0ad273 100644 --- a/extmod/moduheapq.c +++ b/extmod/moduheapq.c @@ -13,7 +13,7 @@ // the algorithm here is modelled on CPython's heapq.py STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) { - if (!MP_OBJ_IS_TYPE(heap_in, &mp_type_list)) { + if (!mp_obj_is_type(heap_in, &mp_type_list)) { mp_raise_TypeError(translate("heap must be a list")); } return MP_OBJ_TO_PTR(heap_in); diff --git a/extmod/modujson.c b/extmod/modujson.c index 63e8a011bf..07d18e5e88 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -243,7 +243,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) { cur = S_CUR(s); if (cur == '.' || cur == 'E' || cur == 'e') { flt = true; - } else if (cur == '-' || unichar_isdigit(cur)) { + } else if (cur == '+' || cur == '-' || unichar_isdigit(cur)) { // pass } else { break; diff --git a/extmod/modurandom.c b/extmod/modurandom.c index 26e89f77f2..f0662a1432 100644 --- a/extmod/modurandom.c +++ b/extmod/modurandom.c @@ -180,8 +180,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform); #endif // MICROPY_PY_URANDOM_EXTRA_FUNCS +#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC +STATIC mp_obj_t mod_urandom___init__() { + mod_urandom_seed(MP_OBJ_NEW_SMALL_INT(MICROPY_PY_URANDOM_SEED_INIT_FUNC)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom___init___obj, mod_urandom___init__); +#endif + STATIC const mp_rom_map_elem_t mp_module_urandom_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_urandom) }, + #ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC + { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&mod_urandom___init___obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_urandom_getrandbits_obj) }, { MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_urandom_seed_obj) }, #if MICROPY_PY_URANDOM_EXTRA_FUNCS diff --git a/extmod/moduselect.c b/extmod/moduselect.c index e88494b279..50587184c0 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) // SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky // // SPDX-License-Identifier: MIT @@ -57,7 +58,7 @@ STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_ STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) { mp_uint_t n_ready = 0; for (mp_uint_t i = 0; i < poll_map->alloc; ++i) { - if (!MP_MAP_SLOT_IS_FILLED(poll_map, i)) { + if (!mp_map_slot_is_filled(poll_map, i)) { continue; } @@ -91,7 +92,7 @@ STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) { } /// \function select(rlist, wlist, xlist[, timeout]) -STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) { +STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) { // get array data from tuple/list arguments size_t rwx_len[3]; mp_obj_t *r_array, *w_array, *x_array; @@ -135,7 +136,7 @@ STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) { list_array[2] = mp_obj_new_list(rwx_len[2], NULL); rwx_len[0] = rwx_len[1] = rwx_len[2] = 0; for (mp_uint_t i = 0; i < poll_map.alloc; ++i) { - if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) { + if (!mp_map_slot_is_filled(&poll_map, i)) { continue; } poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map.table[i].value); @@ -170,7 +171,7 @@ typedef struct _mp_obj_poll_t { } mp_obj_poll_t; /// \method register(obj[, eventmask]) -STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) { +STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) { mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); mp_uint_t flags; if (n_args == 3) { @@ -246,7 +247,7 @@ STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) { mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL)); n_ready = 0; for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) { - if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) { + if (!mp_map_slot_is_filled(&self->poll_map, i)) { continue; } poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value); @@ -289,7 +290,7 @@ STATIC mp_obj_t poll_iternext(mp_obj_t self_in) { for (mp_uint_t i = self->iter_idx; i < self->poll_map.alloc; ++i) { self->iter_idx++; - if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) { + if (!mp_map_slot_is_filled(&self->poll_map, i)) { continue; } poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value); diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c deleted file mode 100644 index 673f480b2c..0000000000 --- a/extmod/modussl_axtls.c +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2015-2017 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - -#include -#include - -#include "py/runtime.h" -#include "py/stream.h" - -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_USSL && MICROPY_SSL_AXTLS - -#include "ssl.h" - -typedef struct _mp_obj_ssl_socket_t { - mp_obj_base_t base; - mp_obj_t sock; - SSL_CTX *ssl_ctx; - SSL *ssl_sock; - byte *buf; - uint32_t bytes_left; -} mp_obj_ssl_socket_t; - -struct ssl_args { - mp_arg_val_t key; - mp_arg_val_t cert; - mp_arg_val_t server_side; - mp_arg_val_t server_hostname; -}; - -STATIC const mp_obj_type_t ussl_socket_type; - -STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { - #if MICROPY_PY_USSL_FINALISER - mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t); - #else - mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); - #endif - o->base.type = &ussl_socket_type; - o->buf = NULL; - o->bytes_left = 0; - o->sock = sock; - - uint32_t options = SSL_SERVER_VERIFY_LATER; - if (args->key.u_obj != mp_const_none) { - options |= SSL_NO_DEFAULT_KEY; - } - if ((o->ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) { - mp_raise_OSError(MP_EINVAL); - } - - if (args->key.u_obj != mp_const_none) { - size_t len; - const byte *data = (const byte *)mp_obj_str_get_data(args->key.u_obj, &len); - int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL); - if (res != SSL_OK) { - mp_raise_ValueError(translate("invalid key")); - } - - data = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &len); - res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL); - if (res != SSL_OK) { - mp_raise_ValueError(translate("invalid cert")); - } - } - - if (args->server_side.u_bool) { - o->ssl_sock = ssl_server_new(o->ssl_ctx, (long)sock); - } else { - SSL_EXTENSIONS *ext = ssl_ext_new(); - - if (args->server_hostname.u_obj != mp_const_none) { - ext->host_name = (char *)mp_obj_str_get_str(args->server_hostname.u_obj); - } - - o->ssl_sock = ssl_client_new(o->ssl_ctx, (long)sock, NULL, 0, ext); - - int res = ssl_handshake_status(o->ssl_sock); - // Pointer to SSL_EXTENSIONS as being passed to ssl_client_new() - // is saved in ssl_sock->extensions. - // As of axTLS 2.1.3, extensions aren't used beyond the initial - // handshake, and that's pretty much how it's expected to be. So - // we allocate them on stack and reset the pointer after handshake. - - if (res != SSL_OK) { - printf("ssl_handshake_status: %d\n", res); - ssl_display_error(res); - mp_raise_OSError(MP_EIO); - } - - } - - return o; -} - -STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - (void)kind; - mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "<_SSLSocket %p>", self->ssl_sock); -} - -STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); - - if (o->ssl_sock == NULL) { - *errcode = EBADF; - return MP_STREAM_ERROR; - } - - while (o->bytes_left == 0) { - mp_int_t r = ssl_read(o->ssl_sock, &o->buf); - if (r == SSL_OK) { - // SSL_OK from ssl_read() means "everything is ok, but there's - // no user data yet". So, we just keep reading. - continue; - } - if (r < 0) { - if (r == SSL_CLOSE_NOTIFY || r == SSL_ERROR_CONN_LOST) { - // EOF - return 0; - } - if (r == SSL_EAGAIN) { - r = MP_EAGAIN; - } - *errcode = r; - return MP_STREAM_ERROR; - } - o->bytes_left = r; - } - - if (size > o->bytes_left) { - size = o->bytes_left; - } - memcpy(buf, o->buf, size); - o->buf += size; - o->bytes_left -= size; - return size; -} - -STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); - - if (o->ssl_sock == NULL) { - *errcode = EBADF; - return MP_STREAM_ERROR; - } - - mp_int_t r = ssl_write(o->ssl_sock, buf, size); - if (r < 0) { - *errcode = r; - return MP_STREAM_ERROR; - } - return r; -} - -STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { - mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in); - if (request == MP_STREAM_CLOSE && self->ssl_sock != NULL) { - ssl_free(self->ssl_sock); - ssl_ctx_free(self->ssl_ctx); - self->ssl_sock = NULL; - } - // Pass all requests down to the underlying socket - return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode); -} - -STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { - // Currently supports only blocking mode - (void)self_in; - if (!mp_obj_is_true(flag_in)) { - mp_raise_NotImplementedError(NULL); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); - -STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, - #if MICROPY_PY_USSL_FINALISER - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, - #endif -}; - -STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); - -STATIC const mp_stream_p_t ussl_socket_stream_p = { - MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) - .read = socket_read, - .write = socket_write, - .ioctl = socket_ioctl, -}; - -STATIC const mp_obj_type_t ussl_socket_type = { - { &mp_type_type }, - // Save on qstr's, reuse same as for module - .name = MP_QSTR_ussl, - .print = socket_print, - .getiter = NULL, - .iternext = NULL, - .protocol = &ussl_socket_stream_p, - .locals_dict = (void *)&ussl_socket_locals_dict, -}; - -STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - // TODO: Implement more args - static const mp_arg_t allowed_args[] = { - { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, - { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, - { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} }, - }; - - // TODO: Check that sock implements stream protocol - mp_obj_t sock = pos_args[0]; - - struct ssl_args args; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, - MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); - - return MP_OBJ_FROM_PTR(socket_new(sock, &args)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); - -STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) }, - { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table); - -const mp_obj_module_t mp_module_ussl = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&mp_module_ssl_globals, -}; - -#endif // MICROPY_PY_USSL diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c deleted file mode 100644 index 05d6047f9b..0000000000 --- a/extmod/modussl_mbedtls.c +++ /dev/null @@ -1,330 +0,0 @@ -// Copyright (c) 2016 Linaro Ltd. -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - -#include "py/mpconfig.h" -#if MICROPY_PY_USSL && MICROPY_SSL_MBEDTLS - -#include -#include -#include // needed because mp_is_nonblocking_error uses system error codes - -#include "py/runtime.h" -#include "py/stream.h" - -// mbedtls_time_t -#include "mbedtls/platform.h" -#include "mbedtls/net.h" -#include "mbedtls/ssl.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/pk.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/debug.h" - -typedef struct _mp_obj_ssl_socket_t { - mp_obj_base_t base; - mp_obj_t sock; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; - mbedtls_ssl_context ssl; - mbedtls_ssl_config conf; - mbedtls_x509_crt cacert; - mbedtls_x509_crt cert; - mbedtls_pk_context pkey; -} mp_obj_ssl_socket_t; - -struct ssl_args { - mp_arg_val_t key; - mp_arg_val_t cert; - mp_arg_val_t server_side; - mp_arg_val_t server_hostname; -}; - -STATIC const mp_obj_type_t ussl_socket_type; - -#ifdef MBEDTLS_DEBUG_C -STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { - (void)ctx; - (void)level; - printf("DBG:%s:%04d: %s\n", file, line, str); -} -#endif - -STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; - - const mp_stream_p_t *sock_stream = mp_get_stream(sock); - int err; - - mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err); - if (out_sz == MP_STREAM_ERROR) { - if (mp_is_nonblocking_error(err)) { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - return -err; - } else { - return out_sz; - } -} - -STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { - mp_obj_t sock = *(mp_obj_t *)ctx; - - const mp_stream_p_t *sock_stream = mp_get_stream(sock); - int err; - - mp_uint_t out_sz = sock_stream->read(sock, buf, len, &err); - if (out_sz == MP_STREAM_ERROR) { - if (mp_is_nonblocking_error(err)) { - return MBEDTLS_ERR_SSL_WANT_READ; - } - return -err; - } else { - return out_sz; - } -} - - -STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) { - // Verify the socket object has the full stream protocol - mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); - - #if MICROPY_PY_USSL_FINALISER - mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t); - #else - mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); - #endif - o->base.type = &ussl_socket_type; - o->sock = sock; - - int ret; - mbedtls_ssl_init(&o->ssl); - mbedtls_ssl_config_init(&o->conf); - mbedtls_x509_crt_init(&o->cacert); - mbedtls_x509_crt_init(&o->cert); - mbedtls_pk_init(&o->pkey); - mbedtls_ctr_drbg_init(&o->ctr_drbg); - #ifdef MBEDTLS_DEBUG_C - // Debug level (0-4) - mbedtls_debug_set_threshold(0); - #endif - - mbedtls_entropy_init(&o->entropy); - const byte seed[] = "upy"; - ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, mbedtls_entropy_func, &o->entropy, seed, sizeof(seed)); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_ssl_config_defaults(&o->conf, - args->server_side.u_bool ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); - if (ret != 0) { - goto cleanup; - } - - mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE); - mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg); - #ifdef MBEDTLS_DEBUG_C - mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL); - #endif - - ret = mbedtls_ssl_setup(&o->ssl, &o->conf); - if (ret != 0) { - goto cleanup; - } - - if (args->server_hostname.u_obj != mp_const_none) { - const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj); - ret = mbedtls_ssl_set_hostname(&o->ssl, sni); - if (ret != 0) { - goto cleanup; - } - } - - mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); - - if (args->key.u_obj != MP_OBJ_NULL) { - size_t key_len; - const byte *key = (const byte *)mp_obj_str_get_data(args->key.u_obj, &key_len); - // len should include terminating null - ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0); - assert(ret == 0); - - size_t cert_len; - const byte *cert = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &cert_len); - // len should include terminating null - ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1); - assert(ret == 0); - - ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey); - assert(ret == 0); - } - - while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - printf("mbedtls_ssl_handshake error: -%x\n", -ret); - goto cleanup; - } - } - - return o; - -cleanup: - mbedtls_pk_free(&o->pkey); - mbedtls_x509_crt_free(&o->cert); - mbedtls_x509_crt_free(&o->cacert); - mbedtls_ssl_free(&o->ssl); - mbedtls_ssl_config_free(&o->conf); - mbedtls_ctr_drbg_free(&o->ctr_drbg); - mbedtls_entropy_free(&o->entropy); - - if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) { - mp_raise_OSError(MP_ENOMEM); - } else { - mp_raise_OSError(MP_EIO); - } -} - -STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); - if (!mp_obj_is_true(binary_form)) { - mp_raise_NotImplementedError(NULL); - } - const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(&o->ssl); - return mp_obj_new_bytes(peer_cert->raw.p, peer_cert->raw.len); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_getpeercert_obj, mod_ssl_getpeercert); - -STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - (void)kind; - mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "<_SSLSocket %p>", self); -} - -STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); - - int ret = mbedtls_ssl_read(&o->ssl, buf, size); - if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - // end of stream - return 0; - } - if (ret >= 0) { - return ret; - } - if (ret == MBEDTLS_ERR_SSL_WANT_READ) { - ret = MP_EWOULDBLOCK; - } - *errcode = ret; - return MP_STREAM_ERROR; -} - -STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in); - - int ret = mbedtls_ssl_write(&o->ssl, buf, size); - if (ret >= 0) { - return ret; - } - if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - ret = MP_EWOULDBLOCK; - } - *errcode = ret; - return MP_STREAM_ERROR; -} - -STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { - mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in); - mp_obj_t sock = o->sock; - mp_obj_t dest[3]; - mp_load_method(sock, MP_QSTR_setblocking, dest); - dest[2] = flag_in; - return mp_call_method_n_kw(1, 0, dest); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); - -STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { - mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in); - if (request == MP_STREAM_CLOSE) { - mbedtls_pk_free(&self->pkey); - mbedtls_x509_crt_free(&self->cert); - mbedtls_x509_crt_free(&self->cacert); - mbedtls_ssl_free(&self->ssl); - mbedtls_ssl_config_free(&self->conf); - mbedtls_ctr_drbg_free(&self->ctr_drbg); - mbedtls_entropy_free(&self->entropy); - } - // Pass all requests down to the underlying socket - return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode); -} - -STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, - #if MICROPY_PY_USSL_FINALISER - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table); - -STATIC const mp_stream_p_t ussl_socket_stream_p = { - MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) - .read = socket_read, - .write = socket_write, - .ioctl = socket_ioctl, -}; - -STATIC const mp_obj_type_t ussl_socket_type = { - { &mp_type_type }, - // Save on qstr's, reuse same as for module - .name = MP_QSTR_ussl, - .print = socket_print, - .getiter = NULL, - .iternext = NULL, - .protocol = &ussl_socket_stream_p, - .locals_dict = (void *)&ussl_socket_locals_dict, -}; - -STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - // TODO: Implement more args - static const mp_arg_t allowed_args[] = { - { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // TODO: Check that sock implements stream protocol - mp_obj_t sock = pos_args[0]; - - struct ssl_args args; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, - MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); - - return MP_OBJ_FROM_PTR(socket_new(sock, &args)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket); - -STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) }, - { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table); - -const mp_obj_module_t mp_module_ussl = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&mp_module_ssl_globals, -}; - -#endif // MICROPY_PY_USSL diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index beeb4353d9..b24633398c 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -126,7 +126,7 @@ STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) { mp_raise_IndexError(translate("empty heap")); } mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref); - if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 3) { + if (!mp_obj_is_type(list_ref, &mp_type_list) || ret->len < 3) { mp_raise_TypeError(NULL); } diff --git a/extmod/moduwebsocket.h b/extmod/moduwebsocket.h new file mode 100644 index 0000000000..c1ea291ed7 --- /dev/null +++ b/extmod/moduwebsocket.h @@ -0,0 +1,10 @@ +#ifndef MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H +#define MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H + +#define FRAME_OPCODE_MASK 0x0f +enum { + FRAME_CONT, FRAME_TXT, FRAME_BIN, + FRAME_CLOSE = 0x8, FRAME_PING, FRAME_PONG +}; + +#endif // MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index f470e26dba..9edea9b087 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -13,7 +13,7 @@ #ifdef MICROPY_PY_WEBREPL_DELAY #include "py/mphal.h" #endif -#include "extmod/modwebsocket.h" +#include "extmod/moduwebsocket.h" #if MICROPY_PY_WEBREPL @@ -87,6 +87,15 @@ STATIC mp_obj_t webrepl_make_new(const mp_obj_type_t *type, size_t n_args, size_ return o; } +STATIC void check_file_op_finished(mp_obj_webrepl_t *self) { + if (self->data_to_recv == 0) { + mp_stream_close(self->cur_file); + self->hdr_to_recv = sizeof(struct webrepl_file); + DEBUG_printf("webrepl: Finished file operation %d\n", self->hdr.type); + write_webrepl_resp(self->sock, 0); + } +} + STATIC int write_file_chunk(mp_obj_webrepl_t *self) { const mp_stream_p_t *file_stream = mp_get_stream(self->cur_file); byte readbuf[2 + 256]; @@ -139,6 +148,7 @@ STATIC void handle_op(mp_obj_webrepl_t *self) { if (self->hdr.type == PUT_FILE) { self->data_to_recv = self->hdr.size; + check_file_op_finished(self); } else if (self->hdr.type == GET_FILE) { self->data_to_recv = 1; } @@ -245,12 +255,7 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int } } - if (self->data_to_recv == 0) { - mp_stream_close(self->cur_file); - self->hdr_to_recv = sizeof(struct webrepl_file); - DEBUG_printf("webrepl: Finished file operation %d\n", self->hdr.type); - write_webrepl_resp(self->sock, 0); - } + check_file_op_finished(self); #ifdef MICROPY_PY_WEBREPL_DELAY // Some platforms may have broken drivers and easily gets diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c deleted file mode 100644 index 6547ebee44..0000000000 --- a/extmod/modwebsocket.c +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - -#include -#include -#include - -#include "py/runtime.h" -#include "py/stream.h" -#include "extmod/modwebsocket.h" - -#if MICROPY_PY_WEBSOCKET - -enum { FRAME_HEADER, FRAME_OPT, PAYLOAD, CONTROL }; - -enum { BLOCKING_WRITE = 0x80 }; - -typedef struct _mp_obj_websocket_t { - mp_obj_base_t base; - mp_obj_t sock; - uint32_t msg_sz; - byte mask[4]; - byte state; - byte to_recv; - byte mask_pos; - byte buf_pos; - byte buf[6]; - byte opts; - // Copy of last data frame flags - byte ws_flags; - // Copy of current frame flags - byte last_flags; -} mp_obj_websocket_t; - -STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode); - -STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 1, 2, false); - mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); - mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t); - o->base.type = type; - o->sock = args[0]; - o->state = FRAME_HEADER; - o->to_recv = 2; - o->mask_pos = 0; - o->buf_pos = 0; - o->opts = FRAME_TXT; - if (n_args > 1 && args[1] == mp_const_true) { - o->opts |= BLOCKING_WRITE; - } - return MP_OBJ_FROM_PTR(o); -} - -STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { - mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); - const mp_stream_p_t *stream_p = mp_get_stream(self->sock); - while (1) { - if (self->to_recv != 0) { - mp_uint_t out_sz = stream_p->read(self->sock, self->buf + self->buf_pos, self->to_recv, errcode); - if (out_sz == 0 || out_sz == MP_STREAM_ERROR) { - return out_sz; - } - self->buf_pos += out_sz; - self->to_recv -= out_sz; - if (self->to_recv != 0) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - } - - switch (self->state) { - case FRAME_HEADER: { - // TODO: Split frame handling below is untested so far, so conservatively disable it - assert(self->buf[0] & 0x80); - - // "Control frames MAY be injected in the middle of a fragmented message." - // So, they must be processed before data frames (and not alter - // self->ws_flags) - byte frame_type = self->buf[0]; - self->last_flags = frame_type; - frame_type &= FRAME_OPCODE_MASK; - - if ((self->buf[0] & FRAME_OPCODE_MASK) == FRAME_CONT) { - // Preserve previous frame type - self->ws_flags = (self->ws_flags & FRAME_OPCODE_MASK) | (self->buf[0] & ~FRAME_OPCODE_MASK); - } else { - self->ws_flags = self->buf[0]; - } - - // Reset mask in case someone will use "simplified" protocol - // without masks. - memset(self->mask, 0, sizeof(self->mask)); - - int to_recv = 0; - size_t sz = self->buf[1] & 0x7f; - if (sz == 126) { - // Msg size is next 2 bytes - to_recv += 2; - } else if (sz == 127) { - // Msg size is next 8 bytes - assert(0); - } - if (self->buf[1] & 0x80) { - // Next 4 bytes is mask - to_recv += 4; - } - - self->buf_pos = 0; - self->to_recv = to_recv; - self->msg_sz = sz; // May be overridden by FRAME_OPT - if (to_recv != 0) { - self->state = FRAME_OPT; - } else { - if (frame_type >= FRAME_CLOSE) { - self->state = CONTROL; - } else { - self->state = PAYLOAD; - } - } - continue; - } - - case FRAME_OPT: { - if ((self->buf_pos & 3) == 2) { - // First two bytes are message length - self->msg_sz = (self->buf[0] << 8) | self->buf[1]; - } - if (self->buf_pos >= 4) { - // Last 4 bytes is mask - memcpy(self->mask, self->buf + self->buf_pos - 4, 4); - } - self->buf_pos = 0; - if ((self->last_flags & FRAME_OPCODE_MASK) >= FRAME_CLOSE) { - self->state = CONTROL; - } else { - self->state = PAYLOAD; - } - continue; - } - - case PAYLOAD: - case CONTROL: { - mp_uint_t out_sz = 0; - if (self->msg_sz == 0) { - // In case message had zero payload - goto no_payload; - } - - size_t sz = MIN(size, self->msg_sz); - out_sz = stream_p->read(self->sock, buf, sz, errcode); - if (out_sz == 0 || out_sz == MP_STREAM_ERROR) { - return out_sz; - } - - sz = out_sz; - for (byte *p = buf; sz--; p++) { - *p ^= self->mask[self->mask_pos++ & 3]; - } - - self->msg_sz -= out_sz; - if (self->msg_sz == 0) { - byte last_state; - no_payload: - last_state = self->state; - self->state = FRAME_HEADER; - self->to_recv = 2; - self->mask_pos = 0; - self->buf_pos = 0; - - // Handle control frame - if (last_state == CONTROL) { - byte frame_type = self->last_flags & FRAME_OPCODE_MASK; - if (frame_type == FRAME_CLOSE) { - static char close_resp[2] = {0x88, 0}; - int err; - websocket_write(self_in, close_resp, sizeof(close_resp), &err); - return 0; - } - - // DEBUG_printf("Finished receiving ctrl message %x, ignoring\n", self->last_flags); - continue; - } - } - - if (out_sz != 0) { - return out_sz; - } - // Empty (data) frame received is not EOF - continue; - } - - } - } -} - -STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { - mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); - assert(size < 0x10000); - byte header[4] = {0x80 | (self->opts & FRAME_OPCODE_MASK)}; - int hdr_sz; - if (size < 126) { - header[1] = size; - hdr_sz = 2; - } else { - header[1] = 126; - header[2] = size >> 8; - header[3] = size & 0xff; - hdr_sz = 4; - } - - mp_obj_t dest[3]; - if (self->opts & BLOCKING_WRITE) { - mp_load_method(self->sock, MP_QSTR_setblocking, dest); - dest[2] = mp_const_true; - mp_call_method_n_kw(1, 0, dest); - } - - mp_uint_t out_sz = mp_stream_write_exactly(self->sock, header, hdr_sz, errcode); - if (*errcode == 0) { - out_sz = mp_stream_write_exactly(self->sock, buf, size, errcode); - } - - if (self->opts & BLOCKING_WRITE) { - dest[2] = mp_const_false; - mp_call_method_n_kw(1, 0, dest); - } - - if (*errcode != 0) { - return MP_STREAM_ERROR; - } - return out_sz; -} - -STATIC mp_uint_t websocket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { - mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); - switch (request) { - case MP_STREAM_CLOSE: - // TODO: Send close signaling to the other side, otherwise it's - // abrupt close (connection abort). - mp_stream_close(self->sock); - return 0; - case MP_STREAM_GET_DATA_OPTS: - return self->ws_flags & FRAME_OPCODE_MASK; - case MP_STREAM_SET_DATA_OPTS: { - int cur = self->opts & FRAME_OPCODE_MASK; - self->opts = (self->opts & ~FRAME_OPCODE_MASK) | (arg & FRAME_OPCODE_MASK); - return cur; - } - default: - *errcode = MP_EINVAL; - return MP_STREAM_ERROR; - } -} - -STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_stream_ioctl_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table); - -STATIC const mp_stream_p_t websocket_stream_p = { - MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) - .read = websocket_read, - .write = websocket_write, - .ioctl = websocket_ioctl, -}; - -STATIC const mp_obj_type_t websocket_type = { - { &mp_type_type }, - .name = MP_QSTR_websocket, - .make_new = websocket_make_new, - .protocol = &websocket_stream_p, - .locals_dict = (void *)&websocket_locals_dict, -}; - -STATIC const mp_rom_map_elem_t websocket_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_websocket) }, - { MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&websocket_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(websocket_module_globals, websocket_module_globals_table); - -const mp_obj_module_t mp_module_websocket = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&websocket_module_globals, -}; - -#endif // MICROPY_PY_WEBSOCKET diff --git a/extmod/modwebsocket.h b/extmod/modwebsocket.h deleted file mode 100644 index 46aa0408b6..0000000000 --- a/extmod/modwebsocket.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - -#ifndef MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H -#define MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H - -#define FRAME_OPCODE_MASK 0x0f -enum { - FRAME_CONT, FRAME_TXT, FRAME_BIN, - FRAME_CLOSE = 0x8, FRAME_PING, FRAME_PONG -}; - -#endif // MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H diff --git a/extmod/ulab b/extmod/ulab index ef65415b55..e3bf07cabb 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit ef65415b5503ae71cc0a9064197f2e3fa5365d74 +Subproject commit e3bf07cabb728ecfa2b78ea5e468179f94dbf933 diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c index 4668279bc8..57b7de319f 100644 --- a/extmod/uos_dupterm.c +++ b/extmod/uos_dupterm.c @@ -11,6 +11,7 @@ #include "py/objtuple.h" #include "py/objarray.h" #include "py/stream.h" +#include "extmod/misc.h" #include "lib/utils/interrupt_char.h" #include "supervisor/shared/translate.h" @@ -39,6 +40,20 @@ int mp_uos_dupterm_rx_chr(void) { continue; } + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM + if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) { + byte buf[1]; + int errcode = 0; + const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx])); + mp_uint_t out_sz = stream_p->read(MP_STATE_VM(dupterm_objs[idx]), buf, 1, &errcode); + if (errcode == 0 && out_sz != 0) { + return buf[0]; + } else { + continue; + } + } + #endif + nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { byte buf[1]; @@ -79,6 +94,16 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) { if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) { continue; } + + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM + if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) { + int errcode = 0; + const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx])); + stream_p->write(MP_STATE_VM(dupterm_objs[idx]), str, len, &errcode); + continue; + } + #endif + nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_stream_write(MP_STATE_VM(dupterm_objs[idx]), str, len, MP_STREAM_RW_WRITE); diff --git a/extmod/vfs.c b/extmod/vfs.c index cac51289fd..eff41da5a8 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -207,7 +207,7 @@ mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) { mp_vfs_mount_t *vfs = NULL; size_t mnt_len; const char *mnt_str = NULL; - if (MP_OBJ_IS_STR(mnt_in)) { + if (mp_obj_is_str(mnt_in)) { mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len); } for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) { @@ -250,7 +250,7 @@ mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) #if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX // If the file is an integer then delegate straight to the POSIX handler - if (MP_OBJ_IS_SMALL_INT(args[ARG_file].u_obj)) { + if (mp_obj_is_small_int(args[ARG_file].u_obj)) { return mp_vfs_posix_file_open(&mp_type_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); } #endif diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 5da4ecd872..f6645e50a1 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -21,8 +21,8 @@ #include "supervisor/filesystem.h" #include "supervisor/shared/translate.h" -#if _MAX_SS == _MIN_SS -#define SECSIZE(fs) (_MIN_SS) +#if FF_MAX_SS == FF_MIN_SS +#define SECSIZE(fs) (FF_MIN_SS) #else #define SECSIZE(fs) ((fs)->ssize) #endif @@ -84,7 +84,7 @@ STATIC void verify_fs_writable(fs_user_mount_t *vfs) { } } -#if _FS_REENTRANT +#if FF_FS_REENTRANT STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in); // f_umount only needs to be called to release the sync object @@ -99,8 +99,11 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) { fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL)); // make the filesystem - uint8_t working_buf[_MAX_SS]; + uint8_t working_buf[FF_MAX_SS]; FRESULT res = f_mkfs(&vfs->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); + if (res == FR_MKFS_ABORTED) { // Probably doesn't support FAT16 + res = f_mkfs(&vfs->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf)); + } if (res != FR_OK) { mp_raise_OSError(fresult_to_errno_table[res]); } @@ -377,7 +380,7 @@ STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) { t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags - t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax + t->items[9] = MP_OBJ_NEW_SMALL_INT(FF_MAX_LFN); // f_namemax return MP_OBJ_FROM_PTR(t); } @@ -397,7 +400,7 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs // check if we need to make the filesystem FRESULT res = (self->flags & FSUSER_NO_FILESYSTEM) ? FR_NO_FILESYSTEM : FR_OK; if (res == FR_NO_FILESYSTEM && mp_obj_is_true(mkfs)) { - uint8_t working_buf[_MAX_SS]; + uint8_t working_buf[FF_MAX_SS]; res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); } if (res != FR_OK) { @@ -451,7 +454,7 @@ STATIC const mp_obj_property_t fat_vfs_label_obj = { #endif STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { - #if _FS_REENTRANT + #if FF_FS_REENTRANT { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fat_vfs_del_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) }, diff --git a/extmod/vfs_fat_diskio.c b/extmod/vfs_fat_diskio.c index b3054ef2c6..c656984a67 100644 --- a/extmod/vfs_fat_diskio.c +++ b/extmod/vfs_fat_diskio.c @@ -18,8 +18,8 @@ #include "lib/oofatfs/diskio.h" #include "extmod/vfs_fat.h" -#if _MAX_SS == _MIN_SS -#define SECSIZE(fs) (_MIN_SS) +#if FF_MAX_SS == FF_MIN_SS +#define SECSIZE(fs) (FF_MIN_SS) #else #define SECSIZE(fs) ((fs)->ssize) #endif @@ -34,7 +34,7 @@ STATIC fs_user_mount_t *disk_get_device(void *bdev) { /*-----------------------------------------------------------------------*/ DRESULT disk_read( - bdev_t pdrv, /* Physical drive */ + bdev_t pdrv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ UINT count /* Number of sectors to read (1..128) */ @@ -74,7 +74,7 @@ DRESULT disk_read( /*-----------------------------------------------------------------------*/ DRESULT disk_write( - bdev_t pdrv, /* Physical drive */ + bdev_t pdrv, /* Physical drive nmuber (0..) */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address (LBA) */ UINT count /* Number of sectors to write (1..128) */ @@ -120,8 +120,8 @@ DRESULT disk_write( /*-----------------------------------------------------------------------*/ DRESULT disk_ioctl( - bdev_t pdrv, /* Physical drive */ - BYTE cmd, /* Control code */ + bdev_t pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { fs_user_mount_t *vfs = disk_get_device(pdrv); @@ -198,7 +198,7 @@ DRESULT disk_ioctl( } else { *((WORD *)buff) = out_value; } - #if _MAX_SS != _MIN_SS + #if FF_MAX_SS != FF_MIN_SS // need to store ssize because we use it in disk_read/disk_write vfs->fatfs.ssize = *((WORD *)buff); #endif diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index ff2ed04715..73f4a1d874 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -110,7 +110,7 @@ STATIC mp_obj_t vfs_posix_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode && (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL || strchr(mode, '+') != NULL)) { mp_raise_OSError(MP_EROFS); } - if (!MP_OBJ_IS_SMALL_INT(path_in)) { + if (!mp_obj_is_small_int(path_in)) { path_in = vfs_posix_get_path_obj(self, path_in); } return mp_vfs_posix_file_open(&mp_type_textio, path_in, mode_in); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index bc45a2cf2e..cf638cd239 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -74,7 +74,7 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ mp_obj_t fid = file_in; - if (MP_OBJ_IS_SMALL_INT(fid)) { + if (mp_obj_is_small_int(fid)) { o->fd = MP_OBJ_SMALL_INT_VALUE(fid); return MP_OBJ_FROM_PTR(o); } diff --git a/lib/netutils/netutils.h b/lib/netutils/netutils.h index 98e1d24932..b23a78e5b8 100644 --- a/lib/netutils/netutils.h +++ b/lib/netutils/netutils.h @@ -29,6 +29,10 @@ #define NETUTILS_IPV4ADDR_BUFSIZE 4 +#define NETUTILS_TRACE_IS_TX (0x0001) +#define NETUTILS_TRACE_PAYLOAD (0x0002) +#define NETUTILS_TRACE_NEWLINE (0x0004) + typedef enum _netutils_endian_t { NETUTILS_LITTLE, NETUTILS_BIG, @@ -47,4 +51,6 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian // puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes). mp_uint_t netutils_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian_t endian); +void netutils_ethernet_trace(const mp_print_t *print, size_t len, const uint8_t *buf, unsigned int flags); + #endif // MICROPY_INCLUDED_LIB_NETUTILS_NETUTILS_H diff --git a/lib/netutils/trace.c b/lib/netutils/trace.c new file mode 100644 index 0000000000..1610966c2d --- /dev/null +++ b/lib/netutils/trace.c @@ -0,0 +1,170 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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 "py/mphal.h" +#include "lib/netutils/netutils.h" + +static uint32_t get_be16(const uint8_t *buf) { + return buf[0] << 8 | buf[1]; +} + +static uint32_t get_be32(const uint8_t *buf) { + return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; +} + +static void dump_hex_bytes(const mp_print_t *print, size_t len, const uint8_t *buf) { + for (size_t i = 0; i < len; ++i) { + mp_printf(print, " %02x", buf[i]); + } +} + +static const char *ethertype_str(uint16_t type) { + // A value between 0x0000 - 0x05dc (inclusive) indicates a length, not type + switch (type) { + case 0x0800: + return "IPv4"; + case 0x0806: + return "ARP"; + case 0x86dd: + return "IPv6"; + default: + return NULL; + } +} + +void netutils_ethernet_trace(const mp_print_t *print, size_t len, const uint8_t *buf, unsigned int flags) { + mp_printf(print, "[% 8d] ETH%cX len=%u", mp_hal_ticks_ms(), flags & NETUTILS_TRACE_IS_TX ? 'T' : 'R', len); + mp_printf(print, " dst=%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + mp_printf(print, " src=%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); + + const char *ethertype = ethertype_str(buf[12] << 8 | buf[13]); + if (ethertype) { + mp_printf(print, " type=%s", ethertype); + } else { + mp_printf(print, " type=0x%04x", buf[12] << 8 | buf[13]); + } + if (len > 14) { + len -= 14; + buf += 14; + if (buf[-2] == 0x08 && buf[-1] == 0x00 && buf[0] == 0x45) { + // IPv4 packet + len = get_be16(buf + 2); + mp_printf(print, " srcip=%u.%u.%u.%u dstip=%u.%u.%u.%u", + buf[12], buf[13], buf[14], buf[15], + buf[16], buf[17], buf[18], buf[19]); + uint8_t prot = buf[9]; + buf += 20; + len -= 20; + if (prot == 6) { + // TCP packet + uint16_t srcport = get_be16(buf); + uint16_t dstport = get_be16(buf + 2); + uint32_t seqnum = get_be32(buf + 4); + uint32_t acknum = get_be32(buf + 8); + uint16_t dataoff_flags = get_be16(buf + 12); + uint16_t winsz = get_be16(buf + 14); + mp_printf(print, " TCP srcport=%u dstport=%u seqnum=%u acknum=%u dataoff=%u flags=%x winsz=%u", + srcport, dstport, (unsigned)seqnum, (unsigned)acknum, dataoff_flags >> 12, dataoff_flags & 0x1ff, winsz); + buf += 20; + len -= 20; + if (dataoff_flags >> 12 > 5) { + mp_printf(print, " opts="); + size_t opts_len = ((dataoff_flags >> 12) - 5) * 4; + dump_hex_bytes(print, opts_len, buf); + buf += opts_len; + len -= opts_len; + } + } else if (prot == 17) { + // UDP packet + uint16_t srcport = get_be16(buf); + uint16_t dstport = get_be16(buf + 2); + mp_printf(print, " UDP srcport=%u dstport=%u", srcport, dstport); + len = get_be16(buf + 4); + buf += 8; + if ((srcport == 67 && dstport == 68) || (srcport == 68 && dstport == 67)) { + // DHCP + if (srcport == 67) { + mp_printf(print, " DHCPS"); + } else { + mp_printf(print, " DHCPC"); + } + dump_hex_bytes(print, 12 + 16 + 16 + 64, buf); + size_t n = 12 + 16 + 16 + 64 + 128; + len -= n; + buf += n; + mp_printf(print, " opts:"); + switch (buf[6]) { + case 1: + mp_printf(print, " DISCOVER"); + break; + case 2: + mp_printf(print, " OFFER"); + break; + case 3: + mp_printf(print, " REQUEST"); + break; + case 4: + mp_printf(print, " DECLINE"); + break; + case 5: + mp_printf(print, " ACK"); + break; + case 6: + mp_printf(print, " NACK"); + break; + case 7: + mp_printf(print, " RELEASE"); + break; + case 8: + mp_printf(print, " INFORM"); + break; + } + } + } else { + // Non-UDP packet + mp_printf(print, " prot=%u", prot); + } + } else if (buf[-2] == 0x86 && buf[-1] == 0xdd && (buf[0] >> 4) == 6) { + // IPv6 packet + uint32_t h = get_be32(buf); + uint16_t l = get_be16(buf + 4); + mp_printf(print, " tclass=%u flow=%u len=%u nexthdr=%u hoplimit=%u", (unsigned)((h >> 20) & 0xff), (unsigned)(h & 0xfffff), l, buf[6], buf[7]); + mp_printf(print, " srcip="); + dump_hex_bytes(print, 16, buf + 8); + mp_printf(print, " dstip="); + dump_hex_bytes(print, 16, buf + 24); + buf += 40; + len -= 40; + } + if (flags & NETUTILS_TRACE_PAYLOAD) { + mp_printf(print, " data="); + dump_hex_bytes(print, len, buf); + } + } + if (flags & NETUTILS_TRACE_NEWLINE) { + mp_printf(print, "\n"); + } +} diff --git a/lib/oofatfs/diskio.h b/lib/oofatfs/diskio.h index 8deb68ecea..d886bdd9cc 100644 --- a/lib/oofatfs/diskio.h +++ b/lib/oofatfs/diskio.h @@ -13,8 +13,6 @@ extern "C" { #endif - - /* Status of Disk Functions */ typedef BYTE DSTATUS; @@ -47,11 +45,11 @@ DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff); /* Command code for disk_ioctrl fucntion */ /* Generic command (Used by FatFs) */ -#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ -#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ -#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ -#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ -#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ +#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ +#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ +#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ #define IOCTL_INIT 5 #define IOCTL_STATUS 6 diff --git a/lib/oofatfs/ff.c b/lib/oofatfs/ff.c index e961c789d8..06743947e0 100644 --- a/lib/oofatfs/ff.c +++ b/lib/oofatfs/ff.c @@ -3,15 +3,15 @@ */ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT file system module R0.12b / +/ FatFs - Generic FAT Filesystem Module R0.13c / /-----------------------------------------------------------------------------/ / -/ Copyright (C) 2016, ChaN, all right reserved. +/ Copyright (C) 2018, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided / that the following condition is met: - +/ / 1. Redistributions of source code must retain the above copyright notice, / this condition and the following disclaimer. / @@ -19,6 +19,7 @@ / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. +/ /----------------------------------------------------------------------------*/ @@ -36,343 +37,43 @@ ---------------------------------------------------------------------------*/ -#if _FATFS != 68020 /* Revision ID */ +#if FF_DEFINED != 86604 /* Revision ID */ #error Wrong include file (ff.h). #endif -#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } - - -/* Reentrancy related */ -#if _FS_REENTRANT -#if _USE_LFN == 1 -#error Static LFN work area cannot be used at thread-safe configuration -#endif -#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } -#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } -#else -#define ENTER_FF(fs) -#define LEAVE_FF(fs, res) return res -#endif - - - -/* Definitions of sector size */ -#if (_MAX_SS < _MIN_SS) || (_MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096) || (_MIN_SS != 512 && _MIN_SS != 1024 && _MIN_SS != 2048 && _MIN_SS != 4096) -#error Wrong sector size configuration -#endif -#if _MAX_SS == _MIN_SS -#define SS(fs) ((UINT)_MAX_SS) /* Fixed sector size */ -#else -#define SS(fs) ((fs)->ssize) /* Variable sector size */ -#endif - - -/* Timestamp */ -#if _FS_NORTC == 1 -#if _NORTC_YEAR < 1980 || _NORTC_YEAR > 2107 || _NORTC_MON < 1 || _NORTC_MON > 12 || _NORTC_MDAY < 1 || _NORTC_MDAY > 31 -#error Invalid _FS_NORTC settings -#endif -#define GET_FATTIME() ((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16) -#else -#define GET_FATTIME() get_fattime() -#endif - - -/* File lock controls */ -#if _FS_LOCK != 0 -#if _FS_READONLY -#error _FS_LOCK must be 0 at read-only configuration -#endif -typedef struct { - FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ - DWORD clu; /* Object ID 2, directory (0:root) */ - DWORD ofs; /* Object ID 3, directory offset */ - WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ -} FILESEM; -#endif - - - -/* DBCS code ranges and SBCS upper conversion tables */ - -#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ -#define _DF1S 0x81 /* DBC 1st byte range 1 start */ -#define _DF1E 0x9F /* DBC 1st byte range 1 end */ -#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ -#define _DF2E 0xFC /* DBC 1st byte range 2 end */ -#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ -#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ -#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ -#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ - -#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ -#define _DF1S 0x81 -#define _DF1E 0xFE -#define _DS1S 0x40 -#define _DS1E 0x7E -#define _DS2S 0x80 -#define _DS2E 0xFE - -#elif _CODE_PAGE == 949 /* Korean */ -#define _DF1S 0x81 -#define _DF1E 0xFE -#define _DS1S 0x41 -#define _DS1E 0x5A -#define _DS2S 0x61 -#define _DS2E 0x7A -#define _DS3S 0x81 -#define _DS3E 0xFE - -#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ -#define _DF1S 0x81 -#define _DF1E 0xFE -#define _DS1S 0x40 -#define _DS1E 0x7E -#define _DS2S 0xA1 -#define _DS2E 0xFE - -#elif _CODE_PAGE == 437 /* U.S. */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 720 /* Arabic */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 737 /* Greek */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ - 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 771 /* KBL */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF} - -#elif _CODE_PAGE == 775 /* Baltic */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ - 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 850 /* Latin 1 */ -#define _DF1S 0 -#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \ - 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \ - 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 852 /* Latin 2 */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \ - 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} - -#elif _CODE_PAGE == 855 /* Cyrillic */ -#define _DF1S 0 -#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \ - 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ - 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ - 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \ - 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 857 /* Turkish */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ - 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 860 /* Portuguese */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \ - 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 861 /* Icelandic */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ - 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 862 /* Hebrew */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 863 /* Canadian-French */ -#define _DF1S 0 -#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \ - 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \ - 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 864 /* Arabic */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 865 /* Nordic */ -#define _DF1S 0 -#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ - 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ - 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 866 /* Russian */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ - 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} - -#elif _CODE_PAGE == 869 /* Greek 2 */ -#define _DF1S 0 -#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \ - 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ - 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ - 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ - 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \ - 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \ - 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF} - -#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ -#if _USE_LFN != 0 -#error Cannot enable LFN without valid code page. -#endif -#define _DF1S 0 - -#else -#error Unknown code page - -#endif +/* Limits and boundaries */ +#define MAX_DIR 0x200000 /* Max size of FAT directory */ +#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ +#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ +#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ /* Character code support macros */ -#define IsUpper(c) (((c)>='A')&&((c)<='Z')) -#define IsLower(c) (((c)>='a')&&((c)<='z')) -#define IsDigit(c) (((c)>='0')&&((c)<='9')) - -#if _DF1S != 0 /* Code page is DBCS */ - -#ifdef _DF2S /* Two 1st byte areas */ -#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) -#else /* One 1st byte area */ -#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) -#endif - -#ifdef _DS3S /* Three 2nd byte areas */ -#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) -#else /* Two 2nd byte areas */ -#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) -#endif - -#else /* Code page is SBCS */ - -#define IsDBCS1(c) 0 -#define IsDBCS2(c) 0 - -#endif /* _DF1S */ +#define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') +#define IsLower(c) ((c) >= 'a' && (c) <= 'z') +#define IsDigit(c) ((c) >= '0' && (c) <= '9') +#define IsSurrogate(c) ((c) >= 0xD800 && (c) <= 0xDFFF) +#define IsSurrogateH(c) ((c) >= 0xD800 && (c) <= 0xDBFF) +#define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) -/* File attribute bits (internal use) */ -#define AM_VOL 0x08 /* Volume label */ -#define AM_LFN 0x0F /* LFN entry */ -#define AM_MASK 0x3F /* Mask of defined bits */ - - -/* File access control and file status flags (internal use) */ +/* Additional file access control and file status flags for internal use */ #define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ #define FA_MODIFIED 0x40 /* File has been modified */ #define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ -/* Name status flags */ -#define NSFLAG 11 /* Index of name status byte in fn[] */ +/* Additional file attribute bits for internal use */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Name status flags in fn[11] */ +#define NSFLAG 11 /* Index of the name status byte */ #define NS_LOSS 0x01 /* Out of 8.3 format */ #define NS_LFN 0x02 /* Force to create LFN entry */ #define NS_LAST 0x04 /* Last segment */ @@ -383,18 +84,17 @@ typedef struct { #define NS_NONAME 0x80 /* Not followed */ -/* Limits and boundaries (differ from specs but correct for real DOS/Windows) */ -#define MAX_FAT12 0xFF5 /* Maximum number of FAT12 clusters */ -#define MAX_FAT16 0xFFF5 /* Maximum number of FAT16 clusters */ -#define MAX_FAT32 0xFFFFFF5 /* Maximum number of FAT32 clusters */ -#define MAX_EXFAT 0x7FFFFFFD /* Maximum number of exFAT clusters (limited by implementation) */ -#define MAX_DIR 0x200000 /* Maximum size of FAT directory */ -#define MAX_DIR_EX 0x10000000 /* Maximum size of exFAT directory */ +/* exFAT directory entry types */ +#define ET_BITMAP 0x81 /* Allocation bitmap */ +#define ET_UPCASE 0x82 /* Up-case table */ +#define ET_VLABEL 0x83 /* Volume label */ +#define ET_FILEDIR 0x85 /* File and directory */ +#define ET_STREAM 0xC0 /* Stream extension */ +#define ET_FILENAME 0xC1 /* Name extension */ -/* FatFs refers the members in the FAT structures as byte array instead of -/ structure members because the structure is not binary compatible between -/ different platforms */ +/* FatFs refers the FAT structure as simple byte array instead of structure member +/ because the C structure is not binary compatible between different platforms */ #define BS_JmpBoot 0 /* x86 jump instruction (3-byte) */ #define BS_OEMName 3 /* OEM name (8-byte) */ @@ -402,26 +102,26 @@ typedef struct { #define BPB_SecPerClus 13 /* Cluster size [sector] (BYTE) */ #define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (WORD) */ #define BPB_NumFATs 16 /* Number of FATs (BYTE) */ -#define BPB_RootEntCnt 17 /* Size of root directory area for FAT12/16 [entry] (WORD) */ +#define BPB_RootEntCnt 17 /* Size of root directory area for FAT [entry] (WORD) */ #define BPB_TotSec16 19 /* Volume size (16-bit) [sector] (WORD) */ #define BPB_Media 21 /* Media descriptor byte (BYTE) */ #define BPB_FATSz16 22 /* FAT size (16-bit) [sector] (WORD) */ -#define BPB_SecPerTrk 24 /* Track size for int13h [sector] (WORD) */ +#define BPB_SecPerTrk 24 /* Number of sectors per track for int13h [sector] (WORD) */ #define BPB_NumHeads 26 /* Number of heads for int13h (WORD) */ #define BPB_HiddSec 28 /* Volume offset from top of the drive (DWORD) */ #define BPB_TotSec32 32 /* Volume size (32-bit) [sector] (DWORD) */ #define BS_DrvNum 36 /* Physical drive number for int13h (BYTE) */ -#define BS_NTres 37 /* Error flag (BYTE) */ +#define BS_NTres 37 /* WindowsNT error flag (BYTE) */ #define BS_BootSig 38 /* Extended boot signature (BYTE) */ #define BS_VolID 39 /* Volume serial number (DWORD) */ #define BS_VolLab 43 /* Volume label string (8-byte) */ -#define BS_FilSysType 54 /* File system type string (8-byte) */ +#define BS_FilSysType 54 /* Filesystem type string (8-byte) */ #define BS_BootCode 62 /* Boot code (448-byte) */ #define BS_55AA 510 /* Signature word (WORD) */ #define BPB_FATSz32 36 /* FAT32: FAT size [sector] (DWORD) */ #define BPB_ExtFlags32 40 /* FAT32: Extended flags (WORD) */ -#define BPB_FSVer32 42 /* FAT32: File system version (WORD) */ +#define BPB_FSVer32 42 /* FAT32: Filesystem version (WORD) */ #define BPB_RootClus32 44 /* FAT32: Root directory cluster (DWORD) */ #define BPB_FSInfo32 48 /* FAT32: Offset of FSINFO sector (WORD) */ #define BPB_BkBootSec32 50 /* FAT32: Offset of backup boot sector (WORD) */ @@ -430,7 +130,7 @@ typedef struct { #define BS_BootSig32 66 /* FAT32: Extended boot signature (BYTE) */ #define BS_VolID32 67 /* FAT32: Volume serial number (DWORD) */ #define BS_VolLab32 71 /* FAT32: Volume label string (8-byte) */ -#define BS_FilSysType32 82 /* FAT32: File system type string (8-byte) */ +#define BS_FilSysType32 82 /* FAT32: Filesystem type string (8-byte) */ #define BS_BootCode32 90 /* FAT32: Boot code (420-byte) */ #define BPB_ZeroedEx 11 /* exFAT: MBZ field (53-byte) */ @@ -440,19 +140,60 @@ typedef struct { #define BPB_FatSzEx 84 /* exFAT: FAT size [sector] (DWORD) */ #define BPB_DataOfsEx 88 /* exFAT: Data offset from top of the volume [sector] (DWORD) */ #define BPB_NumClusEx 92 /* exFAT: Number of clusters (DWORD) */ -#define BPB_RootClusEx 96 /* exFAT: Root directory cluster (DWORD) */ +#define BPB_RootClusEx 96 /* exFAT: Root directory start cluster (DWORD) */ #define BPB_VolIDEx 100 /* exFAT: Volume serial number (DWORD) */ -#define BPB_FSVerEx 104 /* exFAT: File system version (WORD) */ -#define BPB_VolFlagEx 106 /* exFAT: Volume flags (BYTE) */ -#define BPB_ActFatEx 107 /* exFAT: Active FAT flags (BYTE) */ -#define BPB_BytsPerSecEx 108 /* exFAT: Log2 of sector size in byte (BYTE) */ -#define BPB_SecPerClusEx 109 /* exFAT: Log2 of cluster size in sector (BYTE) */ +#define BPB_FSVerEx 104 /* exFAT: Filesystem version (WORD) */ +#define BPB_VolFlagEx 106 /* exFAT: Volume flags (WORD) */ +#define BPB_BytsPerSecEx 108 /* exFAT: Log2 of sector size in unit of byte (BYTE) */ +#define BPB_SecPerClusEx 109 /* exFAT: Log2 of cluster size in unit of sector (BYTE) */ #define BPB_NumFATsEx 110 /* exFAT: Number of FATs (BYTE) */ #define BPB_DrvNumEx 111 /* exFAT: Physical drive number for int13h (BYTE) */ #define BPB_PercInUseEx 112 /* exFAT: Percent in use (BYTE) */ #define BPB_RsvdEx 113 /* exFAT: Reserved (7-byte) */ #define BS_BootCodeEx 120 /* exFAT: Boot code (390-byte) */ +#define DIR_Name 0 /* Short file name (11-byte) */ +#define DIR_Attr 11 /* Attribute (BYTE) */ +#define DIR_NTres 12 /* Lower case flag (BYTE) */ +#define DIR_CrtTime10 13 /* Created time sub-second (BYTE) */ +#define DIR_CrtTime 14 /* Created time (DWORD) */ +#define DIR_LstAccDate 18 /* Last accessed date (WORD) */ +#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (WORD) */ +#define DIR_ModTime 22 /* Modified time (DWORD) */ +#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (WORD) */ +#define DIR_FileSize 28 /* File size (DWORD) */ +#define LDIR_Ord 0 /* LFN: LFN order and LLE flag (BYTE) */ +#define LDIR_Attr 11 /* LFN: LFN attribute (BYTE) */ +#define LDIR_Type 12 /* LFN: Entry type (BYTE) */ +#define LDIR_Chksum 13 /* LFN: Checksum of the SFN (BYTE) */ +#define LDIR_FstClusLO 26 /* LFN: MBZ field (WORD) */ +#define XDIR_Type 0 /* exFAT: Type of exFAT directory entry (BYTE) */ +#define XDIR_NumLabel 1 /* exFAT: Number of volume label characters (BYTE) */ +#define XDIR_Label 2 /* exFAT: Volume label (11-WORD) */ +#define XDIR_CaseSum 4 /* exFAT: Sum of case conversion table (DWORD) */ +#define XDIR_NumSec 1 /* exFAT: Number of secondary entries (BYTE) */ +#define XDIR_SetSum 2 /* exFAT: Sum of the set of directory entries (WORD) */ +#define XDIR_Attr 4 /* exFAT: File attribute (WORD) */ +#define XDIR_CrtTime 8 /* exFAT: Created time (DWORD) */ +#define XDIR_ModTime 12 /* exFAT: Modified time (DWORD) */ +#define XDIR_AccTime 16 /* exFAT: Last accessed time (DWORD) */ +#define XDIR_CrtTime10 20 /* exFAT: Created time subsecond (BYTE) */ +#define XDIR_ModTime10 21 /* exFAT: Modified time subsecond (BYTE) */ +#define XDIR_CrtTZ 22 /* exFAT: Created timezone (BYTE) */ +#define XDIR_ModTZ 23 /* exFAT: Modified timezone (BYTE) */ +#define XDIR_AccTZ 24 /* exFAT: Last accessed timezone (BYTE) */ +#define XDIR_GenFlags 33 /* exFAT: General secondary flags (BYTE) */ +#define XDIR_NumName 35 /* exFAT: Number of file name characters (BYTE) */ +#define XDIR_NameHash 36 /* exFAT: Hash of file name (WORD) */ +#define XDIR_ValidFileSize 40 /* exFAT: Valid file size (QWORD) */ +#define XDIR_FstClus 52 /* exFAT: First cluster of the file data (DWORD) */ +#define XDIR_FileSize 56 /* exFAT: File/Directory size (QWORD) */ + +#define SZDIRE 32 /* Size of a directory entry */ +#define DDEM 0xE5 /* Deleted directory entry mark set to DIR_Name[0] */ +#define RDDEM 0x05 /* Replacement of the character collides with DDEM */ +#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ + #define FSI_LeadSig 0 /* FAT32 FSI: Leading signature (DWORD) */ #define FSI_StrucSig 484 /* FAT32 FSI: Structure signature (DWORD) */ #define FSI_Free_Count 488 /* FAT32 FSI: Number of free clusters (DWORD) */ @@ -471,49 +212,216 @@ typedef struct { #define PTE_StLba 8 /* MBR PTE: Start in LBA */ #define PTE_SizLba 12 /* MBR PTE: Size in LBA */ -#define DIR_Name 0 /* Short file name (11-byte) */ -#define DIR_Attr 11 /* Attribute (BYTE) */ -#define DIR_NTres 12 /* Lower case flag (BYTE) */ -#define DIR_CrtTime10 13 /* Created time sub-second (BYTE) */ -#define DIR_CrtTime 14 /* Created time (DWORD) */ -#define DIR_LstAccDate 18 /* Last accessed date (WORD) */ -#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (WORD) */ -#define DIR_ModTime 22 /* Modified time (DWORD) */ -#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (WORD) */ -#define DIR_FileSize 28 /* File size (DWORD) */ -#define LDIR_Ord 0 /* LFN entry order and LLE flag (BYTE) */ -#define LDIR_Attr 11 /* LFN attribute (BYTE) */ -#define LDIR_Type 12 /* LFN type (BYTE) */ -#define LDIR_Chksum 13 /* Checksum of the SFN entry (BYTE) */ -#define LDIR_FstClusLO 26 /* Must be zero (WORD) */ -#define XDIR_Type 0 /* Type of exFAT directory entry (BYTE) */ -#define XDIR_NumLabel 1 /* Number of volume label characters (BYTE) */ -#define XDIR_Label 2 /* Volume label (11-WORD) */ -#define XDIR_CaseSum 4 /* Sum of case conversion table (DWORD) */ -#define XDIR_NumSec 1 /* Number of secondary entries (BYTE) */ -#define XDIR_SetSum 2 /* Sum of the set of directory entries (WORD) */ -#define XDIR_Attr 4 /* File attribute (WORD) */ -#define XDIR_CrtTime 8 /* Created time (DWORD) */ -#define XDIR_ModTime 12 /* Modified time (DWORD) */ -#define XDIR_AccTime 16 /* Last accessed time (DWORD) */ -#define XDIR_CrtTime10 20 /* Created time subsecond (BYTE) */ -#define XDIR_ModTime10 21 /* Modified time subsecond (BYTE) */ -#define XDIR_CrtTZ 22 /* Created timezone (BYTE) */ -#define XDIR_ModTZ 23 /* Modified timezone (BYTE) */ -#define XDIR_AccTZ 24 /* Last accessed timezone (BYTE) */ -#define XDIR_GenFlags 33 /* Gneral secondary flags (WORD) */ -#define XDIR_NumName 35 /* Number of file name characters (BYTE) */ -#define XDIR_NameHash 36 /* Hash of file name (WORD) */ -#define XDIR_ValidFileSize 40 /* Valid file size (QWORD) */ -#define XDIR_FstClus 52 /* First cluster of the file data (DWORD) */ -#define XDIR_FileSize 56 /* File/Directory size (QWORD) */ -#define SZDIRE 32 /* Size of a directory entry */ -#define LLEF 0x40 /* Last long entry flag in LDIR_Ord */ -#define DDEM 0xE5 /* Deleted directory entry mark set to DIR_Name[0] */ -#define RDDEM 0x05 /* Replacement of the character collides with DDEM */ +/* Post process on fatal error in the file operations */ +#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } +/* Re-entrancy related */ +#if FF_FS_REENTRANT +#if FF_USE_LFN == 1 +#error Static LFN work area cannot be used at thread-safe configuration +#endif +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } +#else +#define LEAVE_FF(fs, res) return res +#endif + + +/* Definitions of volume - physical location conversion */ +#if FF_MULTI_PARTITION +#define LD2PT(fs) (fs->part) /* Get partition index */ +#else +#define LD2PT(fs) 0 /* Find first valid partition or in SFD */ +#endif + + +/* Definitions of sector size */ +#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096) +#error Wrong sector size configuration +#endif +#if FF_MAX_SS == FF_MIN_SS +#define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */ +#else +#define SS(fs) ((fs)->ssize) /* Variable sector size */ +#endif + + +/* Timestamp */ +#if FF_FS_NORTC == 1 +#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31 +#error Invalid FF_FS_NORTC settings +#endif +#define GET_FATTIME() ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16) +#else +#define GET_FATTIME() get_fattime() +#endif + + +/* File lock controls */ +#if FF_FS_LOCK != 0 +#if FF_FS_READONLY +#error FF_FS_LOCK must be 0 at read-only configuration +#endif +typedef struct { + FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ + DWORD clu; /* Object ID 2, containing directory (0:root) */ + DWORD ofs; /* Object ID 3, offset in the directory */ + WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ +} FILESEM; +#endif + + +/* SBCS up-case tables (\x80-\xFF) */ +#define TBL_CT437 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT720 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT737 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT771 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF} +#define TBL_CT775 {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT850 {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \ + 0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \ + 0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT852 {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} +#define TBL_CT855 {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \ + 0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \ + 0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT857 {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT860 {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \ + 0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x86,0x8B,0x9F,0x96,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT861 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA4,0xA5,0xA6,0xA7,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT862 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT863 {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \ + 0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \ + 0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT864 {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT865 {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \ + 0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \ + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT866 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} +#define TBL_CT869 {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \ + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x86,0x9C,0x8D,0x8F,0x90, \ + 0x91,0x90,0x92,0x95,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \ + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \ + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \ + 0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \ + 0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF} + + +/* DBCS code range |----- 1st byte -----| |----------- 2nd byte -----------| */ +#define TBL_DC932 {0x81, 0x9F, 0xE0, 0xFC, 0x40, 0x7E, 0x80, 0xFC, 0x00, 0x00} +#define TBL_DC936 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0x80, 0xFE, 0x00, 0x00} +#define TBL_DC949 {0x81, 0xFE, 0x00, 0x00, 0x41, 0x5A, 0x61, 0x7A, 0x81, 0xFE} +#define TBL_DC950 {0x81, 0xFE, 0x00, 0x00, 0x40, 0x7E, 0xA1, 0xFE, 0x00, 0x00} + + +/* Macros for table definitions */ +#define MERGE_2STR(a, b) a ## b +#define MKCVTBL(hd, cp) MERGE_2STR(hd, cp) + @@ -522,71 +430,140 @@ typedef struct { Module Private Work Area ---------------------------------------------------------------------------*/ - -/* Remark: Variables here without initial value shall be guaranteed zero/null -/ at start-up. If not, either the linker or start-up routine being used is +/* Remark: Variables defined here without initial value shall be guaranteed +/ zero/null at start-up. If not, the linker option or start-up routine is / not compliance with C standard. */ -#if _VOLUMES < 1 || _VOLUMES > 9 -#error Wrong _VOLUMES setting -#endif -static WORD Fsid; /* File system mount ID */ +/*--------------------------------*/ +/* File/Volume controls */ +/*--------------------------------*/ -#if _FS_LOCK != 0 -static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ +#if FF_VOLUMES < 1 || FF_VOLUMES > 10 +#error Wrong FF_VOLUMES setting +#endif +static WORD Fsid; /* Filesystem mount ID */ + +#if FF_FS_LOCK != 0 +static FILESEM Files[FF_FS_LOCK]; /* Open object lock semaphores */ #endif -#if _USE_LFN == 0 /* Non-LFN configuration */ +#if FF_STR_VOLUME_ID +#ifdef FF_VOLUME_STRS +static const char* const VolumeStr[FF_VOLUMES] = {FF_VOLUME_STRS}; /* Pre-defined volume ID */ +#endif +#endif + + +/*--------------------------------*/ +/* LFN/Directory working buffer */ +/*--------------------------------*/ + +#if FF_USE_LFN == 0 /* Non-LFN configuration */ +#if FF_FS_EXFAT +#error LFN must be enabled when enable exFAT +#endif #define DEF_NAMBUF #define INIT_NAMBUF(fs) #define FREE_NAMBUF() -#else -#if _MAX_LFN < 12 || _MAX_LFN > 255 -#error Wrong _MAX_LFN setting -#endif +#define LEAVE_MKFS(res) return res -#if _USE_LFN == 1 /* LFN enabled with static working buffer */ -#if _FS_EXFAT -static BYTE DirBuf[SZDIRE*19]; /* Directory entry block scratchpad buffer (19 entries in size) */ +#else /* LFN configurations */ +#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255 +#error Wrong setting of FF_MAX_LFN #endif -static WCHAR LfnBuf[_MAX_LFN+1]; /* LFN enabled with static working buffer */ +#if FF_LFN_BUF < FF_SFN_BUF || FF_SFN_BUF < 12 +#error Wrong setting of FF_LFN_BUF or FF_SFN_BUF +#endif +#if FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3 +#error Wrong setting of FF_LFN_UNICODE +#endif +static const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* FAT: Offset of LFN characters in the directory entry */ +#define MAXDIRB(nc) ((nc + 44U) / 15 * SZDIRE) /* exFAT: Size of directory entry block scratchpad buffer needed for the name length */ + +#if FF_USE_LFN == 1 /* LFN enabled with static working buffer */ +#if FF_FS_EXFAT +static BYTE DirBuf[MAXDIRB(FF_MAX_LFN)]; /* Directory entry block scratchpad buffer */ +#endif +static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ #define DEF_NAMBUF #define INIT_NAMBUF(fs) #define FREE_NAMBUF() +#define LEAVE_MKFS(res) return res -#elif _USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */ -#if _FS_EXFAT -#define DEF_NAMBUF WCHAR lbuf[_MAX_LFN+1]; BYTE dbuf[SZDIRE*19]; +#elif FF_USE_LFN == 2 /* LFN enabled with dynamic working buffer on the stack */ +#if FF_FS_EXFAT +#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; BYTE dbuf[MAXDIRB(FF_MAX_LFN)]; /* LFN working buffer and directory entry block scratchpad buffer */ #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; (fs)->dirbuf = dbuf; } #define FREE_NAMBUF() #else -#define DEF_NAMBUF WCHAR lbuf[_MAX_LFN+1]; +#define DEF_NAMBUF WCHAR lbuf[FF_MAX_LFN+1]; /* LFN working buffer */ #define INIT_NAMBUF(fs) { (fs)->lfnbuf = lbuf; } #define FREE_NAMBUF() #endif +#define LEAVE_MKFS(res) return res -#elif _USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */ -#if _FS_EXFAT -#define DEF_NAMBUF WCHAR *lfn; -#define INIT_NAMBUF(fs) { lfn = ff_memalloc((_MAX_LFN+1)*2 + SZDIRE*19); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+_MAX_LFN+1); } +#elif FF_USE_LFN == 3 /* LFN enabled with dynamic working buffer on the heap */ +#if FF_FS_EXFAT +#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer and directory entry block scratchpad buffer */ +#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2 + MAXDIRB(FF_MAX_LFN)); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; (fs)->dirbuf = (BYTE*)(lfn+FF_MAX_LFN+1); } #define FREE_NAMBUF() ff_memfree(lfn) #else -#define DEF_NAMBUF WCHAR *lfn; -#define INIT_NAMBUF(fs) { lfn = ff_memalloc((_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; } +#define DEF_NAMBUF WCHAR *lfn; /* Pointer to LFN working buffer */ +#define INIT_NAMBUF(fs) { lfn = ff_memalloc((FF_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; } #define FREE_NAMBUF() ff_memfree(lfn) #endif +#define LEAVE_MKFS(res) { if (!work) ff_memfree(buf); return res; } +#define MAX_MALLOC 0x8000 /* Must be >=FF_MAX_SS */ #else -#error Wrong _USE_LFN setting -#endif -#endif +#error Wrong setting of FF_USE_LFN -#ifdef _EXCVT -static const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for SBCS extended characters */ -#endif +#endif /* FF_USE_LFN == 1 */ +#endif /* FF_USE_LFN == 0 */ +/*--------------------------------*/ +/* Code conversion tables */ +/*--------------------------------*/ + +#if FF_CODE_PAGE == 0 /* Run-time code page configuration */ +#define CODEPAGE CodePage +static WORD CodePage; /* Current code page */ +static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ + +static const BYTE Ct437[] = TBL_CT437; +static const BYTE Ct720[] = TBL_CT720; +static const BYTE Ct737[] = TBL_CT737; +static const BYTE Ct771[] = TBL_CT771; +static const BYTE Ct775[] = TBL_CT775; +static const BYTE Ct850[] = TBL_CT850; +static const BYTE Ct852[] = TBL_CT852; +static const BYTE Ct855[] = TBL_CT855; +static const BYTE Ct857[] = TBL_CT857; +static const BYTE Ct860[] = TBL_CT860; +static const BYTE Ct861[] = TBL_CT861; +static const BYTE Ct862[] = TBL_CT862; +static const BYTE Ct863[] = TBL_CT863; +static const BYTE Ct864[] = TBL_CT864; +static const BYTE Ct865[] = TBL_CT865; +static const BYTE Ct866[] = TBL_CT866; +static const BYTE Ct869[] = TBL_CT869; +static const BYTE Dc932[] = TBL_DC932; +static const BYTE Dc936[] = TBL_DC936; +static const BYTE Dc949[] = TBL_DC949; +static const BYTE Dc950[] = TBL_DC950; + +#elif FF_CODE_PAGE < 900 /* Static code page configuration (SBCS) */ +#define CODEPAGE FF_CODE_PAGE +static const BYTE ExCvt[] = MKCVTBL(TBL_CT, FF_CODE_PAGE); + +#else /* Static code page configuration (DBCS) */ +#define CODEPAGE FF_CODE_PAGE +static const BYTE DbcTbl[] = MKCVTBL(TBL_DC, FF_CODE_PAGE); + +#endif + @@ -601,8 +578,7 @@ static const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for SBCS extended /* Load/Store multi-byte word in the FAT structure */ /*-----------------------------------------------------------------------*/ -static -WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ +static WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ { WORD rv; @@ -611,8 +587,7 @@ WORD ld_word (const BYTE* ptr) /* Load a 2-byte little-endian word */ return rv; } -static -DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ +static DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ { DWORD rv; @@ -623,9 +598,8 @@ DWORD ld_dword (const BYTE* ptr) /* Load a 4-byte little-endian word */ return rv; } -#if _FS_EXFAT -static -QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ +#if FF_FS_EXFAT +static QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ { QWORD rv; @@ -641,16 +615,14 @@ QWORD ld_qword (const BYTE* ptr) /* Load an 8-byte little-endian word */ } #endif -#if !_FS_READONLY -static -void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */ +#if !FF_FS_READONLY +static void st_word (BYTE* ptr, WORD val) /* Store a 2-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; } -static -void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */ +static void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; @@ -658,9 +630,8 @@ void st_dword (BYTE* ptr, DWORD val) /* Store a 4-byte word in little-endian *ptr++ = (BYTE)val; } -#if _FS_EXFAT -static -void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian */ +#if FF_FS_EXFAT +static void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian */ { *ptr++ = (BYTE)val; val >>= 8; *ptr++ = (BYTE)val; val >>= 8; @@ -672,7 +643,7 @@ void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian *ptr++ = (BYTE)val; } #endif -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ @@ -687,32 +658,232 @@ void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian #define mem_set memset #define mem_cmp memcmp + /* Check if chr is contained in the string */ -static -int chk_chr (const char* str, int chr) { /* NZ:contained, ZR:not contained */ +static int chk_chr (const char* str, int chr) /* NZ:contained, ZR:not contained */ +{ while (*str && *str != chr) str++; return *str; } +/* Test if the character is DBC 1st byte */ +static int dbc_1st (BYTE c) +{ +#if FF_CODE_PAGE == 0 /* Variable code page */ + if (DbcTbl && c >= DbcTbl[0]) { + if (c <= DbcTbl[1]) return 1; /* 1st byte range 1 */ + if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; /* 1st byte range 2 */ + } +#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ + if (c >= DbcTbl[0]) { + if (c <= DbcTbl[1]) return 1; + if (c >= DbcTbl[2] && c <= DbcTbl[3]) return 1; + } +#else /* SBCS fixed code page */ + if (c != 0) return 0; /* Always false */ +#endif + return 0; +} -#if _FS_REENTRANT +/* Test if the character is DBC 2nd byte */ +static int dbc_2nd (BYTE c) +{ +#if FF_CODE_PAGE == 0 /* Variable code page */ + if (DbcTbl && c >= DbcTbl[4]) { + if (c <= DbcTbl[5]) return 1; /* 2nd byte range 1 */ + if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; /* 2nd byte range 2 */ + if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; /* 2nd byte range 3 */ + } +#elif FF_CODE_PAGE >= 900 /* DBCS fixed code page */ + if (c >= DbcTbl[4]) { + if (c <= DbcTbl[5]) return 1; + if (c >= DbcTbl[6] && c <= DbcTbl[7]) return 1; + if (c >= DbcTbl[8] && c <= DbcTbl[9]) return 1; + } +#else /* SBCS fixed code page */ + if (c != 0) return 0; /* Always false */ +#endif + return 0; +} + + +#if FF_USE_LFN + +/* Get a character from TCHAR string in defined API encodeing */ +static DWORD tchar2uni ( /* Returns character in UTF-16 encoding (>=0x10000 on double encoding unit, 0xFFFFFFFF on decode error) */ + const TCHAR** str /* Pointer to pointer to TCHAR string in configured encoding */ +) +{ + DWORD uc; + const TCHAR *p = *str; + +#if FF_LFN_UNICODE == 1 /* UTF-16 input */ + WCHAR wc; + + uc = *p++; /* Get a unit */ + if (IsSurrogate(uc)) { /* Surrogate? */ + wc = *p++; /* Get low surrogate */ + if (!IsSurrogateH(uc) || !IsSurrogateL(wc)) return 0xFFFFFFFF; /* Wrong surrogate? */ + uc = uc << 16 | wc; + } + +#elif FF_LFN_UNICODE == 2 /* UTF-8 input */ + BYTE b; + int nf; + + uc = (BYTE)*p++; /* Get a unit */ + if (uc & 0x80) { /* Multiple byte code? */ + if ((uc & 0xE0) == 0xC0) { /* 2-byte sequence? */ + uc &= 0x1F; nf = 1; + } else { + if ((uc & 0xF0) == 0xE0) { /* 3-byte sequence? */ + uc &= 0x0F; nf = 2; + } else { + if ((uc & 0xF8) == 0xF0) { /* 4-byte sequence? */ + uc &= 0x07; nf = 3; + } else { /* Wrong sequence */ + return 0xFFFFFFFF; + } + } + } + do { /* Get trailing bytes */ + b = (BYTE)*p++; + if ((b & 0xC0) != 0x80) return 0xFFFFFFFF; /* Wrong sequence? */ + uc = uc << 6 | (b & 0x3F); + } while (--nf != 0); + if (uc < 0x80 || IsSurrogate(uc) || uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ + if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ + } + +#elif FF_LFN_UNICODE == 3 /* UTF-32 input */ + uc = (TCHAR)*p++; /* Get a unit */ + if (uc >= 0x110000) return 0xFFFFFFFF; /* Wrong code? */ + if (uc >= 0x010000) uc = 0xD800DC00 | ((uc - 0x10000) << 6 & 0x3FF0000) | (uc & 0x3FF); /* Make a surrogate pair if needed */ + +#else /* ANSI/OEM input */ + BYTE b; + WCHAR wc; + + wc = (BYTE)*p++; /* Get a byte */ + if (dbc_1st((BYTE)wc)) { /* Is it a DBC 1st byte? */ + b = (BYTE)*p++; /* Get 2nd byte */ + if (!dbc_2nd(b)) return 0xFFFFFFFF; /* Invalid code? */ + wc = (wc << 8) + b; /* Make a DBC */ + } + if (wc != 0) { + wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM ==> Unicode */ + if (wc == 0) return 0xFFFFFFFF; /* Invalid code? */ + } + uc = wc; + +#endif + *str = p; /* Next read pointer */ + return uc; +} + + +/* Output a TCHAR string in defined API encoding */ +static BYTE put_utf ( /* Returns number of encoding units written (0:buffer overflow or wrong encoding) */ + DWORD chr, /* UTF-16 encoded character (Double encoding unit char if >=0x10000) */ + TCHAR* buf, /* Output buffer */ + UINT szb /* Size of the buffer */ +) +{ +#if FF_LFN_UNICODE == 1 /* UTF-16 output */ + WCHAR hs, wc; + + hs = (WCHAR)(chr >> 16); + wc = (WCHAR)chr; + if (hs == 0) { /* Single encoding unit? */ + if (szb < 1 || IsSurrogate(wc)) return 0; /* Buffer overflow or wrong code? */ + *buf = wc; + return 1; + } + if (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0; /* Buffer overflow or wrong surrogate? */ + *buf++ = hs; + *buf++ = wc; + return 2; + +#elif FF_LFN_UNICODE == 2 /* UTF-8 output */ + DWORD hc; + + if (chr < 0x80) { /* Single byte code? */ + if (szb < 1) return 0; /* Buffer overflow? */ + *buf = (TCHAR)chr; + return 1; + } + if (chr < 0x800) { /* 2-byte sequence? */ + if (szb < 2) return 0; /* Buffer overflow? */ + *buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 2; + } + if (chr < 0x10000) { /* 3-byte sequence? */ + if (szb < 3 || IsSurrogate(chr)) return 0; /* Buffer overflow or wrong code? */ + *buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F)); + *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 3; + } + /* 4-byte sequence */ + if (szb < 4) return 0; /* Buffer overflow? */ + hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ + chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ + if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ + chr = (hc | chr) + 0x10000; + *buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07)); + *buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F)); + *buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F)); + return 4; + +#elif FF_LFN_UNICODE == 3 /* UTF-32 output */ + DWORD hc; + + if (szb < 1) return 0; /* Buffer overflow? */ + if (chr >= 0x10000) { /* Out of BMP? */ + hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6; /* Get high 10 bits */ + chr = (chr & 0xFFFF) - 0xDC00; /* Get low 10 bits */ + if (hc >= 0x100000 || chr >= 0x400) return 0; /* Wrong surrogate? */ + chr = (hc | chr) + 0x10000; + } + *buf++ = (TCHAR)chr; + return 1; + +#else /* ANSI/OEM output */ + WCHAR wc; + + wc = ff_uni2oem(chr, CODEPAGE); + if (wc >= 0x100) { /* Is this a DBC? */ + if (szb < 2) return 0; + *buf++ = (char)(wc >> 8); /* Store DBC 1st byte */ + *buf++ = (TCHAR)wc; /* Store DBC 2nd byte */ + return 2; + } + if (wc == 0 || szb < 1) return 0; /* Invalid char or buffer overflow? */ + *buf++ = (TCHAR)wc; /* Store the character */ + return 1; +#endif +} +#endif /* FF_USE_LFN */ + + +#if FF_FS_REENTRANT /*-----------------------------------------------------------------------*/ /* Request/Release grant to access the volume */ /*-----------------------------------------------------------------------*/ -static -int lock_fs ( - FATFS* fs /* File system object */ +static int lock_fs ( /* 1:Ok, 0:timeout */ + FATFS* fs /* Filesystem object */ ) { return ff_req_grant(fs->sobj); } -static -void unlock_fs ( - FATFS* fs, /* File system object */ +static void unlock_fs ( + FATFS* fs, /* Filesystem object */ FRESULT res /* Result code to be returned */ ) { @@ -725,50 +896,48 @@ void unlock_fs ( -#if _FS_LOCK != 0 +#if FF_FS_LOCK != 0 /*-----------------------------------------------------------------------*/ /* File lock control functions */ /*-----------------------------------------------------------------------*/ -static -FRESULT chk_lock ( /* Check if the file can be accessed */ +static FRESULT chk_lock ( /* Check if the file can be accessed */ DIR* dp, /* Directory object pointing the file to be checked */ - int acc /* Desired access type (0:Read, 1:Write, 2:Delete/Rename) */ + int acc /* Desired access type (0:Read mode open, 1:Write mode open, 2:Delete or rename) */ ) { UINT i, be; - /* Search file semaphore table */ - for (i = be = 0; i < _FS_LOCK; i++) { + /* Search open object table for the object */ + be = 0; + for (i = 0; i < FF_FS_LOCK; i++) { if (Files[i].fs) { /* Existing entry */ - if (Files[i].fs == dp->obj.fs && /* Check if the object matched with an open object */ + if (Files[i].fs == dp->obj.fs && /* Check if the object matches with an open object */ Files[i].clu == dp->obj.sclust && Files[i].ofs == dp->dptr) break; } else { /* Blank entry */ be = 1; } } - if (i == _FS_LOCK) { /* The object is not opened */ - return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new object? */ + if (i == FF_FS_LOCK) { /* The object has not been opened */ + return (!be && acc != 2) ? FR_TOO_MANY_OPEN_FILES : FR_OK; /* Is there a blank entry for new object? */ } - /* The object has been opened. Reject any open against writing file and all write mode open */ - return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; + /* The object was opened. Reject any open against writing file and all write mode open */ + return (acc != 0 || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; } -static -int enq_lock (void) /* Check if an entry is available for a new object */ +static int enq_lock (void) /* Check if an entry is available for a new object */ { UINT i; - for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; - return (i == _FS_LOCK) ? 0 : 1; + for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; + return (i == FF_FS_LOCK) ? 0 : 1; } -static -UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ +static UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ DIR* dp, /* Directory object pointing the file to register or increment */ int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ ) @@ -776,31 +945,30 @@ UINT inc_lock ( /* Increment object open counter and returns its index (0:Intern UINT i; - for (i = 0; i < _FS_LOCK; i++) { /* Find the object */ + for (i = 0; i < FF_FS_LOCK; i++) { /* Find the object */ if (Files[i].fs == dp->obj.fs && Files[i].clu == dp->obj.sclust && Files[i].ofs == dp->dptr) break; } - if (i == _FS_LOCK) { /* Not opened. Register it as new. */ - for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; - if (i == _FS_LOCK) return 0; /* No free entry to register (int err) */ + if (i == FF_FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ; + if (i == FF_FS_LOCK) return 0; /* No free entry to register (int err) */ Files[i].fs = dp->obj.fs; Files[i].clu = dp->obj.sclust; Files[i].ofs = dp->dptr; Files[i].ctr = 0; } - if (acc && Files[i].ctr) return 0; /* Access violation (int err) */ + if (acc >= 1 && Files[i].ctr) return 0; /* Access violation (int err) */ Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ - return i + 1; + return i + 1; /* Index number origin from 1 */ } -static -FRESULT dec_lock ( /* Decrement object open counter */ +static FRESULT dec_lock ( /* Decrement object open counter */ UINT i /* Semaphore index (1..) */ ) { @@ -808,7 +976,7 @@ FRESULT dec_lock ( /* Decrement object open counter */ FRESULT res; - if (--i < _FS_LOCK) { /* Shift index number origin from 0 */ + if (--i < FF_FS_LOCK) { /* Index number origin from 0 */ n = Files[i].ctr; if (n == 0x100) n = 0; /* If write mode open, delete the entry */ if (n > 0) n--; /* Decrement read mode open count */ @@ -822,48 +990,40 @@ FRESULT dec_lock ( /* Decrement object open counter */ } -static -void clear_lock ( /* Clear lock entries of the volume */ +static void clear_lock ( /* Clear lock entries of the volume */ FATFS *fs ) { UINT i; - for (i = 0; i < _FS_LOCK; i++) { + for (i = 0; i < FF_FS_LOCK; i++) { if (Files[i].fs == fs) Files[i].fs = 0; } } -#endif /* _FS_LOCK != 0 */ +#endif /* FF_FS_LOCK != 0 */ /*-----------------------------------------------------------------------*/ -/* Move/Flush disk access window in the file system object */ +/* Move/Flush disk access window in the filesystem object */ /*-----------------------------------------------------------------------*/ -#if !_FS_READONLY -static -FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERROR */ - FATFS* fs /* File system object */ +#if !FF_FS_READONLY +static FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs /* Filesystem object */ ) { - DWORD wsect; - UINT nf; FRESULT res = FR_OK; - if (fs->wflag) { /* Write back the sector if it is dirty */ - wsect = fs->winsect; /* Current sector number */ - if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) { - res = FR_DISK_ERR; - } else { - fs->wflag = 0; - if (wsect - fs->fatbase < fs->fsize) { /* Is it in the FAT area? */ - for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */ - wsect += fs->fsize; - disk_write(fs->drv, fs->win, wsect, 1); - } + if (fs->wflag) { /* Is the disk access window dirty */ + if (disk_write(fs->drv, fs->win, fs->winsect, 1) == RES_OK) { /* Write back the window */ + fs->wflag = 0; /* Clear window dirty flag */ + if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */ + if (fs->n_fats == 2) disk_write(fs->drv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */ } + } else { + res = FR_DISK_ERR; } } return res; @@ -871,9 +1031,8 @@ FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERROR */ #endif -static -FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERROR */ - FATFS* fs, /* File system object */ +static FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs, /* Filesystem object */ DWORD sector /* Sector number to make appearance in the fs->win[] */ ) { @@ -881,12 +1040,12 @@ FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERROR */ if (sector != fs->winsect) { /* Window offset changed? */ -#if !_FS_READONLY +#if !FF_FS_READONLY res = sync_window(fs); /* Write-back changes */ #endif if (res == FR_OK) { /* Fill sector window with new data */ if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) { - sector = 0xFFFFFFFF; /* Invalidate window if data is not reliable */ + sector = 0xFFFFFFFF; /* Invalidate window if read data is not valid */ res = FR_DISK_ERR; } fs->winsect = sector; @@ -898,14 +1057,13 @@ FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERROR */ -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ -/* Synchronize file system and strage device */ +/* Synchronize filesystem and data on the storage */ /*-----------------------------------------------------------------------*/ -static -FRESULT sync_fs ( /* FR_OK:succeeded, !=0:error */ - FATFS* fs /* File system object */ +static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS* fs /* Filesystem object */ ) { FRESULT res; @@ -913,10 +1071,9 @@ FRESULT sync_fs ( /* FR_OK:succeeded, !=0:error */ res = sync_window(fs); if (res == FR_OK) { - /* Update FSInfo sector if needed */ - if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { + if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ /* Create FSInfo structure */ - mem_set(fs->win, 0, SS(fs)); + mem_set(fs->win, 0, sizeof fs->win); st_word(fs->win + BS_55AA, 0xAA55); st_dword(fs->win + FSI_LeadSig, 0x41615252); st_dword(fs->win + FSI_StrucSig, 0x61417272); @@ -927,7 +1084,7 @@ FRESULT sync_fs ( /* FR_OK:succeeded, !=0:error */ disk_write(fs->drv, fs->win, fs->winsect, 1); fs->fsi_flag = 0; } - /* Make sure that no pending write process in the physical drive */ + /* Make sure that no pending write process in the lower layer */ if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR; } @@ -939,18 +1096,17 @@ FRESULT sync_fs ( /* FR_OK:succeeded, !=0:error */ /*-----------------------------------------------------------------------*/ -/* Get sector# from cluster# */ +/* Get physical sector number from cluster number */ /*-----------------------------------------------------------------------*/ -static -DWORD clust2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ - FATFS* fs, /* File system object */ +static DWORD clst2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ + FATFS* fs, /* Filesystem object */ DWORD clst /* Cluster# to be converted */ ) { - clst -= 2; - if (clst >= fs->n_fatent - 2) return 0; /* Invalid cluster# */ - return clst * fs->csize + fs->database; + clst -= 2; /* Cluster number is origin from 2 */ + if (clst >= fs->n_fatent - 2) return 0; /* Is it invalid cluster number? */ + return fs->database + fs->csize * clst; /* Start sector number of the cluster */ } @@ -960,10 +1116,9 @@ DWORD clust2sect ( /* !=0:Sector number, 0:Failed (invalid cluster#) */ /* FAT access - Read value of a FAT entry */ /*-----------------------------------------------------------------------*/ -static -DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */ - _FDID* obj, /* Corresponding object */ - DWORD clst /* Cluster number to get the value */ +static DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluster status */ + FFOBJID* obj, /* Corresponding object */ + DWORD clst /* Cluster number to get the value */ ) { UINT wc, bc; @@ -981,44 +1136,46 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluste case FS_FAT12 : bc = (UINT)clst; bc += bc / 2; if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; - wc = fs->win[bc++ % SS(fs)]; + wc = fs->win[bc++ % SS(fs)]; /* Get 1st byte of the entry */ if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break; - wc |= fs->win[bc % SS(fs)] << 8; - val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF); + wc |= fs->win[bc % SS(fs)] << 8; /* Merge 2nd byte of the entry */ + val = (clst & 1) ? (wc >> 4) : (wc & 0xFFF); /* Adjust bit position */ break; case FS_FAT16 : if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break; - val = ld_word(fs->win + clst * 2 % SS(fs)); + val = ld_word(fs->win + clst * 2 % SS(fs)); /* Simple WORD array */ break; case FS_FAT32 : if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; - val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; + val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x0FFFFFFF; /* Simple DWORD array but mask out upper 4 bits */ break; -#if _FS_EXFAT +#if FF_FS_EXFAT case FS_EXFAT : - if (obj->objsize) { + if ((obj->objsize != 0 && obj->sclust != 0) || obj->stat == 0) { /* Object except root dir must have valid data length */ DWORD cofs = clst - obj->sclust; /* Offset from start cluster */ DWORD clen = (DWORD)((obj->objsize - 1) / SS(fs)) / fs->csize; /* Number of clusters - 1 */ - if (obj->stat == 2) { /* Is there no valid chain on the FAT? */ - if (cofs <= clen) { - val = (cofs == clen) ? 0x7FFFFFFF : clst + 1; /* Generate the value */ - break; - } + if (obj->stat == 2 && cofs <= clen) { /* Is it a contiguous chain? */ + val = (cofs == clen) ? 0x7FFFFFFF : clst + 1; /* No data on the FAT, generate the value */ + break; } - if (obj->stat == 3 && cofs < obj->n_cont) { /* Is it in the contiguous part? */ + if (obj->stat == 3 && cofs < obj->n_cont) { /* Is it in the 1st fragment? */ val = clst + 1; /* Generate the value */ break; } if (obj->stat != 2) { /* Get value from FAT if FAT chain is valid */ - if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; - val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; + if (obj->n_frag != 0) { /* Is it on the growing edge? */ + val = 0x7FFFFFFF; /* Generate EOC */ + } else { + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break; + val = ld_dword(fs->win + clst * 4 % SS(fs)) & 0x7FFFFFFF; + } break; } } - /* go next */ + /* go to default */ #endif default: val = 1; /* Internal error */ @@ -1031,14 +1188,13 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x7FFFFFFF:Cluste -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT access - Change value of a FAT entry */ /*-----------------------------------------------------------------------*/ -static -FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ - FATFS* fs, /* Corresponding file system object */ +static FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ + FATFS* fs, /* Corresponding filesystem object */ DWORD clst, /* FAT index number (cluster number) to be changed */ DWORD val /* New value to be set to the entry */ ) @@ -1050,34 +1206,34 @@ FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ if (clst >= 2 && clst < fs->n_fatent) { /* Check if in valid range */ switch (fs->fs_type) { - case FS_FAT12 : /* Bitfield items */ - bc = (UINT)clst; bc += bc / 2; + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; /* bc: byte offset of the entry */ res = move_window(fs, fs->fatbase + (bc / SS(fs))); if (res != FR_OK) break; p = fs->win + bc++ % SS(fs); - *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; /* Put 1st byte */ fs->wflag = 1; res = move_window(fs, fs->fatbase + (bc / SS(fs))); if (res != FR_OK) break; p = fs->win + bc % SS(fs); - *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); /* Put 2nd byte */ fs->wflag = 1; break; - case FS_FAT16 : /* WORD aligned items */ + case FS_FAT16 : res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); if (res != FR_OK) break; - st_word(fs->win + clst * 2 % SS(fs), (WORD)val); + st_word(fs->win + clst * 2 % SS(fs), (WORD)val); /* Simple WORD array */ fs->wflag = 1; break; - case FS_FAT32 : /* DWORD aligned items */ -#if _FS_EXFAT + case FS_FAT32 : +#if FF_FS_EXFAT case FS_EXFAT : #endif res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); if (res != FR_OK) break; - if (!_FS_EXFAT || fs->fs_type != FS_EXFAT) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { val = (val & 0x0FFFFFFF) | (ld_dword(fs->win + clst * 4 % SS(fs)) & 0xF0000000); } st_dword(fs->win + clst * 4 % SS(fs), val); @@ -1088,23 +1244,22 @@ FRESULT put_fat ( /* FR_OK(0):succeeded, !=0:error */ return res; } -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ -#if _FS_EXFAT && !_FS_READONLY +#if FF_FS_EXFAT && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* exFAT: Accessing FAT and Allocation Bitmap */ /*-----------------------------------------------------------------------*/ -/*---------------------------------------------*/ -/* exFAT: Find a contiguous free cluster block */ -/*---------------------------------------------*/ +/*--------------------------------------*/ +/* Find a contiguous free cluster block */ +/*--------------------------------------*/ -static -DWORD find_bitmap ( /* 0:No free cluster, 2..:Free cluster found, 0xFFFFFFFF:Disk error */ - FATFS* fs, /* File system object */ +static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:Disk error */ + FATFS* fs, /* Filesystem object */ DWORD clst, /* Cluster number to scan from */ DWORD ncl /* Number of contiguous clusters to find (1..) */ ) @@ -1118,34 +1273,33 @@ DWORD find_bitmap ( /* 0:No free cluster, 2..:Free cluster found, 0xFFFFFFFF:Dis if (clst >= fs->n_fatent - 2) clst = 0; scl = val = clst; ctr = 0; for (;;) { - if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ + if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; i = val / 8 % SS(fs); bm = 1 << (val % 8); do { do { bv = fs->win[i] & bm; bm <<= 1; /* Get bit value */ if (++val >= fs->n_fatent - 2) { /* Next cluster (with wrap-around) */ - val = 0; bm = 0; i = 4096; + val = 0; bm = 0; i = SS(fs); } - if (!bv) { /* Is it a free cluster? */ - if (++ctr == ncl) return scl + 2; /* Check run length */ + if (bv == 0) { /* Is it a free cluster? */ + if (++ctr == ncl) return scl + 2; /* Check if run length is sufficient for required */ } else { - scl = val; ctr = 0; /* Encountered a live cluster, restart to scan */ + scl = val; ctr = 0; /* Encountered a cluster in-use, restart to scan */ } if (val == clst) return 0; /* All cluster scanned? */ - } while (bm); + } while (bm != 0); bm = 1; } while (++i < SS(fs)); } } -/*------------------------------------*/ -/* exFAT: Set/Clear a block of bitmap */ -/*------------------------------------*/ +/*----------------------------------------*/ +/* Set/Clear a block of allocation bitmap */ +/*----------------------------------------*/ -static -FRESULT change_bitmap ( - FATFS* fs, /* File system object */ +static FRESULT change_bitmap ( + FATFS* fs, /* Filesystem object */ DWORD clst, /* Cluster number to change from */ DWORD ncl, /* Number of clusters to be changed */ int bv /* bit value to be set (0 or 1) */ @@ -1157,9 +1311,9 @@ FRESULT change_bitmap ( clst -= 2; /* The first bit corresponds to cluster #2 */ - sect = fs->database + clst / 8 / SS(fs); /* Sector address (assuming bitmap is located top of the cluster heap) */ - i = clst / 8 % SS(fs); /* Byte offset in the sector */ - bm = 1 << (clst % 8); /* Bit mask in the byte */ + sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ + i = clst / 8 % SS(fs); /* Byte offset in the sector */ + bm = 1 << (clst % 8); /* Bit mask in the byte */ for (;;) { if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; do { @@ -1177,18 +1331,18 @@ FRESULT change_bitmap ( /*---------------------------------------------*/ -/* Complement contiguous part of the FAT chain */ +/* Fill the first fragment of the FAT chain */ /*---------------------------------------------*/ -static -FRESULT fill_fat_chain ( - _FDID* obj /* Pointer to the corresponding object */ +static FRESULT fill_first_frag ( + FFOBJID* obj /* Pointer to the corresponding object */ ) { FRESULT res; DWORD cl, n; - if (obj->stat == 3) { /* Has the object been changed 'fragmented'? */ + + if (obj->stat == 3) { /* Has the object been changed 'fragmented' in this session? */ for (cl = obj->sclust, n = obj->n_cont; n; cl++, n--) { /* Create cluster chain on the FAT */ res = put_fat(obj->fs, cl, cl + 1); if (res != FR_OK) return res; @@ -1198,35 +1352,57 @@ FRESULT fill_fat_chain ( return FR_OK; } -#endif /* _FS_EXFAT && !_FS_READONLY */ + +/*---------------------------------------------*/ +/* Fill the last fragment of the FAT chain */ +/*---------------------------------------------*/ + +static FRESULT fill_last_frag ( + FFOBJID* obj, /* Pointer to the corresponding object */ + DWORD lcl, /* Last cluster of the fragment */ + DWORD term /* Value to set the last FAT entry */ +) +{ + FRESULT res; + + + while (obj->n_frag > 0) { /* Create the chain of last fragment */ + res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term); + if (res != FR_OK) return res; + obj->n_frag--; + } + return FR_OK; +} + +#endif /* FF_FS_EXFAT && !FF_FS_READONLY */ -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT handling - Remove a cluster chain */ /*-----------------------------------------------------------------------*/ -static -FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ - _FDID* obj, /* Corresponding object */ + +static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ + FFOBJID* obj, /* Corresponding object */ DWORD clst, /* Cluster to remove a chain from */ - DWORD pclst /* Previous cluster of clst (0:an entire chain) */ + DWORD pclst /* Previous cluster of clst (0 if entire chain) */ ) { FRESULT res = FR_OK; DWORD nxt; FATFS *fs = obj->fs; -#if _FS_EXFAT || _USE_TRIM +#if FF_FS_EXFAT || FF_USE_TRIM DWORD scl = clst, ecl = clst; #endif -#if _USE_TRIM +#if FF_USE_TRIM DWORD rt[2]; #endif if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Check if in valid range */ /* Mark the previous cluster 'EOC' on the FAT if it exists */ - if (pclst && (!_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { + if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) { res = put_fat(fs, pclst, 0xFFFFFFFF); if (res != FR_OK) return res; } @@ -1237,7 +1413,7 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ if (nxt == 0) break; /* Empty cluster? */ if (nxt == 1) return FR_INT_ERR; /* Internal error? */ if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error? */ - if (!_FS_EXFAT || fs->fs_type != FS_EXFAT) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { res = put_fat(fs, clst, 0); /* Mark the cluster 'free' on the FAT */ if (res != FR_OK) return res; } @@ -1245,20 +1421,20 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ fs->free_clst++; fs->fsi_flag |= 1; } -#if _FS_EXFAT || _USE_TRIM +#if FF_FS_EXFAT || FF_USE_TRIM if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ ecl = nxt; } else { /* End of contiguous cluster block */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { res = change_bitmap(fs, scl, ecl - scl + 1, 0); /* Mark the cluster block 'free' on the bitmap */ if (res != FR_OK) return res; } #endif -#if _USE_TRIM - rt[0] = clust2sect(fs, scl); /* Start sector */ - rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ - disk_ioctl(fs->drv, CTRL_TRIM, rt); /* Inform device the block can be erased */ +#if FF_USE_TRIM + rt[0] = clst2sect(fs, scl); /* Start of data area freed */ + rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area freed */ + disk_ioctl(fs->drv, CTRL_TRIM, rt); /* Inform device the data in the block is no longer needed */ #endif scl = ecl = nxt; } @@ -1266,13 +1442,28 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ clst = nxt; /* Next cluster */ } while (clst < fs->n_fatent); /* Repeat while not the last link */ -#if _FS_EXFAT +#if FF_FS_EXFAT + /* Some post processes for chain status */ if (fs->fs_type == FS_EXFAT) { - if (pclst == 0) { /* Does object have no chain? */ - obj->stat = 0; /* Change the object status 'initial' */ + if (pclst == 0) { /* Has the entire chain been removed? */ + obj->stat = 0; /* Change the chain status 'initial' */ } else { - if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Did the chain got contiguous? */ - obj->stat = 2; /* Change the object status 'contiguous' */ + if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */ + clst = obj->sclust; /* Follow the chain to check if it gets contiguous */ + while (clst != pclst) { + nxt = get_fat(obj, clst); + if (nxt < 2) return FR_INT_ERR; + if (nxt == 0xFFFFFFFF) return FR_DISK_ERR; + if (nxt != clst + 1) break; /* Not contiguous? */ + clst++; + } + if (clst == pclst) { /* Has the chain got contiguous again? */ + obj->stat = 2; /* Change the chain status 'contiguous' */ + } + } else { + if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */ + obj->stat = 2; /* Change the chain status 'contiguous' */ + } } } } @@ -1286,9 +1477,9 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ /*-----------------------------------------------------------------------*/ /* FAT handling - Stretch a chain or Create a new chain */ /*-----------------------------------------------------------------------*/ -static -DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ - _FDID* obj, /* Corresponding object */ + +static DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FFOBJID* obj, /* Corresponding object */ DWORD clst /* Cluster# to stretch, 0:Create a new chain */ ) { @@ -1298,18 +1489,19 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk if (clst == 0) { /* Create a new chain */ - scl = fs->last_clst; /* Get suggested cluster to start from */ + scl = fs->last_clst; /* Suggested cluster to start to find */ if (scl == 0 || scl >= fs->n_fatent) scl = 1; } - else { /* Stretch current chain */ + else { /* Stretch a chain */ cs = get_fat(obj, clst); /* Check the cluster status */ - if (cs < 2) return 1; /* Invalid value */ - if (cs == 0xFFFFFFFF) return cs; /* A disk error occurred */ + if (cs < 2) return 1; /* Test for insanity */ + if (cs == 0xFFFFFFFF) return cs; /* Test for disk error */ if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ - scl = clst; + scl = clst; /* Cluster to start to find */ } + if (fs->free_clst == 0) return 0; /* No free cluster */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ ncl = find_bitmap(fs, scl, 1); /* Find a free cluster */ if (ncl == 0 || ncl == 0xFFFFFFFF) return ncl; /* No free cluster or hard error? */ @@ -1317,62 +1509,79 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk if (res == FR_INT_ERR) return 1; if (res == FR_DISK_ERR) return 0xFFFFFFFF; if (clst == 0) { /* Is it a new chain? */ - obj->stat = 2; /* Set status 'contiguous chain' */ - } else { /* This is a stretched chain */ + obj->stat = 2; /* Set status 'contiguous' */ + } else { /* It is a stretched chain */ if (obj->stat == 2 && ncl != scl + 1) { /* Is the chain got fragmented? */ obj->n_cont = scl - obj->sclust; /* Set size of the contiguous part */ obj->stat = 3; /* Change status 'just fragmented' */ } } + if (obj->stat != 2) { /* Is the file non-contiguous? */ + if (ncl == clst + 1) { /* Is the cluster next to previous one? */ + obj->n_frag = obj->n_frag ? obj->n_frag + 1 : 2; /* Increment size of last framgent */ + } else { /* New fragment */ + if (obj->n_frag == 0) obj->n_frag = 1; + res = fill_last_frag(obj, clst, ncl); /* Fill last fragment on the FAT and link it to new one */ + if (res == FR_OK) obj->n_frag = 1; + } + } } else #endif - { /* On the FAT12/16/32 volume */ - ncl = scl; /* Start cluster */ - for (;;) { - ncl++; /* Next cluster */ - if (ncl >= fs->n_fatent) { /* Check wrap-around */ - ncl = 2; - if (ncl > scl) return 0; /* No free cluster */ + { /* On the FAT/FAT32 volume */ + ncl = 0; + if (scl == clst) { /* Stretching an existing chain? */ + ncl = scl + 1; /* Test if next cluster is free */ + if (ncl >= fs->n_fatent) ncl = 2; + cs = get_fat(obj, ncl); /* Get next cluster status */ + if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ + if (cs != 0) { /* Not free? */ + cs = fs->last_clst; /* Start at suggested cluster if it is valid */ + if (cs >= 2 && cs < fs->n_fatent) scl = cs; + ncl = 0; } - cs = get_fat(obj, ncl); /* Get the cluster status */ - if (cs == 0) break; /* Found a free cluster */ - if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* An error occurred */ - if (ncl == scl) return 0; /* No free cluster */ } - } - - if (_FS_EXFAT && fs->fs_type == FS_EXFAT && obj->stat == 2) { /* Is it a contiguous chain? */ - res = FR_OK; /* FAT does not need to be written */ - } else { - res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ - if (res == FR_OK && clst) { - res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ + if (ncl == 0) { /* The new cluster cannot be contiguous and find another fragment */ + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Check wrap-around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster found? */ + } + cs = get_fat(obj, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster? */ + if (cs == 1 || cs == 0xFFFFFFFF) return cs; /* Test for error */ + if (ncl == scl) return 0; /* No free cluster found? */ + } + } + res = put_fat(fs, ncl, 0xFFFFFFFF); /* Mark the new cluster 'EOC' */ + if (res == FR_OK && clst != 0) { + res = put_fat(fs, clst, ncl); /* Link it from the previous one if needed */ } } if (res == FR_OK) { /* Update FSINFO if function succeeded. */ fs->last_clst = ncl; - if (fs->free_clst < fs->n_fatent - 2) fs->free_clst--; + if (fs->free_clst <= fs->n_fatent - 2) fs->free_clst--; fs->fsi_flag |= 1; } else { - ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; /* Failed. Create error status */ + ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; /* Failed. Generate error status */ } return ncl; /* Return new cluster number or error status */ } -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK /*-----------------------------------------------------------------------*/ /* FAT handling - Convert offset into cluster with link map table */ /*-----------------------------------------------------------------------*/ -static -DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ +static DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ FIL* fp, /* Pointer to the file object */ FSIZE_t ofs /* File offset to be converted to cluster# */ ) @@ -1392,7 +1601,47 @@ DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ return cl + *tbl; /* Return the cluster number */ } -#endif /* _USE_FASTSEEK */ +#endif /* FF_USE_FASTSEEK */ + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Fill a cluster with zeros */ +/*-----------------------------------------------------------------------*/ + +#if !FF_FS_READONLY +static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ + FATFS *fs, /* Filesystem object */ + DWORD clst /* Directory table to clear */ +) +{ + DWORD sect; + UINT n, szb; + BYTE *ibuf; + + + if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ + sect = clst2sect(fs, clst); /* Top of the cluster */ + fs->winsect = sect; /* Set window to top of the cluster */ + mem_set(fs->win, 0, sizeof fs->win); /* Clear window buffer */ +#if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ + /* Allocate a temporary buffer */ + for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; + if (szb > SS(fs)) { /* Buffer allocated? */ + mem_set(ibuf, 0, szb); + szb /= SS(fs); /* Bytes -> Sectors */ + for (n = 0; n < fs->csize && disk_write(fs->drv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ + ff_memfree(ibuf); + } else +#endif + { + ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */ + for (n = 0; n < fs->csize && disk_write(fs->drv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */ + } + return (n == fs->csize) ? FR_OK : FR_DISK_ERR; +} +#endif /* !FF_FS_READONLY */ @@ -1401,8 +1650,7 @@ DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ /* Directory handling - Set directory index */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ +static FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ DIR* dp, /* Pointer to directory object */ DWORD ofs /* Offset of directory table */ ) @@ -1411,21 +1659,21 @@ FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ FATFS *fs = dp->obj.fs; - if (ofs >= (DWORD)((_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) { /* Check range of offset and alignment */ + if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR) || ofs % SZDIRE) { /* Check range of offset and alignment */ return FR_INT_ERR; } dp->dptr = ofs; /* Set current offset */ clst = dp->obj.sclust; /* Table start cluster (0:root) */ if (clst == 0 && fs->fs_type >= FS_FAT32) { /* Replace cluster# 0 with root cluster# */ clst = fs->dirbase; - if (_FS_EXFAT) dp->obj.stat = 0; /* exFAT: Root dir has an FAT chain */ + if (FF_FS_EXFAT) dp->obj.stat = 0; /* exFAT: Root dir has an FAT chain */ } - if (clst == 0) { /* Static table (root-directory in FAT12/16) */ - if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ + if (clst == 0) { /* Static table (root-directory on the FAT volume) */ + if (ofs / SZDIRE >= fs->n_rootdir) return FR_INT_ERR; /* Is index out of range? */ dp->sect = fs->dirbase; - } else { /* Dynamic table (sub-directory or root-directory in FAT32+) */ + } else { /* Dynamic table (sub-directory or root-directory on the FAT32/exFAT volume) */ csz = (DWORD)fs->csize * SS(fs); /* Bytes per cluster */ while (ofs >= csz) { /* Follow cluster chain */ clst = get_fat(&dp->obj, clst); /* Get next cluster */ @@ -1433,10 +1681,10 @@ FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR; /* Reached to end of table or internal error */ ofs -= csz; } - dp->sect = clust2sect(fs, clst); + dp->sect = clst2sect(fs, clst); } dp->clust = clst; /* Current cluster# */ - if (!dp->sect) return FR_INT_ERR; + if (dp->sect == 0) return FR_INT_ERR; dp->sect += ofs / SS(fs); /* Sector# of the directory entry */ dp->dir = fs->win + (ofs % SS(fs)); /* Pointer to the entry in the win[] */ @@ -1450,36 +1698,34 @@ FRESULT dir_sdi ( /* FR_OK(0):succeeded, !=0:error */ /* Directory handling - Move directory table index next */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ - DIR* dp, /* Pointer to the directory object */ - int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +static FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ + DIR* dp, /* Pointer to the directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ ) { DWORD ofs, clst; FATFS *fs = dp->obj.fs; -#if !_FS_READONLY - UINT n; -#endif + ofs = dp->dptr + SZDIRE; /* Next entry */ - if (!dp->sect || ofs >= (DWORD)((_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) return FR_NO_FILE; /* Report EOT when offset has reached max value */ + if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0; /* Disable it if the offset reached the max value */ + if (dp->sect == 0) return FR_NO_FILE; /* Report EOT if it has been disabled */ if (ofs % SS(fs) == 0) { /* Sector changed? */ dp->sect++; /* Next sector */ - if (!dp->clust) { /* Static table */ + if (dp->clust == 0) { /* Static table */ if (ofs / SZDIRE >= fs->n_rootdir) { /* Report EOT if it reached end of static table */ dp->sect = 0; return FR_NO_FILE; } } else { /* Dynamic table */ - if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ - clst = get_fat(&dp->obj, dp->clust); /* Get next cluster */ - if (clst <= 1) return FR_INT_ERR; /* Internal error */ - if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ - if (clst >= fs->n_fatent) { /* Reached end of dynamic table */ -#if !_FS_READONLY + if ((ofs / SS(fs) & (fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(&dp->obj, dp->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; /* Internal error */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst >= fs->n_fatent) { /* It reached end of dynamic table */ +#if !FF_FS_READONLY if (!stretch) { /* If no stretch, report EOT */ dp->sect = 0; return FR_NO_FILE; } @@ -1487,22 +1733,15 @@ FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Co if (clst == 0) return FR_DENIED; /* No free cluster */ if (clst == 1) return FR_INT_ERR; /* Internal error */ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ - /* Clean-up the stretched table */ - if (_FS_EXFAT) dp->obj.stat |= 4; /* The directory needs to be updated */ - if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ - mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */ - for (n = 0, fs->winsect = clust2sect(fs, clst); n < fs->csize; n++, fs->winsect++) { /* Fill the new cluster with 0 */ - fs->wflag = 1; - if (sync_window(fs) != FR_OK) return FR_DISK_ERR; - } - fs->winsect -= n; /* Restore window offset */ + if (dir_clear(fs, clst) != FR_OK) return FR_DISK_ERR; /* Clean up the stretched table */ + if (FF_FS_EXFAT) dp->obj.stat |= 4; /* exFAT: The directory has been stretched */ #else - if (!stretch) dp->sect = 0; /* If no stretch, report EOT (this is to suppress warning) */ + if (!stretch) dp->sect = 0; /* (this line is to suppress compiler warning) */ dp->sect = 0; return FR_NO_FILE; /* Report EOT */ #endif } dp->clust = clst; /* Initialize data for new cluster */ - dp->sect = clust2sect(fs, clst); + dp->sect = clst2sect(fs, clst); } } } @@ -1515,15 +1754,14 @@ FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Co -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Directory handling - Reserve a block of directory entries */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ - DIR* dp, /* Pointer to the directory object */ - UINT nent /* Number of contiguous entries to allocate */ +static FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ + DIR* dp, /* Pointer to the directory object */ + UINT nent /* Number of contiguous entries to allocate */ ) { FRESULT res; @@ -1537,7 +1775,7 @@ FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ do { res = move_window(fs, dp->sect); if (res != FR_OK) break; -#if _FS_EXFAT +#if FF_FS_EXFAT if ((fs->fs_type == FS_EXFAT) ? (int)((dp->dir[XDIR_Type] & 0x80) == 0) : (int)(dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0)) { #else if (dp->dir[DIR_Name] == DDEM || dp->dir[DIR_Name] == 0) { @@ -1554,7 +1792,7 @@ FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ return res; } -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ @@ -1563,10 +1801,9 @@ FRESULT dir_alloc ( /* FR_OK(0):succeeded, !=0:error */ /* FAT: Directory handling - Load/Store start cluster number */ /*-----------------------------------------------------------------------*/ -static -DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ - FATFS* fs, /* Pointer to the fs object */ - const BYTE* dir /* Pointer to the key entry */ +static DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ + FATFS* fs, /* Pointer to the fs object */ + const BYTE* dir /* Pointer to the key entry */ ) { DWORD cl; @@ -1580,9 +1817,8 @@ DWORD ld_clust ( /* Returns the top cluster value of the SFN entry */ } -#if !_FS_READONLY -static -void st_clust ( +#if !FF_FS_READONLY +static void st_clust ( FATFS* fs, /* Pointer to the fs object */ BYTE* dir, /* Pointer to the key entry */ DWORD cl /* Value to be set */ @@ -1597,19 +1833,12 @@ void st_clust ( -#if _USE_LFN != 0 -/*------------------------------------------------------------------------*/ -/* FAT-LFN: LFN handling */ -/*------------------------------------------------------------------------*/ -static -const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN characters in the directory entry */ - - +#if FF_USE_LFN /*--------------------------------------------------------*/ /* FAT-LFN: Compare a part of file name with an LFN entry */ /*--------------------------------------------------------*/ -static -int cmp_lfn ( /* 1:matched, 0:not matched */ + +static int cmp_lfn ( /* 1:matched, 0:not matched */ const WCHAR* lfnbuf, /* Pointer to the LFN working buffer to be compared */ BYTE* dir /* Pointer to the directory entry containing the part of LFN */ ) @@ -1624,8 +1853,8 @@ int cmp_lfn ( /* 1:matched, 0:not matched */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ - if (wc) { - if (i >= _MAX_LFN || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ + if (wc != 0) { + if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ return 0; /* Not matched */ } wc = uc; @@ -1640,12 +1869,12 @@ int cmp_lfn ( /* 1:matched, 0:not matched */ } -#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 || _USE_LABEL || _FS_EXFAT +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT /*-----------------------------------------------------*/ /* FAT-LFN: Pick a part of file name from an LFN entry */ /*-----------------------------------------------------*/ -static -int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ + +static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */ WCHAR* lfnbuf, /* Pointer to the LFN working buffer */ BYTE* dir /* Pointer to the LFN entry */ ) @@ -1654,22 +1883,22 @@ int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry * WCHAR wc, uc; - if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO */ + if (ld_word(dir + LDIR_FstClusLO) != 0) return 0; /* Check LDIR_FstClusLO is 0 */ - i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + i = ((dir[LDIR_Ord] & ~LLEF) - 1) * 13; /* Offset in the LFN buffer */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ - if (wc) { - if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + if (wc != 0) { + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i++] = wc = uc; /* Store it */ } else { if (uc != 0xFFFF) return 0; /* Check filler */ } } - if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */ - if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */ + if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */ lfnbuf[i] = 0; } @@ -1678,12 +1907,12 @@ int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry * #endif -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------*/ /* FAT-LFN: Create an entry of LFN entries */ /*-----------------------------------------*/ -static -void put_lfn ( + +static void put_lfn ( const WCHAR* lfn, /* Pointer to the LFN */ BYTE* dir, /* Pointer to the LFN entry to be created */ BYTE ord, /* LFN order (1-20) */ @@ -1710,18 +1939,17 @@ void put_lfn ( dir[LDIR_Ord] = ord; /* Set the LFN order */ } -#endif /* !_FS_READONLY */ -#endif /* _USE_LFN != 0 */ +#endif /* !FF_FS_READONLY */ +#endif /* FF_USE_LFN */ -#if _USE_LFN != 0 && !_FS_READONLY +#if FF_USE_LFN && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* FAT-LFN: Create a Numbered SFN */ /*-----------------------------------------------------------------------*/ -static -void gen_numname ( +static void gen_numname ( BYTE* dst, /* Pointer to the buffer to store numbered SFN */ const BYTE* src, /* Pointer to SFN */ const WCHAR* lfn, /* Pointer to LFN */ @@ -1738,7 +1966,7 @@ void gen_numname ( if (seq > 5) { /* In case of many collisions, generate a hash number instead of sequential number */ sr = seq; - while (*lfn) { /* Create a CRC */ + while (*lfn) { /* Create a CRC as hash value */ wc = *lfn++; for (i = 0; i < 16; i++) { sr = (sr << 1) + (wc & 1); @@ -1759,9 +1987,9 @@ void gen_numname ( } while (seq); ns[i] = '~'; - /* Append the number */ + /* Append the number to the SFN body */ for (j = 0; j < i && dst[j] != ' '; j++) { - if (IsDBCS1(dst[j])) { + if (dbc_1st(dst[j])) { if (j == i - 1) break; j++; } @@ -1770,38 +1998,38 @@ void gen_numname ( dst[j++] = (i < 8) ? ns[i++] : ' '; } while (j < 8); } -#endif /* _USE_LFN != 0 && !_FS_READONLY */ +#endif /* FF_USE_LFN && !FF_FS_READONLY */ -#if _USE_LFN != 0 +#if FF_USE_LFN /*-----------------------------------------------------------------------*/ /* FAT-LFN: Calculate checksum of an SFN entry */ /*-----------------------------------------------------------------------*/ -static -BYTE sum_sfn ( +static BYTE sum_sfn ( const BYTE* dir /* Pointer to the SFN entry */ ) { BYTE sum = 0; UINT n = 11; - do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + do { + sum = (sum >> 1) + (sum << 7) + *dir++; + } while (--n); return sum; } -#endif /* _USE_LFN != 0 */ +#endif /* FF_USE_LFN */ -#if _FS_EXFAT +#if FF_FS_EXFAT /*-----------------------------------------------------------------------*/ /* exFAT: Checksum */ /*-----------------------------------------------------------------------*/ -static -WORD xdir_sum ( /* Get checksum of the directoly block */ +static WORD xdir_sum ( /* Get checksum of the directoly entry block */ const BYTE* dir /* Directory entry block to be calculated */ ) { @@ -1809,9 +2037,9 @@ WORD xdir_sum ( /* Get checksum of the directoly block */ WORD sum; - szblk = (dir[XDIR_NumSec] + 1) * SZDIRE; + szblk = (dir[XDIR_NumSec] + 1) * SZDIRE; /* Number of bytes of the entry block */ for (i = sum = 0; i < szblk; i++) { - if (i == XDIR_SetSum) { /* Skip sum field */ + if (i == XDIR_SetSum) { /* Skip 2-byte sum field */ i++; } else { sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + dir[i]; @@ -1822,8 +2050,7 @@ WORD xdir_sum ( /* Get checksum of the directoly block */ -static -WORD xname_sum ( /* Get check sum (to be used as hash) of the name */ +static WORD xname_sum ( /* Get check sum (to be used as hash) of the file name */ const WCHAR* name /* File name to be calculated */ ) { @@ -1832,7 +2059,7 @@ WORD xname_sum ( /* Get check sum (to be used as hash) of the name */ while ((chr = *name++) != 0) { - chr = ff_wtoupper(chr); /* File name needs to be ignored case */ + chr = (WCHAR)ff_wtoupper(chr); /* File name needs to be up-case converted */ sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr & 0xFF); sum = ((sum & 1) ? 0x8000 : 0) + (sum >> 1) + (chr >> 8); } @@ -1840,11 +2067,10 @@ WORD xname_sum ( /* Get check sum (to be used as hash) of the name */ } -#if !_FS_READONLY && _USE_MKFS -static -DWORD xsum32 ( - BYTE dat, /* Data to be sumed */ - DWORD sum /* Previous value */ +#if !FF_FS_READONLY && FF_USE_MKFS +static DWORD xsum32 ( /* Returns 32-bit checksum */ + BYTE dat, /* Byte to be calculated (byte-by-byte processing) */ + DWORD sum /* Previous sum value */ ) { sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat; @@ -1853,130 +2079,137 @@ DWORD xsum32 ( #endif -#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 /*------------------------------------------------------*/ /* exFAT: Get object information from a directory block */ /*------------------------------------------------------*/ -static -void get_xdir_info ( +static void get_xfileinfo ( BYTE* dirb, /* Pointer to the direcotry entry block 85+C0+C1s */ FILINFO* fno /* Buffer to store the extracted file information */ ) { - UINT di, si; - WCHAR w; -#if !_LFN_UNICODE - UINT nc; -#endif + WCHAR wc, hs; + UINT di, si, nc; - /* Get file name */ -#if _LFN_UNICODE - if (dirb[XDIR_NumName] <= _MAX_LFN) { - for (si = SZDIRE * 2, di = 0; di < dirb[XDIR_NumName]; si += 2, di++) { - if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ - w = ld_word(dirb + si); /* Get a character */ - fno->fname[di] = w; /* Store it */ + /* Get file name from the entry block */ + si = SZDIRE * 2; /* 1st C1 entry */ + nc = 0; hs = 0; di = 0; + while (nc < dirb[XDIR_NumName]) { + if (si >= MAXDIRB(FF_MAX_LFN)) { di = 0; break; } /* Truncated directory block? */ + if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ + wc = ld_word(dirb + si); si += 2; nc++; /* Get a character */ + if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ + hs = wc; continue; /* Get low surrogate */ } - } else { - di = 0; /* Buffer overflow and inaccessible object */ + wc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in API encoding */ + if (wc == 0) { di = 0; break; } /* Buffer overflow or wrong encoding? */ + di += wc; + hs = 0; } -#else - for (si = SZDIRE * 2, di = nc = 0; nc < dirb[XDIR_NumName]; si += 2, nc++) { - if ((si % SZDIRE) == 0) si += 2; /* Skip entry type field */ - w = ld_word(dirb + si); /* Get a character */ - w = ff_convert(w, 0); /* Unicode -> OEM */ - if (w == 0) { di = 0; break; } /* Could not be converted and inaccessible object */ - if (_DF1S && w >= 0x100) { /* Put 1st byte if it is a DBC (always false at SBCS cfg) */ - fno->fname[di++] = (char)(w >> 8); - } - if (di >= _MAX_LFN) { di = 0; break; } /* Buffer overflow and inaccessible object */ - fno->fname[di++] = (char)w; - } -#endif - if (di == 0) fno->fname[di++] = '?'; /* Inaccessible object? */ - fno->fname[di] = 0; /* Terminate file name */ + if (hs != 0) di = 0; /* Broken surrogate pair? */ + if (di == 0) fno->fname[di++] = '?'; /* Inaccessible object name? */ + fno->fname[di] = 0; /* Terminate the name */ + fno->altname[0] = 0; /* exFAT does not support SFN */ - fno->altname[0] = 0; /* No SFN */ - fno->fattrib = dirb[XDIR_Attr]; /* Attribute */ + fno->fattrib = dirb[XDIR_Attr]; /* Attribute */ fno->fsize = (fno->fattrib & AM_DIR) ? 0 : ld_qword(dirb + XDIR_FileSize); /* Size */ fno->ftime = ld_word(dirb + XDIR_ModTime + 0); /* Time */ fno->fdate = ld_word(dirb + XDIR_ModTime + 2); /* Date */ } -#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 */ +#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ /*-----------------------------------*/ /* exFAT: Get a directry entry block */ /*-----------------------------------*/ -static -FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ - DIR* dp /* Pointer to the reading direcotry object pointing the 85 entry */ +static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ + DIR* dp /* Reading direcotry object pointing top of the entry block to load */ ) { FRESULT res; - UINT i, nent; + UINT i, sz_ent; BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ - /* Load 85 entry */ + /* Load file-directory entry */ res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0x85) return FR_INT_ERR; - mem_cpy(dirb, dp->dir, SZDIRE); - nent = dirb[XDIR_NumSec] + 1; + if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */ + mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); + sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; + if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; - /* Load C0 entry */ + /* Load stream-extension entry */ res = dir_next(dp, 0); + if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC0) return FR_INT_ERR; - mem_cpy(dirb + SZDIRE, dp->dir, SZDIRE); + if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */ + mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); + if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; - /* Load C1 entries */ - if (nent < 3 || nent > 19) return FR_NO_FILE; - i = SZDIRE * 2; nent *= SZDIRE; + /* Load file-name entries */ + i = 2 * SZDIRE; /* Name offset to load */ do { res = dir_next(dp, 0); + if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC1) return FR_INT_ERR; - mem_cpy(dirb + i, dp->dir, SZDIRE); - i += SZDIRE; - } while (i < nent); - - /* Sanity check */ - if (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR; + if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */ + if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE); + } while ((i += SZDIRE) < sz_ent); + /* Sanity check (do it for only accessible object) */ + if (i <= MAXDIRB(FF_MAX_LFN)) { + if (xdir_sum(dirb) != ld_word(dirb + XDIR_SetSum)) return FR_INT_ERR; + } return FR_OK; } -#if !_FS_READONLY || _FS_RPATH != 0 +/*------------------------------------------------------------------*/ +/* exFAT: Initialize object allocation info with loaded entry block */ +/*------------------------------------------------------------------*/ + +static void init_alloc_info ( + FATFS* fs, /* Filesystem object */ + FFOBJID* obj /* Object allocation information to be initialized */ +) +{ + obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Start cluster */ + obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); /* Size */ + obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; /* Allocation status */ + obj->n_frag = 0; /* No last fragment info */ +} + + + +#if !FF_FS_READONLY || FF_FS_RPATH != 0 /*------------------------------------------------*/ /* exFAT: Load the object's directory entry block */ /*------------------------------------------------*/ -static -FRESULT load_obj_dir ( + +static FRESULT load_obj_xdir ( DIR* dp, /* Blank directory object to be used to access containing direcotry */ - const _FDID* obj /* Object with containing directory information */ + const FFOBJID* obj /* Object with its containing directory information */ ) { FRESULT res; - /* Open object containing directory */ dp->obj.fs = obj->fs; dp->obj.sclust = obj->c_scl; dp->obj.stat = (BYTE)obj->c_size; dp->obj.objsize = obj->c_size & 0xFFFFFF00; + dp->obj.n_frag = 0; dp->blk_ofs = obj->c_ofs; - res = dir_sdi(dp, dp->blk_ofs); /* Goto the block location */ + res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */ if (res == FR_OK) { res = load_xdir(dp); /* Load the object's entry block */ } @@ -1985,12 +2218,12 @@ FRESULT load_obj_dir ( #endif -#if !_FS_READONLY -/*-----------------------------------------------*/ -/* exFAT: Store the directory block to the media */ -/*-----------------------------------------------*/ -static -FRESULT store_xdir ( +#if !FF_FS_READONLY +/*----------------------------------------*/ +/* exFAT: Store the directory entry block */ +/*----------------------------------------*/ + +static FRESULT store_xdir ( DIR* dp /* Pointer to the direcotry object */ ) { @@ -2002,7 +2235,7 @@ FRESULT store_xdir ( st_word(dirb + XDIR_SetSum, xdir_sum(dirb)); nent = dirb[XDIR_NumSec] + 1; - /* Store the set of directory to the volume */ + /* Store the direcotry entry block to the directory */ res = dir_sdi(dp, dp->blk_ofs); while (res == FR_OK) { res = move_window(dp->obj.fs, dp->sect); @@ -2022,71 +2255,77 @@ FRESULT store_xdir ( /* exFAT: Create a new directory enrty block */ /*-------------------------------------------*/ -static -void create_xdir ( +static void create_xdir ( BYTE* dirb, /* Pointer to the direcotry entry block buffer */ - const WCHAR* lfn /* Pointer to the nul terminated file name */ + const WCHAR* lfn /* Pointer to the object name */ ) { UINT i; - BYTE nb, nc; - WCHAR chr; + BYTE nc1, nlen; + WCHAR wc; - mem_set(dirb, 0, 2 * SZDIRE); /* Initialize 85+C0 entry */ - dirb[XDIR_Type] = 0x85; - dirb[XDIR_Type + SZDIRE] = 0xC0; - st_word(dirb + XDIR_NameHash, xname_sum(lfn)); /* Set name hash */ + /* Create file-directory and stream-extension entry */ + mem_set(dirb, 0, 2 * SZDIRE); + dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR; + dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM; - i = SZDIRE * 2; /* C1 offset */ - nc = 0; nb = 1; chr = 1; + /* Create file-name entries */ + i = SZDIRE * 2; /* Top of file_name entries */ + nlen = nc1 = 0; wc = 1; do { - dirb[i++] = 0xC1; dirb[i++] = 0; /* Entry type C1 */ + dirb[i++] = ET_FILENAME; dirb[i++] = 0; do { /* Fill name field */ - if (chr && (chr = lfn[nc]) != 0) nc++; /* Get a character if exist */ - st_word(dirb + i, chr); i += 2; /* Store it */ - } while (i % SZDIRE); - nb++; - } while (lfn[nc]); /* Fill next entry if any char follows */ + if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ + st_word(dirb + i, wc); /* Store it */ + i += 2; + } while (i % SZDIRE != 0); + nc1++; + } while (lfn[nlen]); /* Fill next entry if any char follows */ - dirb[XDIR_NumName] = nc; /* Set name length */ - dirb[XDIR_NumSec] = nb; /* Set number of C0+C1s */ + dirb[XDIR_NumName] = nlen; /* Set name length */ + dirb[XDIR_NumSec] = 1 + nc1; /* Set secondary count (C0 + C1s) */ + st_word(dirb + XDIR_NameHash, xname_sum(lfn)); /* Set name hash */ } -#endif /* !_FS_READONLY */ -#endif /* _FS_EXFAT */ +#endif /* !FF_FS_READONLY */ +#endif /* FF_FS_EXFAT */ -#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 || _USE_LABEL || _FS_EXFAT +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 || FF_USE_LABEL || FF_FS_EXFAT /*-----------------------------------------------------------------------*/ /* Read an object from the directory */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_read ( +#define DIR_READ_FILE(dp) dir_read(dp, 0) +#define DIR_READ_LABEL(dp) dir_read(dp, 1) + +static FRESULT dir_read ( DIR* dp, /* Pointer to the directory object */ int vol /* Filtered by 0:file/directory or 1:volume label */ ) { FRESULT res = FR_NO_FILE; FATFS *fs = dp->obj.fs; - BYTE a, c; -#if _USE_LFN != 0 + BYTE attr, b; +#if FF_USE_LFN BYTE ord = 0xFF, sum = 0xFF; #endif while (dp->sect) { res = move_window(fs, dp->sect); if (res != FR_OK) break; - c = dp->dir[DIR_Name]; /* Test for the entry type */ - if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of the directory */ -#if _FS_EXFAT + b = dp->dir[DIR_Name]; /* Test for the entry type */ + if (b == 0) { + res = FR_NO_FILE; break; /* Reached to end of the directory */ + } +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - if (_USE_LABEL && vol) { - if (c == 0x83) break; /* Volume label entry? */ + if (FF_USE_LABEL && vol) { + if (b == ET_VLABEL) break; /* Volume label entry? */ } else { - if (c == 0x85) { /* Start of the file entry block? */ + if (b == ET_FILEDIR) { /* Start of the file entry block? */ dp->blk_ofs = dp->dptr; /* Get location of the block */ res = load_xdir(dp); /* Load the entry block */ if (res == FR_OK) { @@ -2097,29 +2336,29 @@ FRESULT dir_read ( } } else #endif - { /* On the FAT12/16/32 volume */ - dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ -#if _USE_LFN != 0 /* LFN configuration */ - if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ + { /* On the FAT/FAT32 volume */ + dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ +#if FF_USE_LFN /* LFN configuration */ + if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ ord = 0xFF; } else { - if (a == AM_LFN) { /* An LFN entry is found */ - if (c & LLEF) { /* Is it start of an LFN sequence? */ + if (attr == AM_LFN) { /* An LFN entry is found */ + if (b & LLEF) { /* Is it start of an LFN sequence? */ sum = dp->dir[LDIR_Chksum]; - c &= (BYTE)~LLEF; ord = c; + b &= (BYTE)~LLEF; ord = b; dp->blk_ofs = dp->dptr; } /* Check LFN validity and capture it */ - ord = (c == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; + ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } else { /* An SFN entry is found */ - if (ord || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ + if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ } break; } } #else /* Non LFN configuration */ - if (c != DDEM && c != '.' && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ + if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ break; } #endif @@ -2132,7 +2371,7 @@ FRESULT dir_read ( return res; } -#endif /* _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 */ +#endif /* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */ @@ -2140,28 +2379,30 @@ FRESULT dir_read ( /* Directory handling - Find an object in the directory */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ - DIR* dp /* Pointer to the directory object with the file name */ +static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ + DIR* dp /* Pointer to the directory object with the file name */ ) { FRESULT res; FATFS *fs = dp->obj.fs; BYTE c; -#if _USE_LFN != 0 +#if FF_USE_LFN BYTE a, ord, sum; #endif res = dir_sdi(dp, 0); /* Rewind directory object */ if (res != FR_OK) return res; -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ BYTE nc; UINT di, ni; WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ - while ((res = dir_read(dp, 0)) == FR_OK) { /* Read an item */ - if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip the comparison if hash value mismatched */ + while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */ +#if FF_MAX_LFN < 255 + if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ +#endif + if (ld_word(fs->dirbuf + XDIR_NameHash) != hash) continue; /* Skip comparison if hash mismatched */ for (nc = fs->dirbuf[XDIR_NumName], di = SZDIRE * 2, ni = 0; nc; nc--, di += 2, ni++) { /* Compare the name */ if ((di % SZDIRE) == 0) di += 2; if (ff_wtoupper(ld_word(fs->dirbuf + di)) != ff_wtoupper(fs->lfnbuf[ni])) break; @@ -2171,8 +2412,8 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ return res; } #endif - /* On the FAT12/16/32 volume */ -#if _USE_LFN != 0 + /* On the FAT/FAT32 volume */ +#if FF_USE_LFN ord = sum = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ #endif do { @@ -2180,7 +2421,7 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ if (res != FR_OK) break; c = dp->dir[DIR_Name]; if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ -#if _USE_LFN != 0 /* LFN configuration */ +#if FF_USE_LFN /* LFN configuration */ dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ @@ -2196,7 +2437,7 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ ord = (c == ord && sum == dp->dir[LDIR_Chksum] && cmp_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } } else { /* An SFN entry is found */ - if (!ord && sum == sum_sfn(dp->dir)) break; /* LFN matched? */ + if (ord == 0 && sum == sum_sfn(dp->dir)) break; /* LFN matched? */ if (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dp->dir, dp->fn, 11)) break; /* SFN matched? */ ord = 0xFF; dp->blk_ofs = 0xFFFFFFFF; /* Reset LFN sequence */ } @@ -2214,19 +2455,18 @@ FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Register an object to the directory */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */ - DIR* dp /* Target directory with object name to be created */ +static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */ + DIR* dp /* Target directory with object name to be created */ ) { FRESULT res; FATFS *fs = dp->obj.fs; -#if _USE_LFN != 0 /* LFN configuration */ +#if FF_USE_LFN /* LFN configuration */ UINT n, nlen, nent; BYTE sn[12], sum; @@ -2234,34 +2474,38 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many if (dp->fn[NSFLAG] & (NS_DOT | NS_NONAME)) return FR_INVALID_NAME; /* Check name validity */ for (nlen = 0; fs->lfnbuf[nlen]; nlen++) ; /* Get lfn length */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - DIR dj; - nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ - res = dir_alloc(dp, nent); /* Allocate entries */ + res = dir_alloc(dp, nent); /* Allocate directory entries */ if (res != FR_OK) return res; - dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set block position */ + dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */ - if (dp->obj.sclust != 0 && (dp->obj.stat & 4)) { /* Has the sub-directory been stretched? */ - dp->obj.stat &= 3; - dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase object size by cluster size */ - res = fill_fat_chain(&dp->obj); /* Complement FAT chain if needed */ + if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */ + dp->obj.stat &= ~4; + res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ if (res != FR_OK) return res; - res = load_obj_dir(&dj, &dp->obj); - if (res != FR_OK) return res; /* Load the object status */ - st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */ - st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize); - fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; - res = store_xdir(&dj); /* Store the object status */ + res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ if (res != FR_OK) return res; + if (dp->obj.sclust != 0) { /* Is it a sub-directory? */ + DIR dj; + + res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ + if (res != FR_OK) return res; + dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */ + st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */ + st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize); + fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1; + res = store_xdir(&dj); /* Store the object status */ + if (res != FR_OK) return res; + } } create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */ return FR_OK; } #endif - /* On the FAT12/16/32 volume */ + /* On the FAT/FAT32 volume */ mem_cpy(sn, dp->fn, 12); if (sn[NSFLAG] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ dp->fn[NSFLAG] = NS_NOLFN; /* Find only SFN */ @@ -2303,7 +2547,7 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many if (res == FR_OK) { mem_set(dp->dir, 0, SZDIRE); /* Clean the entry */ mem_cpy(dp->dir + DIR_Name, dp->fn, 11); /* Put SFN */ -#if _USE_LFN != 0 +#if FF_USE_LFN dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT); /* Put NT flag */ #endif fs->wflag = 1; @@ -2313,23 +2557,22 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many return res; } -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ -#if !_FS_READONLY && _FS_MINIMIZE == 0 +#if !FF_FS_READONLY && FF_FS_MINIMIZE == 0 /*-----------------------------------------------------------------------*/ /* Remove an object from the directory */ /*-----------------------------------------------------------------------*/ -static -FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ - DIR* dp /* Directory object pointing the entry to be removed */ +static FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ + DIR* dp /* Directory object pointing the entry to be removed */ ) { FRESULT res; FATFS *fs = dp->obj.fs; -#if _USE_LFN != 0 /* LFN configuration */ +#if FF_USE_LFN /* LFN configuration */ DWORD last = dp->dptr; res = (dp->blk_ofs == 0xFFFFFFFF) ? FR_OK : dir_sdi(dp, dp->blk_ofs); /* Goto top of the entry block if LFN is exist */ @@ -2337,11 +2580,10 @@ FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ do { res = move_window(fs, dp->sect); if (res != FR_OK) break; - /* Mark an entry 'deleted' */ - if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - dp->dir[XDIR_Type] &= 0x7F; - } else { /* On the FAT12/16/32 volume */ - dp->dir[DIR_Name] = DDEM; + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ + dp->dir[XDIR_Type] &= 0x7F; /* Clear the entry InUse flag. */ + } else { /* On the FAT/FAT32 volume */ + dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'. */ } fs->wflag = 1; if (dp->dptr >= last) break; /* If reached last entry then all entries of the object has been deleted. */ @@ -2353,7 +2595,7 @@ FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ res = move_window(fs, dp->sect); if (res == FR_OK) { - dp->dir[DIR_Name] = DDEM; + dp->dir[DIR_Name] = DDEM; /* Mark the entry 'deleted'.*/ fs->wflag = 1; } #endif @@ -2361,143 +2603,153 @@ FRESULT dir_remove ( /* FR_OK:Succeeded, FR_DISK_ERR:A disk error */ return res; } -#endif /* !_FS_READONLY && _FS_MINIMIZE == 0 */ +#endif /* !FF_FS_READONLY && FF_FS_MINIMIZE == 0 */ -#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 +#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 /*-----------------------------------------------------------------------*/ /* Get file information from directory entry */ /*-----------------------------------------------------------------------*/ -static -void get_fileinfo ( /* No return code */ +static void get_fileinfo ( DIR* dp, /* Pointer to the directory object */ FILINFO* fno /* Pointer to the file information to be filled */ ) { - UINT i, j; - TCHAR c; - DWORD tm; -#if _USE_LFN != 0 - WCHAR w, lfv; + UINT si, di; +#if FF_USE_LFN + BYTE lcf; + WCHAR wc, hs; FATFS *fs = dp->obj.fs; +#else + TCHAR c; #endif - fno->fname[0] = 0; /* Invaidate file info */ - if (!dp->sect) return; /* Exit if read pointer has reached end of directory */ + fno->fname[0] = 0; /* Invaidate file info */ + if (dp->sect == 0) return; /* Exit if read pointer has reached end of directory */ -#if _USE_LFN != 0 /* LFN configuration */ -#if _FS_EXFAT +#if FF_USE_LFN /* LFN configuration */ +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - get_xdir_info(fs->dirbuf, fno); + get_xfileinfo(fs->dirbuf, fno); return; } else #endif - { /* On the FAT12/16/32 volume */ + { /* On the FAT/FAT32 volume */ if (dp->blk_ofs != 0xFFFFFFFF) { /* Get LFN if available */ - i = j = 0; - while ((w = fs->lfnbuf[j++]) != 0) { /* Get an LFN character */ -#if !_LFN_UNICODE - w = ff_convert(w, 0); /* Unicode -> OEM */ - if (w == 0) { i = 0; break; } /* No LFN if it could not be converted */ - if (_DF1S && w >= 0x100) { /* Put 1st byte if it is a DBC (always false at SBCS cfg) */ - fno->fname[i++] = (char)(w >> 8); + si = di = hs = 0; + while (fs->lfnbuf[si] != 0) { + wc = fs->lfnbuf[si++]; /* Get an LFN character (UTF-16) */ + if (hs == 0 && IsSurrogate(wc)) { /* Is it a surrogate? */ + hs = wc; continue; /* Get low surrogate */ } -#endif - if (i >= _MAX_LFN) { i = 0; break; } /* No LFN if buffer overflow */ - fno->fname[i++] = (TCHAR)w; + wc = put_utf((DWORD)hs << 16 | wc, &fno->fname[di], FF_LFN_BUF - di); /* Store it in UTF-16 or UTF-8 encoding */ + if (wc == 0) { di = 0; break; } /* Invalid char or buffer overflow? */ + di += wc; + hs = 0; } - fno->fname[i] = 0; /* Terminate the LFN */ + if (hs != 0) di = 0; /* Broken surrogate pair? */ + fno->fname[di] = 0; /* Terminate the LFN (null string means LFN is invalid) */ } } - i = j = 0; - lfv = fno->fname[i]; /* LFN is exist if non-zero */ - while (i < 11) { /* Copy name body and extension */ - c = (TCHAR)dp->dir[i++]; - if (c == ' ') continue; /* Skip padding spaces */ - if (c == RDDEM) c = (TCHAR)DDEM; /* Restore replaced DDEM character */ - if (i == 9) { /* Insert a . if extension is exist */ - if (!lfv) fno->fname[j] = '.'; - fno->altname[j++] = '.'; + si = di = 0; + while (si < 11) { /* Get SFN from SFN entry */ + wc = dp->dir[si++]; /* Get a char */ + if (wc == ' ') continue; /* Skip padding spaces */ + if (wc == RDDEM) wc = DDEM; /* Restore replaced DDEM character */ + if (si == 9 && di < FF_SFN_BUF) fno->altname[di++] = '.'; /* Insert a . if extension is exist */ +#if FF_LFN_UNICODE >= 1 /* Unicode output */ + if (dbc_1st((BYTE)wc) && si != 8 && si != 11 && dbc_2nd(dp->dir[si])) { /* Make a DBC if needed */ + wc = wc << 8 | dp->dir[si++]; } -#if _LFN_UNICODE - if (IsDBCS1(c) && i != 8 && i != 11 && IsDBCS2(dp->dir[i])) { - c = c << 8 | dp->dir[i++]; - } - c = ff_convert(c, 1); /* OEM -> Unicode */ - if (!c) c = '?'; + wc = ff_oem2uni(wc, CODEPAGE); /* ANSI/OEM -> Unicode */ + if (wc == 0) { di = 0; break; } /* Wrong char in the current code page? */ + wc = put_utf(wc, &fno->altname[di], FF_SFN_BUF - di); /* Store it in Unicode */ + if (wc == 0) { di = 0; break; } /* Buffer overflow? */ + di += wc; +#else /* ANSI/OEM output */ + fno->altname[di++] = (TCHAR)wc; /* Store it without any conversion */ #endif - fno->altname[j] = c; - if (!lfv) { - if (IsUpper(c) && (dp->dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY))) { - c += 0x20; /* To lower */ + } + fno->altname[di] = 0; /* Terminate the SFN (null string means SFN is invalid) */ + + if (fno->fname[0] == 0) { /* If LFN is invalid, altname[] needs to be copied to fname[] */ + if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */ + fno->fname[di++] = '?'; + } else { + for (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ + wc = (WCHAR)fno->altname[si]; + if (wc == '.') lcf = NS_EXT; + if (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20; + fno->fname[di] = (TCHAR)wc; } - fno->fname[j] = c; } - j++; + fno->fname[di] = 0; /* Terminate the LFN */ + if (!dp->dir[DIR_NTres]) fno->altname[0] = 0; /* Altname is not needed if neither LFN nor case info is exist. */ } - if (!lfv) { - fno->fname[j] = 0; - if (!dp->dir[DIR_NTres]) j = 0; /* Altname is no longer needed if neither LFN nor case info is exist. */ - } - fno->altname[j] = 0; /* Terminate the SFN */ #else /* Non-LFN configuration */ - i = j = 0; - while (i < 11) { /* Copy name body and extension */ - c = (TCHAR)dp->dir[i++]; - if (c == ' ') continue; /* Skip padding spaces */ - if (c == RDDEM) c = (TCHAR)DDEM; /* Restore replaced DDEM character */ - if (i == 9) fno->fname[j++] = '.'; /* Insert a . if extension is exist */ - fno->fname[j++] = c; + si = di = 0; + while (si < 11) { /* Copy name body and extension */ + c = (TCHAR)dp->dir[si++]; + if (c == ' ') continue; /* Skip padding spaces */ + if (c == RDDEM) c = DDEM; /* Restore replaced DDEM character */ + if (si == 9) fno->fname[di++] = '.';/* Insert a . if extension is exist */ + fno->fname[di++] = c; } - fno->fname[j] = 0; + fno->fname[di] = 0; #endif - fno->fattrib = dp->dir[DIR_Attr]; /* Attribute */ - fno->fsize = ld_dword(dp->dir + DIR_FileSize); /* Size */ - tm = ld_dword(dp->dir + DIR_ModTime); /* Timestamp */ - fno->ftime = (WORD)tm; fno->fdate = (WORD)(tm >> 16); + fno->fattrib = dp->dir[DIR_Attr]; /* Attribute */ + fno->fsize = ld_dword(dp->dir + DIR_FileSize); /* Size */ + fno->ftime = ld_word(dp->dir + DIR_ModTime + 0); /* Time */ + fno->fdate = ld_word(dp->dir + DIR_ModTime + 2); /* Date */ } -#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 */ +#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */ -#if _USE_FIND && _FS_MINIMIZE <= 1 +#if FF_USE_FIND && FF_FS_MINIMIZE <= 1 /*-----------------------------------------------------------------------*/ /* Pattern matching */ /*-----------------------------------------------------------------------*/ -static -WCHAR get_achar ( /* Get a character and advances ptr 1 or 2 */ - const TCHAR** ptr /* Pointer to pointer to the SBCS/DBCS/Unicode string */ +static DWORD get_achar ( /* Get a character and advances ptr */ + const TCHAR** ptr /* Pointer to pointer to the ANSI/OEM or Unicode string */ ) { -#if !_LFN_UNICODE - WCHAR chr; + DWORD chr; - chr = (BYTE)*(*ptr)++; /* Get a byte */ - if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ -#ifdef _EXCVT + +#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode input */ + chr = tchar2uni(ptr); + if (chr == 0xFFFFFFFF) chr = 0; /* Wrong UTF encoding is recognized as end of the string */ + chr = ff_wtoupper(chr); + +#else /* ANSI/OEM input */ + chr = (BYTE)*(*ptr)++; /* Get a byte */ + if (IsLower(chr)) chr -= 0x20; /* To upper ASCII char */ +#if FF_CODE_PAGE == 0 + if (ExCvt && chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ +#elif FF_CODE_PAGE < 900 if (chr >= 0x80) chr = ExCvt[chr - 0x80]; /* To upper SBCS extended char */ -#else - if (IsDBCS1(chr) && IsDBCS2(**ptr)) { /* Get DBC 2nd byte if needed */ - chr = chr << 8 | (BYTE)*(*ptr)++; +#endif +#if FF_CODE_PAGE == 0 || FF_CODE_PAGE >= 900 + if (dbc_1st((BYTE)chr)) { /* Get DBC 2nd byte if needed */ + chr = dbc_2nd((BYTE)**ptr) ? chr << 8 | (BYTE)*(*ptr)++ : 0; } #endif - return chr; -#else - return ff_wtoupper(*(*ptr)++); /* Get a word and to upper */ + #endif + return chr; } -static -int pattern_matching ( /* 0:not matched, 1:matched */ +static int pattern_matching ( /* 0:not matched, 1:matched */ const TCHAR* pat, /* Matching pattern */ const TCHAR* nam, /* String to be tested */ int skip, /* Number of pre-skip chars (number of ?s) */ @@ -2505,21 +2757,21 @@ int pattern_matching ( /* 0:not matched, 1:matched */ ) { const TCHAR *pp, *np; - WCHAR pc, nc; + DWORD pc, nc; int nm, nx; while (skip--) { /* Pre-skip name chars */ if (!get_achar(&nam)) return 0; /* Branch mismatched if less name chars */ } - if (!*pat && inf) return 1; /* (short circuit) */ + if (*pat == 0 && inf) return 1; /* (short circuit) */ do { pp = pat; np = nam; /* Top of pattern and name to match */ for (;;) { if (*pp == '?' || *pp == '*') { /* Wildcard? */ nm = nx = 0; - do { /* Analyze the wildcard chars */ + do { /* Analyze the wildcard block */ if (*pp++ == '?') nm++; else nx = 1; } while (*pp == '?' || *pp == '*'); if (pattern_matching(pp, np, nm, nx)) return 1; /* Test new branch (recurs upto number of wildcard blocks in the pattern) */ @@ -2536,7 +2788,7 @@ int pattern_matching ( /* 0:not matched, 1:matched */ return 0; } -#endif /* _USE_FIND && _FS_MINIMIZE <= 1 */ +#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */ @@ -2544,131 +2796,133 @@ int pattern_matching ( /* 0:not matched, 1:matched */ /* Pick a top segment and create the object name in directory form */ /*-----------------------------------------------------------------------*/ -static -FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ - DIR* dp, /* Pointer to the directory object */ - const TCHAR** path /* Pointer to pointer to the segment in the path string */ +static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create */ + DIR* dp, /* Pointer to the directory object */ + const TCHAR** path /* Pointer to pointer to the segment in the path string */ ) { -#if _USE_LFN != 0 /* LFN configuration */ +#if FF_USE_LFN /* LFN configuration */ BYTE b, cf; - WCHAR w, *lfn; + WCHAR wc, *lfn; + DWORD uc; UINT i, ni, si, di; const TCHAR *p; - /* Create LFN in Unicode */ - p = *path; lfn = dp->obj.fs->lfnbuf; si = di = 0; + + /* Create LFN into LFN working buffer */ + p = *path; lfn = dp->obj.fs->lfnbuf; di = 0; for (;;) { - w = p[si++]; /* Get a character */ - if (w < ' ') break; /* Break if end of the path name */ - if (w == '/' || w == '\\') { /* Break if a separator is found */ - while (p[si] == '/' || p[si] == '\\') si++; /* Skip duplicated separator if exist */ - break; - } - if (di >= _MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ -#if !_LFN_UNICODE - w &= 0xFF; - if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ - b = (BYTE)p[si++]; /* Get 2nd byte */ - w = (w << 8) + b; /* Create a DBC */ - if (!IsDBCS2(b)) return FR_INVALID_NAME; /* Reject invalid sequence */ - } - w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */ - if (!w) return FR_INVALID_NAME; /* Reject invalid code */ -#endif - if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ - lfn[di++] = w; /* Store the Unicode character */ + uc = tchar2uni(&p); /* Get a character */ + if (uc == 0xFFFFFFFF) return FR_INVALID_NAME; /* Invalid code or UTF decode error */ + if (uc >= 0x10000) lfn[di++] = (WCHAR)(uc >> 16); /* Store high surrogate if needed */ + wc = (WCHAR)uc; + if (wc < ' ' || wc == '/' || wc == '\\') break; /* Break if end of the path or a separator is found */ + if (wc < 0x80 && chk_chr("\"*:<>\?|\x7F", wc)) return FR_INVALID_NAME; /* Reject illegal characters for LFN */ + if (di >= FF_MAX_LFN) return FR_INVALID_NAME; /* Reject too long name */ + lfn[di++] = wc; /* Store the Unicode character */ } - *path = &p[si]; /* Return pointer to the next segment */ - cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ -#if _FS_RPATH != 0 + while (*p == '/' || *p == '\\') p++; /* Skip duplicated separators if exist */ + *path = p; /* Return pointer to the next segment */ + cf = (wc < ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ + +#if FF_FS_RPATH != 0 if ((di == 1 && lfn[di - 1] == '.') || (di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) { /* Is this segment a dot name? */ lfn[di] = 0; - for (i = 0; i < 11; i++) /* Create dot name for SFN entry */ + for (i = 0; i < 11; i++) { /* Create dot name for SFN entry */ dp->fn[i] = (i < di) ? '.' : ' '; + } dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ return FR_OK; } #endif while (di) { /* Snip off trailing spaces and dots if exist */ - w = lfn[di - 1]; - if (w != ' ' && w != '.') break; + wc = lfn[di - 1]; + if (wc != ' ' && wc != '.') break; di--; } - lfn[di] = 0; /* LFN is created */ - if (di == 0) return FR_INVALID_NAME; /* Reject nul name */ + lfn[di] = 0; /* LFN is created into the working buffer */ + if (di == 0) return FR_INVALID_NAME; /* Reject null name */ /* Create SFN in directory form */ - mem_set(dp->fn, ' ', 11); - for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ - if (si) cf |= NS_LOSS | NS_LFN; - while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + for (si = 0; lfn[si] == ' '; si++) ; /* Remove leading spaces */ + if (si > 0 || lfn[si] == '.') cf |= NS_LOSS | NS_LFN; /* Is there any leading space or dot? */ + while (di > 0 && lfn[di - 1] != '.') di--; /* Find last dot (di<=si: no extension) */ + mem_set(dp->fn, ' ', 11); i = b = 0; ni = 8; for (;;) { - w = lfn[si++]; /* Get an LFN character */ - if (!w) break; /* Break on end of the LFN */ - if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ - cf |= NS_LOSS | NS_LFN; continue; + wc = lfn[si++]; /* Get an LFN character */ + if (wc == 0) break; /* Break on end of the LFN */ + if (wc == ' ' || (wc == '.' && si != di)) { /* Remove embedded spaces and dots */ + cf |= NS_LOSS | NS_LFN; + continue; } - if (i >= ni || si == di) { /* Extension or end of SFN */ - if (ni == 11) { /* Long extension */ - cf |= NS_LOSS | NS_LFN; break; + if (i >= ni || si == di) { /* End of field? */ + if (ni == 11) { /* Name extension overflow? */ + cf |= NS_LOSS | NS_LFN; + break; } - if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ - if (si > di) break; /* No extension */ - si = di; i = 8; ni = 11; /* Enter extension section */ - b <<= 2; continue; + if (si != di) cf |= NS_LOSS | NS_LFN; /* Name body overflow? */ + if (si > di) break; /* No name extension? */ + si = di; i = 8; ni = 11; b <<= 2; /* Enter name extension */ + continue; } - if (w >= 0x80) { /* Non ASCII character */ -#ifdef _EXCVT - w = ff_convert(w, 0); /* Unicode -> OEM code */ - if (w) w = ExCvt[w - 0x80]; /* Convert extended character to upper (SBCS) */ -#else - w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ + if (wc >= 0x80) { /* Is this a non-ASCII character? */ + cf |= NS_LFN; /* LFN entry needs to be created */ +#if FF_CODE_PAGE == 0 + if (ExCvt) { /* At SBCS */ + wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ + if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ + } else { /* At DBCS */ + wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Upper convert ==> ANSI/OEM code */ + } +#elif FF_CODE_PAGE < 900 /* SBCS cfg */ + wc = ff_uni2oem(wc, CODEPAGE); /* Unicode ==> ANSI/OEM code */ + if (wc & 0x80) wc = ExCvt[wc & 0x7F]; /* Convert extended character to upper (SBCS) */ +#else /* DBCS cfg */ + wc = ff_uni2oem(ff_wtoupper(wc), CODEPAGE); /* Unicode ==> Upper convert ==> ANSI/OEM code */ #endif - cf |= NS_LFN; /* Force create LFN entry */ } - if (_DF1S && w >= 0x100) { /* Is this DBC? (always false at SBCS cfg) */ - if (i >= ni - 1) { - cf |= NS_LOSS | NS_LFN; i = ni; continue; + if (wc >= 0x100) { /* Is this a DBC? */ + if (i >= ni - 1) { /* Field overflow? */ + cf |= NS_LOSS | NS_LFN; + i = ni; continue; /* Next field */ } - dp->fn[i++] = (BYTE)(w >> 8); + dp->fn[i++] = (BYTE)(wc >> 8); /* Put 1st byte */ } else { /* SBC */ - if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal characters for SFN */ - w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ + if (wc == 0 || chk_chr("+,;=[]", wc)) { /* Replace illegal characters for SFN if needed */ + wc = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ } else { - if (IsUpper(w)) { /* ASCII large capital */ + if (IsUpper(wc)) { /* ASCII upper case? */ b |= 2; - } else { - if (IsLower(w)) { /* ASCII small capital */ - b |= 1; w -= 0x20; - } + } + if (IsLower(wc)) { /* ASCII lower case? */ + b |= 1; wc -= 0x20; } } } - dp->fn[i++] = (BYTE)w; + dp->fn[i++] = (BYTE)wc; } if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */ - if (ni == 8) b <<= 2; - if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN; /* Create LFN entry when there are composite capitals */ - if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ - if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ - if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + if (ni == 8) b <<= 2; /* Shift capital flags if no extension */ + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) cf |= NS_LFN; /* LFN entry needs to be created if composite capitals */ + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ + if (b & 0x01) cf |= NS_EXT; /* NT flag (Extension has small capital letters only) */ + if (b & 0x04) cf |= NS_BODY; /* NT flag (Body has small capital letters only) */ } - dp->fn[NSFLAG] = cf; /* SFN is created */ + dp->fn[NSFLAG] = cf; /* SFN is created into dp->fn[] */ return FR_OK; -#else /* _USE_LFN != 0 : Non-LFN configuration */ +#else /* FF_USE_LFN : Non-LFN configuration */ BYTE c, d, *sfn; UINT ni, si, i; const char *p; @@ -2677,7 +2931,7 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create p = *path; sfn = dp->fn; mem_set(sfn, ' ', 11); si = i = 0; ni = 8; -#if _FS_RPATH != 0 +#if FF_FS_RPATH != 0 if (p[si] == '.') { /* Is this a dot entry? */ for (;;) { c = (BYTE)p[si++]; @@ -2691,29 +2945,29 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create } #endif for (;;) { - c = (BYTE)p[si++]; + c = (BYTE)p[si++]; /* Get a byte */ if (c <= ' ') break; /* Break if end of the path name */ if (c == '/' || c == '\\') { /* Break if a separator is found */ while (p[si] == '/' || p[si] == '\\') si++; /* Skip duplicated separator if exist */ break; } - if (c == '.' || i >= ni) { /* End of body or over size? */ - if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Over size or invalid dot */ - i = 8; ni = 11; /* Goto extension */ + if (c == '.' || i >= ni) { /* End of body or field overflow? */ + if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Field overflow or invalid dot? */ + i = 8; ni = 11; /* Enter file extension field */ continue; } - if (c >= 0x80) { /* Extended character? */ -#ifdef _EXCVT - c = ExCvt[c - 0x80]; /* To upper extended characters (SBCS cfg) */ -#else -#if !_DF1S - return FR_INVALID_NAME; /* Reject extended characters (ASCII only cfg) */ -#endif -#endif +#if FF_CODE_PAGE == 0 + if (ExCvt && c >= 0x80) { /* Is SBC extended character? */ + c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ } - if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false at SBCS cfg.) */ +#elif FF_CODE_PAGE < 900 + if (c >= 0x80) { /* Is SBC extended character? */ + c = ExCvt[c & 0x7F]; /* To upper SBC extended character */ + } +#endif + if (dbc_1st(c)) { /* Check if it is a DBC 1st byte */ d = (BYTE)p[si++]; /* Get 2nd byte */ - if (!IsDBCS2(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */ + if (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */ sfn[i++] = c; sfn[i++] = d; } else { /* SBC */ @@ -2729,7 +2983,7 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create sfn[NSFLAG] = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */ return FR_OK; -#endif /* _USE_LFN != 0 */ +#endif /* FF_USE_LFN */ } @@ -2739,39 +2993,40 @@ FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not create /* Follow a file path */ /*-----------------------------------------------------------------------*/ -static -FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ - DIR* dp, /* Directory object to return last directory and found object */ - const TCHAR* path /* Full-path string to find a file or directory */ +static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR* dp, /* Directory object to return last directory and found object */ + const TCHAR* path /* Full-path string to find a file or directory */ ) { FRESULT res; BYTE ns; - _FDID *obj = &dp->obj; - FATFS *fs = obj->fs; + FATFS *fs = dp->obj.fs; -#if _FS_RPATH != 0 +#if FF_FS_RPATH != 0 if (*path != '/' && *path != '\\') { /* Without heading separator */ - obj->sclust = fs->cdir; /* Start from the current directory */ + dp->obj.sclust = fs->cdir; /* Start from current directory */ } else #endif { /* With heading separator */ while (*path == '/' || *path == '\\') path++; /* Strip heading separator */ - obj->sclust = 0; /* Start from the root directory */ + dp->obj.sclust = 0; /* Start from root directory */ } -#if _FS_EXFAT && _FS_RPATH != 0 - if (fs->fs_type == FS_EXFAT && obj->sclust) { /* Retrieve the sub-directory status if needed */ +#if FF_FS_EXFAT + dp->obj.n_frag = 0; /* Invalidate last fragment counter of the object */ +#if FF_FS_RPATH != 0 + if (fs->fs_type == FS_EXFAT && dp->obj.sclust) { /* exFAT: Retrieve the sub-directory's status */ DIR dj; - obj->c_scl = fs->cdc_scl; - obj->c_size = fs->cdc_size; - obj->c_ofs = fs->cdc_ofs; - res = load_obj_dir(&dj, obj); + dp->obj.c_scl = fs->cdc_scl; + dp->obj.c_size = fs->cdc_size; + dp->obj.c_ofs = fs->cdc_ofs; + res = load_obj_xdir(&dj, &dp->obj); if (res != FR_OK) return res; - obj->objsize = ld_dword(fs->dirbuf + XDIR_FileSize); - obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; + dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize); + dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; } +#endif #endif if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ @@ -2786,7 +3041,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ ns = dp->fn[NSFLAG]; if (res != FR_OK) { /* Failed to find the object */ if (res == FR_NO_FILE) { /* Object is not found */ - if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, stay there */ + if (FF_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, stay there */ if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ dp->fn[NSFLAG] = NS_NONAME; res = FR_OK; @@ -2798,21 +3053,19 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ } if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ /* Get into the sub-directory */ - if (!(obj->attr & AM_DIR)) { /* It is not a sub-directory and cannot follow */ + if (!(dp->obj.attr & AM_DIR)) { /* It is not a sub-directory and cannot follow */ res = FR_NO_PATH; break; } -#if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { - obj->c_scl = obj->sclust; /* Save containing directory information for next dir */ - obj->c_size = ((DWORD)obj->objsize & 0xFFFFFF00) | obj->stat; - obj->c_ofs = dp->blk_ofs; - obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Open next directory */ - obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; - obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* Save containing directory information for next dir */ + dp->obj.c_scl = dp->obj.sclust; + dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; + dp->obj.c_ofs = dp->blk_ofs; + init_alloc_info(fs, &dp->obj); /* Open next directory */ } else #endif { - obj->sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */ + dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs)); /* Open next directory */ } } } @@ -2824,41 +3077,39 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ /*-----------------------------------------------------------------------*/ -/* Load a sector and check if it is an FAT boot sector */ +/* Load a sector and check if it is an FAT VBR */ /*-----------------------------------------------------------------------*/ -static -BYTE check_fs ( /* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */ - FATFS* fs, /* File system object */ - DWORD sect /* Sector# (lba) to check if it is an FAT-VBR or not */ +static BYTE check_fs ( /* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */ + FATFS* fs, /* Filesystem object */ + DWORD sect /* Sector# (lba) to load and check if it is an FAT-VBR or not */ ) { fs->wflag = 0; fs->winsect = 0xFFFFFFFF; /* Invaidate window */ if (move_window(fs, sect) != FR_OK) return 4; /* Load boot record */ - if (ld_word(fs->win + BS_55AA) != 0xAA55) return 3; /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */ + if (ld_word(fs->win + BS_55AA) != 0xAA55) return 3; /* Check boot record signature (always here regardless of the sector size) */ - if (fs->win[BS_JmpBoot] == 0xE9 || (fs->win[BS_JmpBoot] == 0xEB && fs->win[BS_JmpBoot + 2] == 0x90)) { - if ((ld_dword(fs->win + BS_FilSysType) & 0xFFFFFF) == 0x544146) return 0; /* Check "FAT" string */ - if (ld_dword(fs->win + BS_FilSysType32) == 0x33544146) return 0; /* Check "FAT3" string */ - } -#if _FS_EXFAT - if (!mem_cmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; +#if FF_FS_EXFAT + if (!mem_cmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT ", 11)) return 1; /* Check if exFAT VBR */ #endif - return 2; + if (fs->win[BS_JmpBoot] == 0xE9 || fs->win[BS_JmpBoot] == 0xEB || fs->win[BS_JmpBoot] == 0xE8) { /* Valid JumpBoot code? */ + if (!mem_cmp(fs->win + BS_FilSysType, "FAT", 3)) return 0; /* Is it an FAT VBR? */ + if (!mem_cmp(fs->win + BS_FilSysType32, "FAT32", 5)) return 0; /* Is it an FAT32 VBR? */ + } + return 2; /* Valid BS but not FAT */ } /*-----------------------------------------------------------------------*/ -/* Find logical drive and check if the volume is mounted */ +/* Determine logical drive number and mount the volume if needed */ /*-----------------------------------------------------------------------*/ -static -FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ - FATFS* fs, /* Pointer to the file system object */ - BYTE mode /* !=0: Check write protection for write access */ +static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ + FATFS *fs, /* Pointer to the file system object */ + BYTE mode /* !=0: Check write protection for write access */ ) { BYTE fmt, *pt; @@ -2868,65 +3119,70 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ UINT i; - ENTER_FF(fs); /* Lock the volume */ +#if FF_FS_REENTRANT + if (!lock_fs(fs)) return FR_TIMEOUT; /* Lock the volume */ +#endif mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ - if (fs->fs_type) { /* If the volume has been mounted */ + if (fs->fs_type != 0) { /* If the volume has been mounted */ disk_ioctl(fs->drv, IOCTL_STATUS, &stat); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ - if (!_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ + if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ return FR_WRITE_PROTECTED; } - return FR_OK; /* The file system object is valid */ + return FR_OK; /* The filesystem object is valid */ } } - /* The file system object is not valid. */ - /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ + /* The filesystem object is not valid. */ + /* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */ - fs->fs_type = 0; /* Clear the file system object */ + fs->fs_type = 0; /* Clear the filesystem object */ disk_ioctl(fs->drv, IOCTL_INIT, &stat); /* Initialize the physical drive */ if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ } - if (!_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ + if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */ return FR_WRITE_PROTECTED; } -#if _MAX_SS != _MIN_SS /* Get sector size (multiple sector size cfg only) */ +#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */ if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR; - if (SS(fs) > _MAX_SS || SS(fs) < _MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; + if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; #endif - /* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */ + + /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */ bsect = 0; fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ if (fmt == 2 || (fmt < 2 && LD2PT(fs) != 0)) { /* Not an FAT-VBR or forced partition number */ - for (i = 0; i < 4; i++) { /* Get partition offset */ + for (i = 0; i < 4; i++) { /* Get partition offset */ pt = fs->win + (MBR_Table + i * SZ_PTE); br[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0; } - i = LD2PT(fs); /* Partition number: 0:auto, 1-4:forced */ - if (i) i--; - do { /* Find an FAT volume */ + i = LD2PT(fs); /* Partition number: 0:auto, 1-4:forced */ + if (i != 0) i--; + do { /* Find an FAT volume */ bsect = br[i]; fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */ - } while (!LD2PT(fs) && fmt >= 2 && ++i < 4); + } while (LD2PT(fs) == 0 && fmt >= 2 && ++i < 4); } if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ - /* An FAT volume is found. Following code initializes the file system object */ + /* An FAT volume is found (bsect). Following code initializes the filesystem object */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fmt == 1) { QWORD maxlba; + DWORD so, cv, bcl; for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; - if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT revision (Must be 1.0) */ + if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */ - if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ + if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ return FR_NO_FILESYSTEM; + } maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */ if (maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */ @@ -2950,106 +3206,123 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); - /* Check if bitmap location is in assumption (at the first cluster) */ - if (move_window(fs, clust2sect(fs, fs->dirbase)) != FR_OK) return FR_DISK_ERR; - for (i = 0; i < SS(fs); i += SZDIRE) { - if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */ + /* Get bitmap location and check if it is contiguous (implementation assumption) */ + so = i = 0; + for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */ + if (i == 0) { + if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */ + if (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) return FR_DISK_ERR; + so++; + } + if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */ + i = (i + SZDIRE) % SS(fs); /* Next entry */ } - if (i == SS(fs)) return FR_NO_FILESYSTEM; -#if !_FS_READONLY + bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ + if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; + fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */ + for (;;) { /* Check if bitmap is contiguous */ + if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; + cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); + if (cv == 0xFFFFFFFF) break; /* Last link? */ + if (cv != ++bcl) return FR_NO_FILESYSTEM; /* Fragmented? */ + } + +#if !FF_FS_READONLY fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ #endif fmt = FS_EXFAT; /* FAT sub-type */ } else -#endif /* _FS_EXFAT */ +#endif /* FF_FS_EXFAT */ { if (ld_word(fs->win + BPB_BytsPerSec) != SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_BytsPerSec must be equal to the physical sector size) */ - fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ + fasize = ld_word(fs->win + BPB_FATSz16); /* Number of sectors per FAT */ if (fasize == 0) fasize = ld_dword(fs->win + BPB_FATSz32); fs->fsize = fasize; - fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ - fasize *= fs->n_fats; /* Number of sectors for FAT area */ + fasize *= fs->n_fats; /* Number of sectors for FAT area */ - fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ + fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */ fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */ - tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ + tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); - nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ - if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ + nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */ /* Determine the FAT sub type */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ - if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ - nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ - if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ - fmt = FS_FAT32; + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = 0; + if (nclst <= MAX_FAT32) fmt = FS_FAT32; if (nclst <= MAX_FAT16) fmt = FS_FAT16; if (nclst <= MAX_FAT12) fmt = FS_FAT12; + if (fmt == 0) return FR_NO_FILESYSTEM; /* Boundaries and Limits */ - fs->n_fatent = nclst + 2; /* Number of FAT entries */ - fs->volbase = bsect; /* Volume start sector */ - fs->fatbase = bsect + nrsv; /* FAT start sector */ - fs->database = bsect + sysect; /* Data start sector */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->volbase = bsect; /* Volume start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + fs->database = bsect + sysect; /* Data start sector */ if (fmt == FS_FAT32) { if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ - if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ - szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ + szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ } else { - if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM;/* (BPB_RootEntCnt must not be 0) */ - fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ - szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ + if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); } if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */ -#if !_FS_READONLY - /* Get FSINFO if available */ +#if !FF_FS_READONLY + /* Get FSInfo if available */ fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ fs->fsi_flag = 0x80; -#if (_FS_NOFSINFO & 3) != 3 - if (fmt == FS_FAT32 /* Enable FSINFO only if FAT32 and BPB_FSInfo32 == 1 */ +#if (FF_FS_NOFSINFO & 3) != 3 + if (fmt == FS_FAT32 /* Allow to update FSInfo only if BPB_FSInfo32 == 1 */ && ld_word(fs->win + BPB_FSInfo32) == 1 && move_window(fs, bsect + 1) == FR_OK) { fs->fsi_flag = 0; - if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSINFO data if available */ + if (ld_word(fs->win + BS_55AA) == 0xAA55 /* Load FSInfo data if available */ && ld_dword(fs->win + FSI_LeadSig) == 0x41615252 && ld_dword(fs->win + FSI_StrucSig) == 0x61417272) { -#if (_FS_NOFSINFO & 1) == 0 +#if (FF_FS_NOFSINFO & 1) == 0 fs->free_clst = ld_dword(fs->win + FSI_Free_Count); #endif -#if (_FS_NOFSINFO & 2) == 0 +#if (FF_FS_NOFSINFO & 2) == 0 fs->last_clst = ld_dword(fs->win + FSI_Nxt_Free); #endif } } -#endif /* (_FS_NOFSINFO & 3) != 3 */ -#endif /* !_FS_READONLY */ +#endif /* (FF_FS_NOFSINFO & 3) != 3 */ +#endif /* !FF_FS_READONLY */ } - fs->fs_type = fmt; /* FAT sub-type */ - fs->id = ++Fsid; /* File system mount ID */ -#if _USE_LFN == 1 + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* Volume mount ID */ +#if FF_USE_LFN == 1 fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ -#if _FS_EXFAT - fs->dirbuf = DirBuf; /* Static directory block working buuffer */ +#if FF_FS_EXFAT + fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */ #endif #endif -#if _FS_RPATH != 0 - fs->cdir = 0; /* Initialize current directory */ +#if FF_FS_RPATH != 0 + fs->cdir = 0; /* Initialize current directory */ #endif -#if _FS_LOCK != 0 /* Clear file lock semaphores */ +#if FF_FS_LOCK != 0 /* Clear file lock semaphores */ clear_lock(fs); #endif return FR_OK; @@ -3062,24 +3335,33 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ /* Check if the file/directory object is valid or not */ /*-----------------------------------------------------------------------*/ -static -FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ - _FDID* obj, /* Pointer to the _OBJ, the 1st member in the FIL/DIR object, to check validity */ - FATFS** fs /* Pointer to pointer to the owner file system object to return */ +static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ + FFOBJID* obj, /* Pointer to the FFOBJID, the 1st member in the FIL/DIR object, to check validity */ + FATFS** rfs /* Pointer to pointer to the owner filesystem object to return */ ) { - FRESULT res; + FRESULT res = FR_INVALID_OBJECT; DSTATUS stat; - if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || disk_ioctl(obj->fs->drv, IOCTL_STATUS, &stat) != RES_OK || (stat & STA_NOINIT)) { - *fs = 0; /* The object is invalid */ - res = FR_INVALID_OBJECT; - } else { - *fs = obj->fs; /* Owner file sytem object */ - ENTER_FF(obj->fs); /* Lock file system */ - res = FR_OK; + if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */ +#if FF_FS_REENTRANT + if (lock_fs(obj->fs)) { /* Obtain the filesystem object */ + if (disk_ioctl(obj->fs->drv, IOCTL_STATUS, &stat) == RES_OK && !(stat & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ + res = FR_OK; + } else { + unlock_fs(obj->fs, FR_OK); + } + } else { + res = FR_TIMEOUT; + } +#else + if (disk_ioctl(obj->fs->drv, IOCTL_STATUS, &stat) == RES_OK && !(stat & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */ + res = FR_OK; + } +#endif } + *rfs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */ return res; } @@ -3105,7 +3387,7 @@ FRESULT f_mount ( FRESULT res; fs->fs_type = 0; /* Clear new fs object */ -#if _FS_REENTRANT /* Create sync object for the new volume */ +#if FF_FS_REENTRANT /* Create sync object for the new volume */ if (!ff_cre_syncobj(fs, &fs->sobj)) return FR_INT_ERR; #endif @@ -3118,10 +3400,10 @@ FRESULT f_umount ( FATFS* fs /* Pointer to the file system object to unmount */ ) { -#if _FS_LOCK +#if FF_FS_LOCK clear_lock(fs); #endif -#if _FS_REENTRANT /* Discard sync object of the current volume */ +#if FF_FS_REENTRANT /* Discard sync object of the current volume */ if (!ff_del_syncobj(fs->sobj)) return FR_INT_ERR; #endif fs->fs_type = 0; /* Clear old fs object */ @@ -3143,7 +3425,7 @@ FRESULT f_open ( { FRESULT res; DIR dj; -#if !_FS_READONLY +#if !FF_FS_READONLY DWORD dw, cl, bcs, clst, sc; FSIZE_t ofs; #endif @@ -3152,79 +3434,71 @@ FRESULT f_open ( if (!fp) return FR_INVALID_OBJECT; - /* Get logical drive */ - mode &= _FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND | FA_SEEKEND; + /* Get logical drive number */ + mode &= FF_FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND; res = find_volume(fs, mode); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ -#if !_FS_READONLY /* R/W configuration */ +#if !FF_FS_READONLY /* Read/Write configuration */ if (res == FR_OK) { if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */ res = FR_INVALID_NAME; } -#if _FS_LOCK != 0 +#if FF_FS_LOCK != 0 else { - res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Check if the file can be used */ } #endif } /* Create or Open a file */ if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { if (res != FR_OK) { /* No file, create new */ - if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ -#if _FS_LOCK != 0 + if (res == FR_NO_FILE) { /* There is no file to open, create a new entry */ +#if FF_FS_LOCK != 0 res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; #else res = dir_register(&dj); #endif + } mode |= FA_CREATE_ALWAYS; /* File is created */ } - else { /* Any object is already existing */ + else { /* Any object with the same name is already existing */ if (dj.obj.attr & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ res = FR_DENIED; } else { if (mode & FA_CREATE_NEW) res = FR_EXIST; /* Cannot create as new file */ } } - if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ - dw = GET_FATTIME(); -#if _FS_EXFAT + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate the file if overwrite mode */ +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Get current allocation info */ fp->obj.fs = fs; - fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus); - fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize); - fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; - /* Initialize directory entry block */ - st_dword(fs->dirbuf + XDIR_CrtTime, dw); /* Set created time */ - fs->dirbuf[XDIR_CrtTime10] = 0; - st_dword(fs->dirbuf + XDIR_ModTime, dw); /* Set modified time */ - fs->dirbuf[XDIR_ModTime10] = 0; - fs->dirbuf[XDIR_Attr] = AM_ARC; /* Reset attribute */ - st_dword(fs->dirbuf + XDIR_FstClus, 0); /* Reset file allocation info */ - st_qword(fs->dirbuf + XDIR_FileSize, 0); - st_qword(fs->dirbuf + XDIR_ValidFileSize, 0); + init_alloc_info(fs, &fp->obj); + /* Set directory entry block initial state */ + mem_set(fs->dirbuf + 2, 0, 30); /* Clear 85 entry except for NumSec */ + mem_set(fs->dirbuf + 38, 0, 26); /* Clear C0 entry except for NumName and NameHash */ + fs->dirbuf[XDIR_Attr] = AM_ARC; + st_dword(fs->dirbuf + XDIR_CrtTime, GET_FATTIME()); fs->dirbuf[XDIR_GenFlags] = 1; res = store_xdir(&dj); - if (res == FR_OK && fp->obj.sclust) { /* Remove the cluster chain if exist */ + if (res == FR_OK && fp->obj.sclust != 0) { /* Remove the cluster chain if exist */ res = remove_chain(&fp->obj, fp->obj.sclust, 0); fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */ } } else #endif { - /* Clean directory info */ - st_dword(dj.dir + DIR_CrtTime, dw); /* Set created time */ - st_dword(dj.dir + DIR_ModTime, dw); /* Set modified time */ + /* Set directory entry initial state */ + cl = ld_clust(fs, dj.dir); /* Get current cluster chain */ + st_dword(dj.dir + DIR_CrtTime, GET_FATTIME()); /* Set created time */ dj.dir[DIR_Attr] = AM_ARC; /* Reset attribute */ - cl = ld_clust(fs, dj.dir); /* Get cluster chain */ st_clust(fs, dj.dir, 0); /* Reset file allocation info */ st_dword(dj.dir + DIR_FileSize, 0); fs->wflag = 1; - - if (cl) { /* Remove the cluster chain if exist */ + if (cl != 0) { /* Remove the cluster chain if exist */ dw = fs->winsect; res = remove_chain(&dj.obj, cl, 0); if (res == FR_OK) { @@ -3236,32 +3510,31 @@ FRESULT f_open ( } } else { /* Open an existing file */ - if (res == FR_OK) { /* Following succeeded */ - if (dj.obj.attr & AM_DIR) { /* It is a directory */ + if (res == FR_OK) { /* Is the object exsiting? */ + if (dj.obj.attr & AM_DIR) { /* File open against a directory */ res = FR_NO_FILE; } else { - if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* R/O violation */ + if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* Write mode open against R/O file */ res = FR_DENIED; } } } } if (res == FR_OK) { - if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ - mode |= FA_MODIFIED; + if (mode & FA_CREATE_ALWAYS) mode |= FA_MODIFIED; /* Set file change flag if created or overwritten */ fp->dir_sect = fs->winsect; /* Pointer to the directory entry */ fp->dir_ptr = dj.dir; -#if _FS_LOCK != 0 - fp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); - if (!fp->obj.lockid) res = FR_INT_ERR; +#if FF_FS_LOCK != 0 + fp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); /* Lock the file for this session */ + if (fp->obj.lockid == 0) res = FR_INT_ERR; #endif } #else /* R/O configuration */ if (res == FR_OK) { - if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */ + if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it origin directory itself? */ res = FR_INVALID_NAME; } else { - if (dj.obj.attr & AM_DIR) { /* It is a directory */ + if (dj.obj.attr & AM_DIR) { /* Is it a directory? */ res = FR_NO_FILE; } } @@ -3269,21 +3542,19 @@ FRESULT f_open ( #endif if (res == FR_OK) { -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { - fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get allocation info */ - fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize); - fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; - fp->obj.c_scl = dj.obj.sclust; + fp->obj.c_scl = dj.obj.sclust; /* Get containing directory info */ fp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat; fp->obj.c_ofs = dj.blk_ofs; + init_alloc_info(fs, &fp->obj); } else #endif { - fp->obj.sclust = ld_clust(fs, dj.dir); /* Get allocation info */ + fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */ fp->obj.objsize = ld_dword(dj.dir + DIR_FileSize); } -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK fp->cltbl = 0; /* Disable fast seek mode */ #endif fp->obj.fs = fs; /* Validate the file object */ @@ -3292,9 +3563,9 @@ FRESULT f_open ( fp->err = 0; /* Clear error flag */ fp->sect = 0; /* Invalidate current data sector */ fp->fptr = 0; /* Set file pointer top of the file */ -#if !_FS_READONLY -#if !_FS_TINY - mem_set(fp->buf, 0, _MAX_SS); /* Clear sector buffer */ +#if !FF_FS_READONLY +#if !FF_FS_TINY + mem_set(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ #endif if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ fp->fptr = fp->obj.objsize; /* Offset to seek */ @@ -3307,11 +3578,11 @@ FRESULT f_open ( } fp->clust = clst; if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */ - if ((sc = clust2sect(fs, clst)) == 0) { + if ((sc = clst2sect(fs, clst)) == 0) { res = FR_INT_ERR; } else { fp->sect = sc + (DWORD)(ofs / SS(fs)); -#if !_FS_TINY +#if !FF_FS_TINY if (disk_read(fs->drv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR; #endif } @@ -3357,15 +3628,15 @@ FRESULT f_read ( remain = fp->obj.objsize - fp->fptr; if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ - for ( ; btr; /* Repeat until all data read */ - rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + for ( ; btr; /* Repeat until btr bytes read */ + btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */ if (csect == 0) { /* On the cluster boundary? */ if (fp->fptr == 0) { /* On the top of the file? */ clst = fp->obj.sclust; /* Follow cluster chain from the origin */ } else { /* Middle or end of the file */ -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK if (fp->cltbl) { clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ } else @@ -3378,17 +3649,17 @@ FRESULT f_read ( if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR); fp->clust = clst; /* Update current cluster */ } - sect = clust2sect(fs, fp->clust); /* Get current sector */ - if (!sect) ABORT(fs, FR_INT_ERR); + sect = clst2sect(fs, fp->clust); /* Get current sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btr / SS(fs); /* When remaining bytes >= sector size, */ - if (cc) {/* Read maximum contiguous sectors directly */ + if (cc > 0) { /* Read maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } if (disk_read(fs->drv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); -#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ -#if _FS_TINY +#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if FF_FS_TINY if (fs->wflag && fs->winsect - sect < cc) { mem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs)); } @@ -3401,22 +3672,22 @@ FRESULT f_read ( rcnt = SS(fs) * cc; /* Number of bytes transferred */ continue; } -#if !_FS_TINY +#if !FF_FS_TINY if (fp->sect != sect) { /* Load data sector if not in cache */ -#if !_FS_READONLY +#if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ + if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ } #endif fp->sect = sect; } rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */ -#if _FS_TINY +#if FF_FS_TINY if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ mem_cpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */ #else @@ -3430,7 +3701,7 @@ FRESULT f_read ( -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Write File */ /*-----------------------------------------------------------------------*/ @@ -3454,13 +3725,13 @@ FRESULT f_write ( if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - /* Check fptr wrap-around (file size cannot reach 4GiB on FATxx) */ - if ((!_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { + /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ + if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr); } for ( ; btw; /* Repeat until all data written */ - wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize, *bw += wcnt, btw -= wcnt) { + btw -= wcnt, *bw += wcnt, wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize) { if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */ csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */ if (csect == 0) { /* On the cluster boundary? */ @@ -3470,7 +3741,7 @@ FRESULT f_write ( clst = create_chain(&fp->obj, 0); /* create a new cluster chain */ } } else { /* On the middle or end of the file */ -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK if (fp->cltbl) { clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ } else @@ -3485,7 +3756,7 @@ FRESULT f_write ( fp->clust = clst; /* Update current cluster */ if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */ } -#if _FS_TINY +#if FF_FS_TINY if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ #else if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ @@ -3493,17 +3764,17 @@ FRESULT f_write ( fp->flag &= (BYTE)~FA_DIRTY; } #endif - sect = clust2sect(fs, fp->clust); /* Get current sector */ - if (!sect) ABORT(fs, FR_INT_ERR); + sect = clst2sect(fs, fp->clust); /* Get current sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; cc = btw / SS(fs); /* When remaining bytes >= sector size, */ - if (cc) { /* Write maximum contiguous sectors directly */ + if (cc > 0) { /* Write maximum contiguous sectors directly */ if (csect + cc > fs->csize) { /* Clip at cluster boundary */ cc = fs->csize - csect; } if (disk_write(fs->drv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR); -#if _FS_MINIMIZE <= 2 -#if _FS_TINY +#if FF_FS_MINIMIZE <= 2 +#if FF_FS_TINY if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ mem_cpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs)); fs->wflag = 0; @@ -3518,7 +3789,7 @@ FRESULT f_write ( wcnt = SS(fs) * cc; /* Number of bytes transferred */ continue; } -#if _FS_TINY +#if FF_FS_TINY if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */ if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); fs->winsect = sect; @@ -3534,7 +3805,7 @@ FRESULT f_write ( } wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ if (wcnt > btw) wcnt = btw; /* Clip it by btw if needed */ -#if _FS_TINY +#if FF_FS_TINY if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */ mem_cpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */ fs->wflag = 1; @@ -3564,15 +3835,12 @@ FRESULT f_sync ( FATFS *fs; DWORD tm; BYTE *dir; -#if _FS_EXFAT - DEF_NAMBUF -#endif res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */ -#if !_FS_TINY +#if !FF_FS_TINY if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; @@ -3580,17 +3848,21 @@ FRESULT f_sync ( #endif /* Update the directory entry */ tm = GET_FATTIME(); /* Modified time */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { - res = fill_fat_chain(&fp->obj); /* Create FAT chain if needed */ + res = fill_first_frag(&fp->obj); /* Fill first fragment on the FAT if needed */ + if (res == FR_OK) { + res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ + } if (res == FR_OK) { DIR dj; + DEF_NAMBUF INIT_NAMBUF(fs); - res = load_obj_dir(&dj, &fp->obj); /* Load directory entry block */ + res = load_obj_xdir(&dj, &fp->obj); /* Load directory entry block */ if (res == FR_OK) { - fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive bit */ - fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation info */ + fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ + fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation information */ st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust); st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize); st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize); @@ -3611,8 +3883,8 @@ FRESULT f_sync ( res = move_window(fs, fp->dir_sect); if (res == FR_OK) { dir = fp->dir_ptr; - dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ - st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation info */ + dir[DIR_Attr] |= AM_ARC; /* Set archive attribute to indicate that the file has been changed */ + st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation information */ st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize); /* Update file size */ st_dword(dir + DIR_ModTime, tm); /* Update modified time */ st_word(dir + DIR_LstAccDate, 0); @@ -3627,7 +3899,7 @@ FRESULT f_sync ( LEAVE_FF(fs, res); } -#endif /* !_FS_READONLY */ +#endif /* !FF_FS_READONLY */ @@ -3643,21 +3915,20 @@ FRESULT f_close ( FRESULT res; FATFS *fs; -#if !_FS_READONLY +#if !FF_FS_READONLY res = f_sync(fp); /* Flush cached data */ if (res == FR_OK) #endif { res = validate(&fp->obj, &fs); /* Lock volume */ if (res == FR_OK) { -#if _FS_LOCK != 0 - res = dec_lock(fp->obj.lockid); /* Decrement file open counter */ - if (res == FR_OK) +#if FF_FS_LOCK != 0 + res = dec_lock(fp->obj.lockid); /* Decrement file open counter */ + if (res == FR_OK) fp->obj.fs = 0; /* Invalidate file object */ +#else + fp->obj.fs = 0; /* Invalidate file object */ #endif - { - fp->obj.fs = 0; /* Invalidate file object */ - } -#if _FS_REENTRANT +#if FF_FS_REENTRANT unlock_fs(fs, FR_OK); /* Unlock volume */ #endif } @@ -3668,7 +3939,7 @@ FRESULT f_close ( -#if _FS_RPATH >= 1 +#if FF_FS_RPATH >= 1 /*-----------------------------------------------------------------------*/ /* Change Current Directory or Current Drive, Get Current Directory */ /*-----------------------------------------------------------------------*/ @@ -3678,10 +3949,14 @@ FRESULT f_chdir ( const TCHAR* path /* Pointer to the directory path */ ) { +#if FF_STR_VOLUME_ID == 2 + UINT i; +#endif FRESULT res; DIR dj; DEF_NAMBUF + /* Get logical drive */ res = find_volume(fs, 0); if (res == FR_OK) { @@ -3689,9 +3964,9 @@ FRESULT f_chdir ( INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the path */ if (res == FR_OK) { /* Follow completed */ - if (dj.fn[NSFLAG] & NS_NONAME) { - fs->cdir = dj.obj.sclust; /* It is the start directory itself */ -#if _FS_EXFAT + if (dj.fn[NSFLAG] & NS_NONAME) { /* Is it the start directory itself? */ + fs->cdir = dj.obj.sclust; +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->cdc_scl = dj.obj.c_scl; fs->cdc_size = dj.obj.c_size; @@ -3700,7 +3975,7 @@ FRESULT f_chdir ( #endif } else { if (dj.obj.attr & AM_DIR) { /* It is a sub-directory */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->cdir = ld_dword(fs->dirbuf + XDIR_FstClus); /* Sub-directory cluster */ fs->cdc_scl = dj.obj.sclust; /* Save containing directory information */ @@ -3718,36 +3993,50 @@ FRESULT f_chdir ( } FREE_NAMBUF(); if (res == FR_NO_FILE) res = FR_NO_PATH; +#if FF_STR_VOLUME_ID == 2 /* Also current drive is changed at Unix style volume ID */ + if (res == FR_OK) { + for (i = FF_VOLUMES - 1; i && fs != FatFs[i]; i--) ; /* Set current drive */ + CurrVol = (BYTE)i; + } +#endif } LEAVE_FF(fs, res); } -#if _FS_RPATH >= 2 +#if FF_FS_RPATH >= 2 FRESULT f_getcwd ( FATFS *fs, TCHAR* buff, /* Pointer to the directory path */ - UINT len /* Size of path */ + UINT len /* Size of buff in unit of TCHAR */ ) { FRESULT res; DIR dj; UINT i, n; DWORD ccl; - TCHAR *tp; + TCHAR *tp = buff; +#if FF_VOLUMES >= 2 + UINT vl; +#endif +#if FF_STR_VOLUME_ID + const char *vp; +#endif FILINFO fno; DEF_NAMBUF - *buff = 0; /* Get logical drive */ - res = find_volume(fs, 0); /* Get current volume */ + buff[0] = 0; /* Set null string to get current volume */ + res = find_volume(fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); + + /* Follow parent directories and create the path */ i = len; /* Bottom of buffer (directory stack base) */ - if (!_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path) */ + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* (Cannot do getcwd on exFAT and returns root path) */ dj.obj.sclust = fs->cdir; /* Start to follow upper directory from current directory */ while ((ccl = dj.obj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ res = dir_sdi(&dj, 1 * SZDIRE); /* Get parent directory */ @@ -3758,7 +4047,7 @@ FRESULT f_getcwd ( res = dir_sdi(&dj, 0); if (res != FR_OK) break; do { /* Find the entry links to the child directory */ - res = dir_read(&dj, 0); + res = DIR_READ_FILE(&dj); if (res != FR_OK) break; if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ res = dir_next(&dj, 0); @@ -3766,39 +4055,55 @@ FRESULT f_getcwd ( if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ if (res != FR_OK) break; get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ - for (n = 0; fno.fname[n]; n++) ; - if (i < n + 3) { + for (n = 0; fno.fname[n]; n++) ; /* Name length */ + if (i < n + 1) { /* Insufficient space to store the path name? */ res = FR_NOT_ENOUGH_CORE; break; } - while (n) buff[--i] = fno.fname[--n]; + while (n) buff[--i] = fno.fname[--n]; /* Stack the name */ buff[--i] = '/'; } } - tp = buff; if (res == FR_OK) { - if (i == len) { /* Root-directory */ - *tp++ = '/'; - } else { /* Sub-directroy */ - do /* Add stacked path str */ - *tp++ = buff[i++]; - while (i < len); + if (i == len) buff[--i] = '/'; /* Is it the root-directory? */ +#if FF_VOLUMES >= 2 /* Put drive prefix */ + vl = 0; +#if FF_STR_VOLUME_ID >= 1 /* String volume ID */ + for (n = 0, vp = (const char*)VolumeStr[CurrVol]; vp[n]; n++) ; + if (i >= n + 2) { + if (FF_STR_VOLUME_ID == 2) *tp++ = (TCHAR)'/'; + for (vl = 0; vl < n; *tp++ = (TCHAR)vp[vl], vl++) ; + if (FF_STR_VOLUME_ID == 1) *tp++ = (TCHAR)':'; + vl++; + } +#else /* Numeric volume ID */ + if (i >= 3) { + *tp++ = (TCHAR)'0' + CurrVol; + *tp++ = (TCHAR)':'; + vl = 2; + } +#endif + if (vl == 0) res = FR_NOT_ENOUGH_CORE; +#endif + /* Add current directory path */ + if (res == FR_OK) { + do *tp++ = buff[i++]; while (i < len); /* Copy stacked path string */ } } - *tp = 0; FREE_NAMBUF(); } + *tp = 0; LEAVE_FF(fs, res); } -#endif /* _FS_RPATH >= 2 */ -#endif /* _FS_RPATH >= 1 */ +#endif /* FF_FS_RPATH >= 2 */ +#endif /* FF_FS_RPATH >= 1 */ -#if _FS_MINIMIZE <= 2 +#if FF_FS_MINIMIZE <= 2 /*-----------------------------------------------------------------------*/ -/* Seek File R/W Pointer */ +/* Seek File Read/Write Pointer */ /*-----------------------------------------------------------------------*/ FRESULT f_lseek ( @@ -3810,19 +4115,26 @@ FRESULT f_lseek ( FATFS *fs; DWORD clst, bcs, nsect; FSIZE_t ifptr; -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; #endif res = validate(&fp->obj, &fs); /* Check validity of the file object */ - if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */ -#if _USE_FASTSEEK + if (res == FR_OK) res = (FRESULT)fp->err; +#if FF_FS_EXFAT && !FF_FS_READONLY + if (res == FR_OK && fs->fs_type == FS_EXFAT) { + res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */ + } +#endif + if (res != FR_OK) LEAVE_FF(fs, res); + +#if FF_USE_FASTSEEK if (fp->cltbl) { /* Fast seek */ if (ofs == CREATE_LINKMAP) { /* Create CLMT */ tbl = fp->cltbl; tlen = *tbl++; ulen = 2; /* Given table size and required table size */ cl = fp->obj.sclust; /* Origin of the chain */ - if (cl) { + if (cl != 0) { do { /* Get a fragment */ tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ @@ -3846,20 +4158,20 @@ FRESULT f_lseek ( } else { /* Fast seek */ if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; /* Clip offset at the file size */ fp->fptr = ofs; /* Set file pointer */ - if (ofs) { + if (ofs > 0) { fp->clust = clmt_clust(fp, ofs - 1); - dsc = clust2sect(fs, fp->clust); - if (!dsc) ABORT(fs, FR_INT_ERR); + dsc = clst2sect(fs, fp->clust); + if (dsc == 0) ABORT(fs, FR_INT_ERR); dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1); if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */ -#if !_FS_TINY -#if !_FS_READONLY +#if !FF_FS_TINY +#if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ + if (disk_read(fs->drv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */ #endif fp->sect = dsc; } @@ -3870,15 +4182,15 @@ FRESULT f_lseek ( /* Normal Seek */ { -#if _FS_EXFAT - if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4GiB-1 if at FATxx */ +#if FF_FS_EXFAT + if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4 GiB - 1 if at FATxx */ #endif - if (ofs > fp->obj.objsize && (_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ + if (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */ ofs = fp->obj.objsize; } ifptr = fp->fptr; fp->fptr = nsect = 0; - if (ofs) { + if (ofs > 0) { bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */ if (ifptr > 0 && (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ @@ -3887,7 +4199,7 @@ FRESULT f_lseek ( clst = fp->clust; } else { /* When seek to back cluster, */ clst = fp->obj.sclust; /* start from the first cluster */ -#if !_FS_READONLY +#if !FF_FS_READONLY if (clst == 0) { /* If no cluster chain, create a new chain */ clst = create_chain(&fp->obj, 0); if (clst == 1) ABORT(fs, FR_INT_ERR); @@ -3900,9 +4212,9 @@ FRESULT f_lseek ( if (clst != 0) { while (ofs > bcs) { /* Cluster following loop */ ofs -= bcs; fp->fptr += bcs; -#if !_FS_READONLY +#if !FF_FS_READONLY if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ - if (_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ + if (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */ fp->obj.objsize = fp->fptr; fp->flag |= FA_MODIFIED; } @@ -3921,25 +4233,25 @@ FRESULT f_lseek ( } fp->fptr += ofs; if (ofs % SS(fs)) { - nsect = clust2sect(fs, clst); /* Current sector */ - if (!nsect) ABORT(fs, FR_INT_ERR); + nsect = clst2sect(fs, clst); /* Current sector */ + if (nsect == 0) ABORT(fs, FR_INT_ERR); nsect += (DWORD)(ofs / SS(fs)); } } } - if (!_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ + if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */ fp->obj.objsize = fp->fptr; fp->flag |= FA_MODIFIED; } if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */ -#if !_FS_TINY -#if !_FS_READONLY +#if !FF_FS_TINY +#if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; } #endif - if (disk_read(fs->drv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ + if (disk_read(fs->drv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */ #endif fp->sect = nsect; } @@ -3950,7 +4262,7 @@ FRESULT f_lseek ( -#if _FS_MINIMIZE <= 1 +#if FF_FS_MINIMIZE <= 1 /*-----------------------------------------------------------------------*/ /* Create a Directory Object */ /*-----------------------------------------------------------------------*/ @@ -3962,49 +4274,45 @@ FRESULT f_opendir ( ) { FRESULT res; - _FDID *obj; DEF_NAMBUF if (!dp) return FR_INVALID_OBJECT; /* Get logical drive */ - obj = &dp->obj; res = find_volume(fs, 0); if (res == FR_OK) { - obj->fs = fs; + dp->obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(dp, path); /* Follow the path to the directory */ if (res == FR_OK) { /* Follow completed */ if (!(dp->fn[NSFLAG] & NS_NONAME)) { /* It is not the origin directory itself */ - if (obj->attr & AM_DIR) { /* This object is a sub-directory */ -#if _FS_EXFAT + if (dp->obj.attr & AM_DIR) { /* This object is a sub-directory */ +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { - obj->c_scl = obj->sclust; /* Save containing directory inforamation */ - obj->c_size = ((DWORD)obj->objsize & 0xFFFFFF00) | obj->stat; - obj->c_ofs = dp->blk_ofs; - obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get object location and status */ - obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize); - obj->stat = fs->dirbuf[XDIR_GenFlags] & 2; + dp->obj.c_scl = dp->obj.sclust; /* Get containing directory inforamation */ + dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat; + dp->obj.c_ofs = dp->blk_ofs; + init_alloc_info(fs, &dp->obj); /* Get object allocation info */ } else #endif { - obj->sclust = ld_clust(fs, dp->dir); /* Get object location */ + dp->obj.sclust = ld_clust(fs, dp->dir); /* Get object allocation info */ } } else { /* This object is a file */ res = FR_NO_PATH; } } if (res == FR_OK) { - obj->id = fs->id; + dp->obj.id = fs->id; res = dir_sdi(dp, 0); /* Rewind directory */ -#if _FS_LOCK != 0 +#if FF_FS_LOCK != 0 if (res == FR_OK) { - if (obj->sclust) { - obj->lockid = inc_lock(dp, 0); /* Lock the sub directory */ - if (!obj->lockid) res = FR_TOO_MANY_OPEN_FILES; + if (dp->obj.sclust != 0) { + dp->obj.lockid = inc_lock(dp, 0); /* Lock the sub directory */ + if (!dp->obj.lockid) res = FR_TOO_MANY_OPEN_FILES; } else { - obj->lockid = 0; /* Root directory need not to be locked */ + dp->obj.lockid = 0; /* Root directory need not to be locked */ } } #endif @@ -4013,7 +4321,7 @@ FRESULT f_opendir ( FREE_NAMBUF(); if (res == FR_NO_FILE) res = FR_NO_PATH; } - if (res != FR_OK) obj->fs = 0; /* Invalidate the directory object if function faild */ + if (res != FR_OK) dp->obj.fs = 0; /* Invalidate the directory object if function faild */ LEAVE_FF(fs, res); } @@ -4033,18 +4341,15 @@ FRESULT f_closedir ( FATFS *fs; - res = validate(&dp->obj, &fs); /* Check validity of the file object */ + res = validate(&dp->obj, &fs); /* Check validity of the file object */ if (res == FR_OK) { -#if _FS_LOCK != 0 - if (dp->obj.lockid) { /* Decrement sub-directory open counter */ - res = dec_lock(dp->obj.lockid); - } - if (res == FR_OK) +#if FF_FS_LOCK != 0 + if (dp->obj.lockid) res = dec_lock(dp->obj.lockid); /* Decrement sub-directory open counter */ + if (res == FR_OK) dp->obj.fs = 0; /* Invalidate directory object */ +#else + dp->obj.fs = 0; /* Invalidate directory object */ #endif - { - dp->obj.fs = 0; /* Invalidate directory object */ - } -#if _FS_REENTRANT +#if FF_FS_REENTRANT unlock_fs(fs, FR_OK); /* Unlock volume */ #endif } @@ -4074,7 +4379,7 @@ FRESULT f_readdir ( res = dir_sdi(dp, 0); /* Rewind the directory object */ } else { INIT_NAMBUF(fs); - res = dir_read(dp, 0); /* Read an item */ + res = DIR_READ_FILE(dp); /* Read an item */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ if (res == FR_OK) { /* A valid entry is found */ get_fileinfo(dp, fno); /* Get the object information */ @@ -4089,7 +4394,7 @@ FRESULT f_readdir ( -#if _USE_FIND +#if FF_USE_FIND /*-----------------------------------------------------------------------*/ /* Find Next File */ /*-----------------------------------------------------------------------*/ @@ -4106,7 +4411,7 @@ FRESULT f_findnext ( res = f_readdir(dp, fno); /* Get a directory item */ if (res != FR_OK || !fno || !fno->fname[0]) break; /* Terminate if any error or end of directory */ if (pattern_matching(dp->pat, fno->fname, 0, 0)) break; /* Test for the file name */ -#if _USE_LFN != 0 && _USE_FIND == 2 +#if FF_USE_LFN && FF_USE_FIND == 2 if (pattern_matching(dp->pat, fno->altname, 0, 0)) break; /* Test for alternative name if exist */ #endif } @@ -4137,11 +4442,11 @@ FRESULT f_findfirst ( return res; } -#endif /* _USE_FIND */ +#endif /* FF_USE_FIND */ -#if _FS_MINIMIZE == 0 +#if FF_FS_MINIMIZE == 0 /*-----------------------------------------------------------------------*/ /* Get File Status */ /*-----------------------------------------------------------------------*/ @@ -4178,7 +4483,7 @@ FRESULT f_stat ( -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Get Number of Free Clusters */ /*-----------------------------------------------------------------------*/ @@ -4191,20 +4496,19 @@ FRESULT f_getfree ( FRESULT res; DWORD nfree, clst, sect, stat; UINT i; - BYTE *p; - _FDID obj; + FFOBJID obj; /* Get logical drive */ res = find_volume(fs, 0); if (res == FR_OK) { - /* If free_clst is valid, return it without full cluster scan */ + /* If free_clst is valid, return it without full FAT scan */ if (fs->free_clst <= fs->n_fatent - 2) { *nclst = fs->free_clst; } else { - /* Get number of free clusters */ + /* Scan FAT to obtain number of free clusters */ nfree = 0; - if (fs->fs_type == FS_FAT12) { /* FAT12: Sector unalighed FAT entries */ + if (fs->fs_type == FS_FAT12) { /* FAT12: Scan bit field FAT entries */ clst = 2; obj.fs = fs; do { stat = get_fat(&obj, clst); @@ -4213,16 +4517,19 @@ FRESULT f_getfree ( if (stat == 0) nfree++; } while (++clst < fs->n_fatent); } else { -#if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan bitmap table */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan allocation bitmap */ BYTE bm; UINT b; - clst = fs->n_fatent - 2; - sect = fs->database; - i = 0; - do { - if (i == 0 && (res = move_window(fs, sect++)) != FR_OK) break; + clst = fs->n_fatent - 2; /* Number of clusters */ + sect = fs->bitbase; /* Bitmap sector */ + i = 0; /* Offset in the sector */ + do { /* Counts numbuer of bits with zero in the bitmap */ + if (i == 0) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + } for (b = 8, bm = fs->win[i]; b && clst; b--, clst--) { if (!(bm & 1)) nfree++; bm >>= 1; @@ -4231,29 +4538,29 @@ FRESULT f_getfree ( } while (clst); } else #endif - { /* FAT16/32: Sector alighed FAT entries */ - clst = fs->n_fatent; sect = fs->fatbase; - i = 0; p = 0; - do { + { /* FAT16/32: Scan WORD/DWORD FAT entries */ + clst = fs->n_fatent; /* Number of entries */ + sect = fs->fatbase; /* Top of the FAT */ + i = 0; /* Offset in the sector */ + do { /* Counts numbuer of entries with zero in the FAT */ if (i == 0) { res = move_window(fs, sect++); if (res != FR_OK) break; - p = fs->win; - i = SS(fs); } if (fs->fs_type == FS_FAT16) { - if (ld_word(p) == 0) nfree++; - p += 2; i -= 2; + if (ld_word(fs->win + i) == 0) nfree++; + i += 2; } else { - if ((ld_dword(p) & 0x0FFFFFFF) == 0) nfree++; - p += 4; i -= 4; + if ((ld_dword(fs->win + i) & 0x0FFFFFFF) == 0) nfree++; + i += 4; } + i %= SS(fs); } while (--clst); } } *nclst = nfree; /* Return the free clusters */ fs->free_clst = nfree; /* Now free_clst is valid */ - fs->fsi_flag |= 1; /* FSInfo is to be updated */ + fs->fsi_flag |= 1; /* FAT32: FSInfo is to be updated */ } } @@ -4280,7 +4587,7 @@ FRESULT f_truncate ( if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */ - if (fp->obj.objsize > fp->fptr) { + if (fp->fptr < fp->obj.objsize) { /* Process when fptr is not on the eof */ if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ res = remove_chain(&fp->obj, fp->obj.sclust, 0); fp->obj.sclust = 0; @@ -4293,9 +4600,9 @@ FRESULT f_truncate ( res = remove_chain(&fp->obj, ncl, fp->clust); } } - fp->obj.objsize = fp->fptr; /* Set file size to current R/W point */ + fp->obj.objsize = fp->fptr; /* Set file size to current read/write point */ fp->flag |= FA_MODIFIED; -#if !_FS_TINY +#if !FF_FS_TINY if (res == FR_OK && (fp->flag & FA_DIRTY)) { if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) { res = FR_DISK_ERR; @@ -4325,22 +4632,22 @@ FRESULT f_unlink ( FRESULT res; DIR dj, sdj; DWORD dclst = 0; -#if _FS_EXFAT - _FDID obj; +#if FF_FS_EXFAT + FFOBJID obj; #endif DEF_NAMBUF /* Get logical drive */ res = find_volume(fs, FA_WRITE); - dj.obj.fs = fs; if (res == FR_OK) { + dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ - if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) { + if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) { res = FR_INVALID_NAME; /* Cannot remove dot entry */ } -#if _FS_LOCK != 0 +#if FF_FS_LOCK != 0 if (res == FR_OK) res = chk_lock(&dj, 2); /* Check if it is an open object */ #endif if (res == FR_OK) { /* The object is accessible */ @@ -4352,27 +4659,26 @@ FRESULT f_unlink ( } } if (res == FR_OK) { -#if _FS_EXFAT +#if FF_FS_EXFAT obj.fs = fs; if (fs->fs_type == FS_EXFAT) { - obj.sclust = dclst = ld_dword(fs->dirbuf + XDIR_FstClus); - obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize); - obj.stat = fs->dirbuf[XDIR_GenFlags] & 2; + init_alloc_info(fs, &obj); + dclst = obj.sclust; } else #endif { dclst = ld_clust(fs, dj.dir); } - if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory ? */ -#if _FS_RPATH != 0 - if (dclst == fs->cdir) { /* Is it the current directory? */ + if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory? */ +#if FF_FS_RPATH != 0 + if (dclst == fs->cdir) { /* Is it the current directory? */ res = FR_DENIED; } else #endif { - sdj.obj.fs = fs; /* Open the sub-directory */ + sdj.obj.fs = fs; /* Open the sub-directory */ sdj.obj.sclust = dclst; -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { sdj.obj.objsize = obj.objsize; sdj.obj.stat = obj.stat; @@ -4380,7 +4686,7 @@ FRESULT f_unlink ( #endif res = dir_sdi(&sdj, 0); if (res == FR_OK) { - res = dir_read(&sdj, 0); /* Read an item */ + res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */ if (res == FR_OK) res = FR_DENIED; /* Not empty? */ if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ } @@ -4389,8 +4695,8 @@ FRESULT f_unlink ( } if (res == FR_OK) { res = dir_remove(&dj); /* Remove the directory entry */ - if (res == FR_OK && dclst) { /* Remove the cluster chain if exist */ -#if _FS_EXFAT + if (res == FR_OK && dclst != 0) { /* Remove the cluster chain if exist */ +#if FF_FS_EXFAT res = remove_chain(&obj, dclst, 0); #else res = remove_chain(&dj.obj, dclst, 0); @@ -4419,77 +4725,68 @@ FRESULT f_mkdir ( { FRESULT res; DIR dj; - BYTE *dir; - UINT n; - DWORD dsc, dcl, pcl, tm; + FFOBJID sobj; + DWORD dcl, pcl, tm; DEF_NAMBUF - /* Get logical drive */ - res = find_volume(fs, FA_WRITE); - dj.obj.fs = fs; + res = find_volume(fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { + dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ - if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { + if (res == FR_OK) res = FR_EXIST; /* Name collision? */ + if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */ res = FR_INVALID_NAME; } - if (res == FR_NO_FILE) { /* Can create a new directory */ - dcl = create_chain(&dj.obj, 0); /* Allocate a cluster for the new directory table */ - dj.obj.objsize = (DWORD)fs->csize * SS(fs); + if (res == FR_NO_FILE) { /* It is clear to create a new directory */ + sobj.fs = fs; /* New object id to create a new chain */ + dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ res = FR_OK; - if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ - if (dcl == 1) res = FR_INT_ERR; - if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) res = sync_window(fs); /* Flush FAT */ + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */ + if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */ + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */ tm = GET_FATTIME(); - if (res == FR_OK) { /* Initialize the new directory table */ - dsc = clust2sect(fs, dcl); - dir = fs->win; - mem_set(dir, 0, SS(fs)); - if (!_FS_EXFAT || fs->fs_type != FS_EXFAT) { - mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */ - dir[DIR_Name] = '.'; - dir[DIR_Attr] = AM_DIR; - st_dword(dir + DIR_ModTime, tm); - st_clust(fs, dir, dcl); - mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */ - dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; - if (fs->fs_type == FS_FAT32 && pcl == fs->dirbase) pcl = 0; - st_clust(fs, dir + SZDIRE, pcl); - } - for (n = fs->csize; n; n--) { /* Write dot entries and clear following sectors */ - fs->winsect = dsc++; - fs->wflag = 1; - res = sync_window(fs); - if (res != FR_OK) break; - mem_set(dir, 0, SS(fs)); + if (res == FR_OK) { + res = dir_clear(fs, dcl); /* Clean up the new table */ + if (res == FR_OK) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */ + mem_set(fs->win + DIR_Name, ' ', 11); /* Create "." entry */ + fs->win[DIR_Name] = '.'; + fs->win[DIR_Attr] = AM_DIR; + st_dword(fs->win + DIR_ModTime, tm); + st_clust(fs, fs->win, dcl); + mem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */ + fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; + st_clust(fs, fs->win + SZDIRE, pcl); + fs->wflag = 1; + } + res = dir_register(&dj); /* Register the object to the parent directoy */ } } - if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ if (res == FR_OK) { -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */ st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */ st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */ - st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)dj.obj.objsize); /* File size needs to be valid */ - st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)dj.obj.objsize); - fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag (contiguous) */ + st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* File size needs to be valid */ + st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs)); + fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */ fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */ res = store_xdir(&dj); } else #endif { - dir = dj.dir; - st_dword(dir + DIR_ModTime, tm); /* Created time */ - st_clust(fs, dir, dcl); /* Table start cluster */ - dir[DIR_Attr] = AM_DIR; /* Attribute */ + st_dword(dj.dir + DIR_ModTime, tm); /* Created time */ + st_clust(fs, dj.dir, dcl); /* Table start cluster */ + dj.dir[DIR_Attr] = AM_DIR; /* Attribute */ fs->wflag = 1; } - if (res == FR_OK) res = sync_fs(fs); + if (res == FR_OK) { + res = sync_fs(fs); + } } else { - remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */ + remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */ } } FREE_NAMBUF(); @@ -4513,23 +4810,25 @@ FRESULT f_rename ( { FRESULT res; DIR djo, djn; - BYTE buf[_FS_EXFAT ? SZDIRE * 2 : 24], *dir; + BYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir; DWORD dw; DEF_NAMBUF - res = find_volume(fs, FA_WRITE); + res = find_volume(fs, FA_WRITE); /* Get logical drive of the old object */ if (res == FR_OK) { djo.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&djo, path_old); /* Check old object */ if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check validity of name */ -#if _FS_LOCK != 0 - if (res == FR_OK) res = chk_lock(&djo, 2); +#if FF_FS_LOCK != 0 + if (res == FR_OK) { + res = chk_lock(&djo, 2); + } #endif if (res == FR_OK) { /* Object to be renamed is found */ -#if _FS_EXFAT - if (fs->fs_type == FS_EXFAT) { /* At exFAT */ +#if FF_FS_EXFAT + if (fs->fs_type == FS_EXFAT) { /* At exFAT volume */ BYTE nf, nn; WORD nh; @@ -4544,17 +4843,18 @@ FRESULT f_rename ( if (res == FR_OK) { nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName]; nh = ld_word(fs->dirbuf + XDIR_NameHash); - mem_cpy(fs->dirbuf, buf, SZDIRE * 2); + mem_cpy(fs->dirbuf, buf, SZDIRE * 2); /* Restore 85+C0 entry */ fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn; st_word(fs->dirbuf + XDIR_NameHash, nh); -/* Start of critical section where any interruption can cause a cross-link */ + if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ +/* Start of critical section where an interruption can cause a cross-link */ res = store_xdir(&djn); } } } else #endif - { /* At FAT12/FAT16/FAT32 */ - mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about the object except name */ + { /* At FAT/FAT32 volume */ + mem_cpy(buf, djo.dir, SZDIRE); /* Save directory entry of the object */ mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */ if (res == FR_OK) { /* Is new name already in use by any other object? */ @@ -4563,16 +4863,17 @@ FRESULT f_rename ( if (res == FR_NO_FILE) { /* It is a valid path and no name collision */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { - dir = djn.dir; /* Copy information about object except name */ - mem_cpy(dir + 13, buf + 2, 19); - dir[DIR_Attr] = buf[0] | AM_ARC; + dir = djn.dir; /* Copy directory entry of the object except name */ + mem_cpy(dir + 13, buf + 13, SZDIRE - 13); + dir[DIR_Attr] = buf[DIR_Attr]; + if (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC; /* Set archive attribute if it is a file */ fs->wflag = 1; if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) { /* Update .. entry in the sub-directory if needed */ - dw = clust2sect(fs, ld_clust(fs, dir)); - if (!dw) { + dw = clst2sect(fs, ld_clust(fs, dir)); + if (dw == 0) { res = FR_INT_ERR; } else { -/* Start of critical section where any interruption can cause a cross-link */ +/* Start of critical section where an interruption can cause a cross-link */ res = move_window(fs, dw); dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */ if (res == FR_OK && dir[1] == '.') { @@ -4590,7 +4891,7 @@ FRESULT f_rename ( res = sync_fs(fs); } } -/* End of critical section */ +/* End of the critical section */ } FREE_NAMBUF(); } @@ -4598,14 +4899,14 @@ FRESULT f_rename ( LEAVE_FF(fs, res); } -#endif /* !_FS_READONLY */ -#endif /* _FS_MINIMIZE == 0 */ -#endif /* _FS_MINIMIZE <= 1 */ -#endif /* _FS_MINIMIZE <= 2 */ +#endif /* !FF_FS_READONLY */ +#endif /* FF_FS_MINIMIZE == 0 */ +#endif /* FF_FS_MINIMIZE <= 1 */ +#endif /* FF_FS_MINIMIZE <= 2 */ -#if _USE_CHMOD && !_FS_READONLY +#if FF_USE_CHMOD && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Change Attribute */ /*-----------------------------------------------------------------------*/ @@ -4623,14 +4924,14 @@ FRESULT f_chmod ( res = find_volume(fs, FA_WRITE); /* Get logical drive */ - dj.obj.fs = fs; if (res == FR_OK) { + dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ if (res == FR_OK) { mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { fs->dirbuf[XDIR_Attr] = (attr & mask) | (fs->dirbuf[XDIR_Attr] & (BYTE)~mask); /* Apply attribute change */ res = store_xdir(&dj); @@ -4640,7 +4941,9 @@ FRESULT f_chmod ( dj.dir[DIR_Attr] = (attr & mask) | (dj.dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ fs->wflag = 1; } - if (res == FR_OK) res = sync_fs(fs); + if (res == FR_OK) { + res = sync_fs(fs); + } } FREE_NAMBUF(); } @@ -4658,7 +4961,7 @@ FRESULT f_chmod ( FRESULT f_utime ( FATFS *fs, const TCHAR* path, /* Pointer to the file/directory name */ - const FILINFO* fno /* Pointer to the time stamp to be set */ + const FILINFO* fno /* Pointer to the timestamp to be set */ ) { FRESULT res; @@ -4667,13 +4970,13 @@ FRESULT f_utime ( res = find_volume(fs, FA_WRITE); /* Get logical drive */ - dj.obj.fs = fs; if (res == FR_OK) { + dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ if (res == FR_OK && (dj.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check object validity */ if (res == FR_OK) { -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { st_dword(fs->dirbuf + XDIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); res = store_xdir(&dj); @@ -4683,7 +4986,9 @@ FRESULT f_utime ( st_dword(dj.dir + DIR_ModTime, (DWORD)fno->fdate << 16 | fno->ftime); fs->wflag = 1; } - if (res == FR_OK) res = sync_fs(fs); + if (res == FR_OK) { + res = sync_fs(fs); + } } FREE_NAMBUF(); } @@ -4691,27 +4996,25 @@ FRESULT f_utime ( LEAVE_FF(fs, res); } -#endif /* _USE_CHMOD && !_FS_READONLY */ +#endif /* FF_USE_CHMOD && !FF_FS_READONLY */ -#if _USE_LABEL +#if FF_USE_LABEL /*-----------------------------------------------------------------------*/ /* Get Volume Label */ /*-----------------------------------------------------------------------*/ FRESULT f_getlabel ( FATFS *fs, - TCHAR* label, /* Pointer to a buffer to return the volume label */ - DWORD* vsn /* Pointer to a variable to return the volume serial number */ + TCHAR* label, /* Buffer to store the volume label */ + DWORD* vsn /* Variable to store the volume serial number */ ) { FRESULT res; DIR dj; UINT si, di; -#if _LFN_UNICODE || _FS_EXFAT - WCHAR w; -#endif + WCHAR wc; /* Get logical drive */ res = find_volume(fs, 0); @@ -4721,37 +5024,40 @@ FRESULT f_getlabel ( dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read(&dj, 1); /* Find a volume label entry */ + res = DIR_READ_LABEL(&dj); /* Find a volume label entry */ if (res == FR_OK) { -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { - for (si = di = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */ - w = ld_word(dj.dir + XDIR_Label + si * 2); -#if _LFN_UNICODE - label[di++] = w; -#else - w = ff_convert(w, 0); /* Unicode -> OEM */ - if (w == 0) w = '?'; /* Replace wrong character */ - if (_DF1S && w >= 0x100) label[di++] = (char)(w >> 8); - label[di++] = (char)w; -#endif + WCHAR hs; + + for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */ + wc = ld_word(dj.dir + XDIR_Label + si * 2); + if (hs == 0 && IsSurrogate(wc)) { /* Is the code a surrogate? */ + hs = wc; continue; + } + wc = put_utf((DWORD)hs << 16 | wc, &label[di], 4); + if (wc == 0) { di = 0; break; } + di += wc; + hs = 0; } + if (hs != 0) di = 0; /* Broken surrogate pair? */ label[di] = 0; } else #endif { - si = di = 0; /* Extract volume label from AM_VOL entry with code comversion */ - do { -#if _LFN_UNICODE - w = (si < 11) ? dj.dir[si++] : ' '; - if (IsDBCS1(w) && si < 11 && IsDBCS2(dj.dir[si])) { - w = w << 8 | dj.dir[si++]; - } - label[di++] = ff_convert(w, 1); /* OEM -> Unicode */ -#else - label[di++] = dj.dir[si++]; + si = di = 0; /* Extract volume label from AM_VOL entry */ + while (si < 11) { + wc = dj.dir[si++]; +#if FF_USE_LFN && FF_LFN_UNICODE >= 1 /* Unicode output */ + if (dbc_1st((BYTE)wc) && si < 11) wc = wc << 8 | dj.dir[si++]; /* Is it a DBC? */ + wc = ff_oem2uni(wc, CODEPAGE); /* Convert it into Unicode */ + if (wc != 0) wc = put_utf(wc, &label[di], 4); /* Put it in Unicode */ + if (wc == 0) { di = 0; break; } + di += wc; +#else /* ANSI/OEM output */ + label[di++] = (TCHAR)wc; #endif - } while (di < 11); + } do { /* Truncate trailing spaces */ label[di] = 0; if (di == 0) break; @@ -4770,9 +5076,14 @@ FRESULT f_getlabel ( res = move_window(fs, fs->volbase); if (res == FR_OK) { switch (fs->fs_type) { - case FS_EXFAT: di = BPB_VolIDEx; break; - case FS_FAT32: di = BS_VolID32; break; - default: di = BS_VolID; + case FS_EXFAT: + di = BPB_VolIDEx; break; + + case FS_FAT32: + di = BS_VolID32; break; + + default: + di = BS_VolID; } *vsn = ld_dword(fs->win + di); } @@ -4783,95 +5094,88 @@ FRESULT f_getlabel ( -#if !_FS_READONLY +#if !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Set Volume Label */ /*-----------------------------------------------------------------------*/ FRESULT f_setlabel ( FATFS *fs, - const TCHAR* label /* Pointer to the volume label to set */ + const TCHAR* label /* Volume label to set with heading logical drive number */ ) { FRESULT res; DIR dj; BYTE dirvn[22]; - UINT i, j, slen; - WCHAR w; - static const char badchr[] = "\"*+,.:;<=>\?[]|\x7F"; - + UINT di; + WCHAR wc; + static const char badchr[] = "+.,;=[]/\\\"*:<>\?|\x7F"; /* [0..] for FAT, [7..] for exFAT */ +#if FF_USE_LFN + DWORD dc; +#endif /* Get logical drive */ res = find_volume(fs, FA_WRITE); if (res != FR_OK) LEAVE_FF(fs, res); - dj.obj.fs = fs; - /* Get length of given volume label */ - for (slen = 0; (UINT)label[slen] >= ' '; slen++) { } /* Get name length */ - -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ - for (i = j = 0; i < slen; ) { /* Create volume label in directory form */ - w = label[i++]; -#if !_LFN_UNICODE - if (IsDBCS1(w)) { - w = (i < slen && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0; + mem_set(dirvn, 0, 22); + di = 0; + while ((UINT)*label >= ' ') { /* Create volume label */ + dc = tchar2uni(&label); /* Get a Unicode character */ + if (dc >= 0x10000) { + if (dc == 0xFFFFFFFF || di >= 10) { /* Wrong surrogate or buffer overflow */ + dc = 0; + } else { + st_word(dirvn + di * 2, (WCHAR)(dc >> 16)); di++; + } } - w = ff_convert(w, 1); -#endif - if (w == 0 || chk_chr(badchr, w) || j == 22) { /* Check validity check validity of the volume label */ + if (dc == 0 || chk_chr(badchr + 7, (int)dc) || di >= 11) { /* Check validity of the volume label */ LEAVE_FF(fs, FR_INVALID_NAME); } - st_word(dirvn + j, w); j += 2; + st_word(dirvn + di * 2, (WCHAR)dc); di++; } - slen = j; } else #endif - { /* On the FAT12/16/32 volume */ - for ( ; slen && label[slen - 1] == ' '; slen--) ; /* Remove trailing spaces */ - if (slen) { /* Is there a volume label to be set? */ - dirvn[0] = 0; i = j = 0; /* Create volume label in directory form */ - do { -#if _LFN_UNICODE - w = ff_convert(ff_wtoupper(label[i++]), 0); -#else - w = (BYTE)label[i++]; - if (IsDBCS1(w)) { - w = (j < 10 && i < slen && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0; - } -#if _USE_LFN != 0 - w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0); -#else - if (IsLower(w)) w -= 0x20; /* To upper ASCII characters */ -#ifdef _EXCVT - if (w >= 0x80) w = ExCvt[w - 0x80]; /* To upper extended characters (SBCS cfg) */ -#else - if (!_DF1S && w >= 0x80) w = 0; /* Reject extended characters (ASCII cfg) */ + { /* On the FAT/FAT32 volume */ + mem_set(dirvn, ' ', 11); + di = 0; + while ((UINT)*label >= ' ') { /* Create volume label */ +#if FF_USE_LFN + dc = tchar2uni(&label); + wc = (dc < 0x10000) ? ff_uni2oem(ff_wtoupper(dc), CODEPAGE) : 0; +#else /* ANSI/OEM input */ + wc = (BYTE)*label++; + if (dbc_1st((BYTE)wc)) wc = dbc_2nd((BYTE)*label) ? wc << 8 | (BYTE)*label++ : 0; + if (IsLower(wc)) wc -= 0x20; /* To upper ASCII characters */ +#if FF_CODE_PAGE == 0 + if (ExCvt && wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ +#elif FF_CODE_PAGE < 900 + if (wc >= 0x80) wc = ExCvt[wc - 0x80]; /* To upper extended characters (SBCS cfg) */ #endif #endif -#endif - if (w == 0 || chk_chr(badchr, w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) { /* Reject invalid characters for volume label */ - LEAVE_FF(fs, FR_INVALID_NAME); - } - if (w >= 0x100) dirvn[j++] = (BYTE)(w >> 8); - dirvn[j++] = (BYTE)w; - } while (i < slen); - while (j < 11) dirvn[j++] = ' '; /* Fill remaining name field */ - if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ + if (wc == 0 || chk_chr(badchr + 0, (int)wc) || di >= (UINT)((wc >= 0x100) ? 10 : 11)) { /* Reject invalid characters for volume label */ + LEAVE_FF(fs, FR_INVALID_NAME); + } + if (wc >= 0x100) dirvn[di++] = (BYTE)(wc >> 8); + dirvn[di++] = (BYTE)wc; } + if (dirvn[0] == DDEM) LEAVE_FF(fs, FR_INVALID_NAME); /* Reject illegal name (heading DDEM) */ + while (di && dirvn[di - 1] == ' ') di--; /* Snip trailing spaces */ } /* Set volume label */ - dj.obj.sclust = 0; /* Open root directory */ + dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read(&dj, 1); /* Get volume label entry */ + res = DIR_READ_LABEL(&dj); /* Get volume label entry */ if (res == FR_OK) { - if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_NumLabel] = (BYTE)(slen / 2); /* Change the volume label */ - mem_cpy(dj.dir + XDIR_Label, dirvn, slen); + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { + dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ + mem_cpy(dj.dir + XDIR_Label, dirvn, 22); } else { - if (slen) { + if (di != 0) { mem_cpy(dj.dir, dirvn, 11); /* Change the volume label */ } else { dj.dir[DIR_Name] = DDEM; /* Remove the volume label */ @@ -4879,17 +5183,17 @@ FRESULT f_setlabel ( } fs->wflag = 1; res = sync_fs(fs); - } else { /* No volume label entry is found or error */ + } else { /* No volume label entry or an error */ if (res == FR_NO_FILE) { res = FR_OK; - if (slen) { /* Create a volume label entry */ + if (di != 0) { /* Create a volume label entry */ res = dir_alloc(&dj, 1); /* Allocate an entry */ if (res == FR_OK) { - mem_set(dj.dir, 0, SZDIRE); /* Clear the entry */ - if (_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ - dj.dir[XDIR_NumLabel] = (BYTE)(slen / 2); - mem_cpy(dj.dir + XDIR_Label, dirvn, slen); + mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */ + if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { + dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */ + dj.dir[XDIR_NumLabel] = (BYTE)di; + mem_cpy(dj.dir + XDIR_Label, dirvn, 22); } else { dj.dir[DIR_Attr] = AM_VOL; /* Create volume label entry */ mem_cpy(dj.dir, dirvn, 11); @@ -4905,12 +5209,12 @@ FRESULT f_setlabel ( LEAVE_FF(fs, res); } -#endif /* !_FS_READONLY */ -#endif /* _USE_LABEL */ +#endif /* !FF_FS_READONLY */ +#endif /* FF_USE_LABEL */ -#if _USE_EXPAND && !_FS_READONLY +#if FF_USE_EXPAND && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ /* Allocate a Contiguous Blocks to the File */ /*-----------------------------------------------------------------------*/ @@ -4929,7 +5233,7 @@ FRESULT f_expand ( res = validate(&fp->obj, &fs); /* Check validity of the file object */ if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); if (fsz == 0 || fp->obj.objsize != 0 || !(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type != FS_EXFAT && fsz >= 0x100000000) LEAVE_FF(fs, FR_DENIED); /* Check if in size limit */ #endif n = (DWORD)fs->csize * SS(fs); /* Cluster size */ @@ -4937,16 +5241,16 @@ FRESULT f_expand ( stcl = fs->last_clst; lclst = 0; if (stcl < 2 || stcl >= fs->n_fatent) stcl = 2; -#if _FS_EXFAT +#if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { scl = find_bitmap(fs, stcl, tcl); /* Find a contiguous cluster block */ if (scl == 0) res = FR_DENIED; /* No contiguous cluster block was found */ if (scl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) { - if (opt) { + if (res == FR_OK) { /* A contiguous free area is found */ + if (opt) { /* Allocate it now */ res = change_bitmap(fs, scl, tcl, 1); /* Mark the cluster block 'in use' */ lclst = scl + tcl - 1; - } else { + } else { /* Set it as suggested point for next allocation */ lclst = scl - 1; } } @@ -4966,14 +5270,14 @@ FRESULT f_expand ( } if (clst == stcl) { res = FR_DENIED; break; } /* No contiguous cluster? */ } - if (res == FR_OK) { - if (opt) { + if (res == FR_OK) { /* A contiguous free area is found */ + if (opt) { /* Allocate it now */ for (clst = scl, n = tcl; n; clst++, n--) { /* Create a cluster chain on the FAT */ res = put_fat(fs, clst, (n == 1) ? 0xFFFFFFFF : clst + 1); if (res != FR_OK) break; lclst = clst; } - } else { + } else { /* Set it as suggested point for next allocation */ lclst = scl - 1; } } @@ -4981,12 +5285,12 @@ FRESULT f_expand ( if (res == FR_OK) { fs->last_clst = lclst; /* Set suggested start cluster to start next */ - if (opt) { + if (opt) { /* Is it allocated now? */ fp->obj.sclust = scl; /* Update object allocation information */ fp->obj.objsize = fsz; - if (_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ + if (FF_FS_EXFAT) fp->obj.stat = 2; /* Set status 'contiguous chain' */ fp->flag |= FA_MODIFIED; - if (fs->free_clst < fs->n_fatent - 2) { /* Update FSINFO */ + if (fs->free_clst <= fs->n_fatent - 2) { /* Update FSINFO */ fs->free_clst -= tcl; fs->fsi_flag |= 1; } @@ -4996,13 +5300,13 @@ FRESULT f_expand ( LEAVE_FF(fs, res); } -#endif /* _USE_EXPAND && !_FS_READONLY */ +#endif /* FF_USE_EXPAND && !FF_FS_READONLY */ -#if _USE_FORWARD +#if FF_USE_FORWARD /*-----------------------------------------------------------------------*/ -/* Forward data to the stream directly */ +/* Forward Data to the Stream Directly */ /*-----------------------------------------------------------------------*/ FRESULT f_forward ( @@ -5040,15 +5344,15 @@ FRESULT f_forward ( fp->clust = clst; /* Update current cluster */ } } - sect = clust2sect(fs, fp->clust); /* Get current data sector */ - if (!sect) ABORT(fs, FR_INT_ERR); + sect = clst2sect(fs, fp->clust); /* Get current data sector */ + if (sect == 0) ABORT(fs, FR_INT_ERR); sect += csect; -#if _FS_TINY +#if FF_FS_TINY if (move_window(fs, sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window to the file data */ dbuf = fs->win; #else if (fp->sect != sect) { /* Fill sector cache with file data */ -#if !_FS_READONLY +#if !FF_FS_READONLY if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */ if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); fp->flag &= (BYTE)~FA_DIRTY; @@ -5062,40 +5366,40 @@ FRESULT f_forward ( rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */ if (rcnt > btf) rcnt = btf; /* Clip it by btr if needed */ rcnt = (*func)(dbuf + ((UINT)fp->fptr % SS(fs)), rcnt); /* Forward the file data */ - if (!rcnt) ABORT(fs, FR_INT_ERR); + if (rcnt == 0) ABORT(fs, FR_INT_ERR); } LEAVE_FF(fs, FR_OK); } -#endif /* _USE_FORWARD */ +#endif /* FF_USE_FORWARD */ -#if _USE_MKFS && !_FS_READONLY +#if FF_USE_MKFS && !FF_FS_READONLY /*-----------------------------------------------------------------------*/ -/* Create FAT file system on the logical drive */ +/* Create an FAT/exFAT volume */ /*-----------------------------------------------------------------------*/ FRESULT f_mkfs ( FATFS *fs, BYTE opt, /* Format option */ - DWORD au, /* Size of allocation unit [byte] */ - void* work, /* Pointer to working buffer */ - UINT len /* Size of working buffer */ + DWORD au, /* Size of allocation unit (cluster) [byte] */ + void* work, /* Pointer to working buffer (null: use heap memory) */ + UINT len /* Size of working buffer [byte] */ ) { - const UINT n_fats = 1; /* Number of FATs for FAT12/16/32 volume (1 or 2) */ - const UINT n_rootdir = 512; /* Number of root directory entries for FAT12/16 volume */ - static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT12/16 volume (4Ks unit) */ + const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */ + const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */ + static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */ static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ BYTE fmt, sys, *buf, *pte, part; void *pdrv; - WORD ss; + WORD ss; /* Sector size */ DWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n; DWORD b_vol, b_fat, b_data; /* Base LBA for volume, fat, data */ DWORD sz_vol, sz_rsv, sz_fat, sz_dir; /* Size for volume, fat, dir, data */ UINT i; DSTATUS stat; -#if _USE_TRIM || _FS_EXFAT +#if FF_USE_TRIM || FF_FS_EXFAT DWORD tbl[3]; #endif @@ -5110,70 +5414,78 @@ FRESULT f_mkfs ( if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */ -#if _MAX_SS != _MIN_SS /* Get sector size of the medium */ +#if FF_MAX_SS != FF_MIN_SS /* Get sector size of the medium if variable sector size cfg. */ if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; - if (ss > _MAX_SS || ss < _MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; + if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR; #else - ss = _MAX_SS; + ss = FF_MAX_SS; #endif if ((au != 0 && au < ss) || au > 0x1000000 || (au & (au - 1))) return FR_INVALID_PARAMETER; /* Check if au is valid */ au /= ss; /* Cluster size in unit of sector */ /* Get working buffer */ - buf = (BYTE*)work; /* Working buffer */ - sz_buf = len / ss; /* Size of working buffer (sector) */ - szb_buf = sz_buf * ss; /* Size of working buffer (byte) */ - if (!szb_buf) return FR_MKFS_ABORTED; +#if FF_USE_LFN == 3 + if (!work) { /* Use heap memory for working buffer */ + for (szb_buf = MAX_MALLOC, buf = 0; szb_buf >= ss && (buf = ff_memalloc(szb_buf)) == 0; szb_buf /= 2) ; + sz_buf = szb_buf / ss; /* Size of working buffer (sector) */ + } else +#endif + { + buf = (BYTE*)work; /* Working buffer */ + sz_buf = len / ss; /* Size of working buffer (sector) */ + szb_buf = sz_buf * ss; /* Size of working buffer (byte) */ + } + if (!buf || sz_buf == 0) return FR_NOT_ENOUGH_CORE; /* Determine where the volume to be located (b_vol, sz_vol) */ - if (_MULTI_PARTITION && part != 0) { + if (FF_MULTI_PARTITION && part != 0) { /* Get partition information from partition table in the MBR */ - if (disk_read(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Load MBR */ - if (ld_word(buf + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; /* Check if MBR is valid */ + if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */ + if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */ pte = buf + (MBR_Table + (part - 1) * SZ_PTE); - if (!pte[PTE_System]) return FR_MKFS_ABORTED; /* No partition? */ + if (pte[PTE_System] == 0) LEAVE_MKFS(FR_MKFS_ABORTED); /* No partition? */ b_vol = ld_dword(pte + PTE_StLba); /* Get volume start sector */ sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */ } else { /* Create a single-partition in this function */ - if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) return FR_DISK_ERR; + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */ - if (sz_vol < b_vol) return FR_MKFS_ABORTED; + if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); sz_vol -= b_vol; /* Volume size */ } - if (sz_vol < 50) return FR_MKFS_ABORTED; /* Check if volume size is >=50s */ + if (sz_vol < 22) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if volume size is >=22s (minimum for ss=4096) */ /* Pre-determine the FAT type */ do { - if (_FS_EXFAT && (opt & FM_EXFAT)) { /* exFAT possible? */ + if (FF_FS_EXFAT && (opt & FM_EXFAT)) { /* exFAT possible? */ if ((opt & FM_ANY) == FM_EXFAT || sz_vol >= 0x4000000 || au > 128) { /* exFAT only, vol >= 64Ms or au > 128s ? */ fmt = FS_EXFAT; break; } } - if (au > 128) return FR_INVALID_PARAMETER; /* Too large au for FAT/FAT32 */ + if (au > 128) LEAVE_MKFS(FR_INVALID_PARAMETER); /* Too large au for FAT/FAT32 */ if (opt & FM_FAT32) { /* FAT32 possible? */ if ((opt & FM_ANY) == FM_FAT32 || !(opt & FM_FAT)) { /* FAT32 only or no-FAT? */ fmt = FS_FAT32; break; } } - if (!(opt & FM_FAT)) return FR_INVALID_PARAMETER; /* no-FAT? */ + if (!(opt & FM_FAT)) LEAVE_MKFS(FR_INVALID_PARAMETER); /* no-FAT? */ fmt = FS_FAT16; } while (0); -#if _FS_EXFAT +#if FF_FS_EXFAT if (fmt == FS_EXFAT) { /* Create an exFAT volume */ DWORD szb_bit, szb_case, sum, nb, cl; WCHAR ch, si; UINT j, st; BYTE b; - if (sz_vol < 0x1000) return FR_MKFS_ABORTED; /* Too small volume? */ -#if _USE_TRIM - tbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1; /* Inform the device the volume area can be erased */ + if (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ +#if FF_USE_TRIM + tbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1; /* Inform the device the volume area may be erased */ disk_ioctl(pdrv, CTRL_TRIM, tbl); #endif /* Determine FAT location, data location and number of clusters */ - if (!au) { /* au auto-selection */ + if (au == 0) { /* au auto-selection */ au = 8; if (sz_vol >= 0x80000) au = 64; /* >= 512Ks */ if (sz_vol >= 0x4000000) au = 256; /* >= 64Ms */ @@ -5181,10 +5493,10 @@ FRESULT f_mkfs ( b_fat = b_vol + 32; /* FAT start at offset 32 */ sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ b_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1); /* Align data area to the erase block boundary */ - if (b_data >= sz_vol / 2) return FR_MKFS_ABORTED; /* Too small volume? */ + if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */ - if (n_clst <16) return FR_MKFS_ABORTED; /* Too few clusters? */ - if (n_clst > MAX_EXFAT) return FR_MKFS_ABORTED; /* Too many clusters? */ + if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ + if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ szb_bit = (n_clst + 7) / 8; /* Size of allocation bitmap */ tbl[0] = (szb_bit + au * ss - 1) / (au * ss); /* Number of allocation bitmap clusters */ @@ -5192,11 +5504,11 @@ FRESULT f_mkfs ( /* Create a compressed up-case table */ sect = b_data + au * tbl[0]; /* Table start sector */ sum = 0; /* Table checksum to be stored in the 82 entry */ - st = si = i = j = szb_case = 0; + st = 0; si = 0; i = 0; j = 0; szb_case = 0; do { switch (st) { case 0: - ch = ff_wtoupper(si); /* Get an up-case char */ + ch = (WCHAR)ff_wtoupper(si); /* Get an up-case char */ if (ch != si) { si++; break; /* Store the up-case char if exist */ } @@ -5205,21 +5517,22 @@ FRESULT f_mkfs ( ch = 0xFFFF; st = 2; break; /* Compress the no-case block if run is >= 128 */ } st = 1; /* Do not compress short run */ - /* continue */ + /* go to next case */ case 1: ch = si++; /* Fill the short run */ if (--j == 0) st = 0; break; + default: - ch = (WCHAR)j; si += j; /* Number of chars to skip */ + ch = (WCHAR)j; si += (WCHAR)j; /* Number of chars to skip */ st = 0; } sum = xsum32(buf[i + 0] = (BYTE)ch, sum); /* Put it into the write buffer */ sum = xsum32(buf[i + 1] = (BYTE)(ch >> 8), sum); i += 2; szb_case += 2; - if (!si || i == szb_buf) { /* Write buffered data when buffer full or end of process */ + if (si == 0 || i == szb_buf) { /* Write buffered data when buffer full or end of process */ n = (i + ss - 1) / ss; - if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; i = 0; } } while (si); @@ -5232,9 +5545,9 @@ FRESULT f_mkfs ( do { mem_set(buf, 0, szb_buf); for (i = 0; nb >= 8 && i < szb_buf; buf[i++] = 0xFF, nb -= 8) ; - for (b = 1; nb && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ; + for (b = 1; nb != 0 && i < szb_buf; buf[i] |= b, b <<= 1, nb--) ; n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ - if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); @@ -5248,31 +5561,31 @@ FRESULT f_mkfs ( st_dword(buf + i, 0xFFFFFFFF); i += 4; cl++; } do { /* Create chains of bitmap, up-case and root dir */ - while (nb && i < szb_buf) { /* Create a chain */ + while (nb != 0 && i < szb_buf) { /* Create a chain */ st_dword(buf + i, (nb > 1) ? cl + 1 : 0xFFFFFFFF); i += 4; cl++; nb--; } - if (!nb && j < 3) nb = tbl[j++]; /* Next chain */ - } while (nb && i < szb_buf); + if (nb == 0 && j < 3) nb = tbl[j++]; /* Next chain */ + } while (nb != 0 && i < szb_buf); n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */ - if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); /* Initialize the root directory */ mem_set(buf, 0, szb_buf); - buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ - buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ - st_dword(buf + SZDIRE * 1 + 20, 2); - st_dword(buf + SZDIRE * 1 + 24, szb_bit); - buf[SZDIRE * 2 + 0] = 0x82; /* 82 entry (up-case table) */ - st_dword(buf + SZDIRE * 2 + 4, sum); - st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); - st_dword(buf + SZDIRE * 2 + 24, szb_case); + buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry */ + buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */ + st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ + st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ + buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */ + st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ + st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */ + st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ sect = b_data + au * (tbl[0] + tbl[1]); nsect = au; /* Start of the root directory and number of sectors */ do { /* Fill root directory sectors */ n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); mem_set(buf, 0, ss); sect += n; nsect -= n; } while (nsect); @@ -5291,7 +5604,7 @@ FRESULT f_mkfs ( st_dword(buf + BPB_NumClusEx, n_clst); /* Number of clusters */ st_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]); /* Root dir cluster # */ st_dword(buf + BPB_VolIDEx, GET_FATTIME()); /* VSN */ - st_word(buf + BPB_FSVerEx, 0x100); /* File system version (1.00) */ + st_word(buf + BPB_FSVerEx, 0x100); /* Filesystem version (1.00) */ for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ; /* Log2 of sector size [byte] */ for (buf[BPB_SecPerClusEx] = 0, i = au; i >>= 1; buf[BPB_SecPerClusEx]++) ; /* Log2 of cluster size [sector] */ buf[BPB_NumFATsEx] = 1; /* Number of FATs */ @@ -5301,33 +5614,33 @@ FRESULT f_mkfs ( for (i = sum = 0; i < ss; i++) { /* VBR checksum */ if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum); } - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Extended bootstrap record (+1..+8) */ mem_set(buf, 0, ss); st_word(buf + ss - 2, 0xAA55); /* Signature (placed at end of sector) */ for (j = 1; j < 9; j++) { for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } /* OEM/Reserved record (+9..+10) */ mem_set(buf, 0, ss); for ( ; j < 11; j++) { for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } /* Sum record (+11) */ for (i = 0; i < ss; i += 4) st_dword(buf + i, sum); /* Fill with checksum value */ - if (disk_write(pdrv, buf, sect++, 1) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); } } else -#endif /* _FS_EXFAT */ - { /* Create an FAT12/16/32 volume */ +#endif /* FF_FS_EXFAT */ + { /* Create an FAT/FAT32 volume */ do { pau = au; /* Pre-determine number of clusters and FAT sub-type */ if (fmt == FS_FAT32) { /* FAT32 volume */ - if (!pau) { /* au auto-selection */ + if (pau == 0) { /* au auto-selection */ n = sz_vol / 0x20000; /* Volume size in unit of 128KS */ for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */ } @@ -5335,9 +5648,9 @@ FRESULT f_mkfs ( sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */ sz_rsv = 32; /* Number of reserved sectors */ sz_dir = 0; /* No static directory */ - if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) return FR_MKFS_ABORTED; - } else { /* FAT12/16 volume */ - if (!pau) { /* au auto-selection */ + if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); + } else { /* FAT volume */ + if (pau == 0) { /* au auto-selection */ n = sz_vol / 0x1000; /* Volume size in unit of 4KS */ for (i = 0, pau = 1; cst[i] && cst[i] <= n; i++, pau <<= 1) ; /* Get from table */ } @@ -5359,42 +5672,42 @@ FRESULT f_mkfs ( n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */ if (fmt == FS_FAT32) { /* FAT32: Move FAT base */ sz_rsv += n; b_fat += n; - } else { /* FAT12/16: Expand FAT size */ + } else { /* FAT: Expand FAT size */ sz_fat += n / n_fats; } /* Determine number of clusters and final check of validity of the FAT sub-type */ - if (sz_vol < b_data + pau * 16 - b_vol) return FR_MKFS_ABORTED; /* Too small volume */ + if (sz_vol < b_data + pau * 16 - b_vol) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume */ n_clst = (sz_vol - sz_rsv - sz_fat * n_fats - sz_dir) / pau; if (fmt == FS_FAT32) { if (n_clst <= MAX_FAT16) { /* Too few clusters for FAT32 */ - if (!au && (au = pau / 2) != 0) continue; /* Adjust cluster size and retry */ - return FR_MKFS_ABORTED; + if (au == 0 && (au = pau / 2) != 0) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); } } if (fmt == FS_FAT16) { if (n_clst > MAX_FAT16) { /* Too many clusters for FAT16 */ - if (!au && (pau * 2) <= 64) { + if (au == 0 && (pau * 2) <= 64) { au = pau * 2; continue; /* Adjust cluster size and retry */ } if ((opt & FM_FAT32)) { fmt = FS_FAT32; continue; /* Switch type to FAT32 and retry */ } - if (!au && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ - return FR_MKFS_ABORTED; + if (au == 0 && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); } if (n_clst <= MAX_FAT12) { /* Too few clusters for FAT16 */ - if (!au && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ - return FR_MKFS_ABORTED; + if (au == 0 && (au = pau * 2) <= 128) continue; /* Adjust cluster size and retry */ + LEAVE_MKFS(FR_MKFS_ABORTED); } } - if (fmt == FS_FAT12 && n_clst > MAX_FAT12) return FR_MKFS_ABORTED; /* Too many clusters for FAT12 */ + if (fmt == FS_FAT12 && n_clst > MAX_FAT12) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters for FAT12 */ /* Ok, it is the valid cluster configuration */ break; } while (1); -#if _USE_TRIM +#if FF_USE_TRIM tbl[0] = b_vol; tbl[1] = b_vol + sz_vol - 1; /* Inform the device the volume area can be erased */ disk_ioctl(pdrv, CTRL_TRIM, tbl); #endif @@ -5432,7 +5745,7 @@ FRESULT f_mkfs ( mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ } st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */ - if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the VBR sector */ + if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */ /* Create FSINFO record if needed */ if (fmt == FS_FAT32) { @@ -5461,7 +5774,7 @@ FRESULT f_mkfs ( nsect = sz_fat; /* Number of FAT sectors */ do { /* Fill FAT sectors */ n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); mem_set(buf, 0, ss); sect += n; nsect -= n; } while (nsect); @@ -5471,34 +5784,34 @@ FRESULT f_mkfs ( nsect = (fmt == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */ do { n = (nsect > sz_buf) ? sz_buf : nsect; - if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) return FR_DISK_ERR; + if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); sect += n; nsect -= n; } while (nsect); } /* Determine system ID in the partition table */ - if (_FS_EXFAT && fmt == FS_EXFAT) { + if (FF_FS_EXFAT && fmt == FS_EXFAT) { sys = 0x07; /* HPFS/NTFS/exFAT */ } else { if (fmt == FS_FAT32) { sys = 0x0C; /* FAT32X */ } else { if (sz_vol >= 0x10000) { - sys = 0x06; /* FAT12/16 (>=64KS) */ + sys = 0x06; /* FAT12/16 (large) */ } else { - sys = (fmt == FS_FAT16) ? 0x04 : 0x01; /* FAT16 (<64KS) : FAT12 (<64KS) */ + sys = (fmt == FS_FAT16) ? 0x04 : 0x01; /* FAT16 : FAT12 */ } } } - if (_MULTI_PARTITION && part != 0) { + /* Update partition information */ + if (FF_MULTI_PARTITION && part != 0) { /* Created in the existing partition */ /* Update system ID in the partition table */ - if (disk_read(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Read the MBR */ - buf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys; /* Set system type */ - if (disk_write(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it back to the MBR */ - } else { - if (!(opt & FM_SFD)) { - /* Create partition table in FDISK format */ + if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */ + buf[MBR_Table + (part - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */ + if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */ + } else { /* Created as a new single partition */ + if (!(opt & FM_SFD)) { /* Create partition table if in FDISK format */ mem_set(buf, 0, ss); st_word(buf + BS_55AA, 0xAA55); /* MBR signature */ pte = buf + MBR_Table; /* Create partition table for single partition in the drive */ @@ -5507,38 +5820,39 @@ FRESULT f_mkfs ( pte[PTE_StSec] = 1; /* Start sector */ pte[PTE_StCyl] = 0; /* Start cylinder */ pte[PTE_System] = sys; /* System type */ - n = (b_vol + sz_vol) / (63 * 255); /* (End CHS is incorrect) */ + n = (b_vol + sz_vol) / (63 * 255); /* (End CHS may be invalid) */ pte[PTE_EdHead] = 254; /* End head */ - pte[PTE_EdSec] = (BYTE)(n >> 2 | 63); /* End sector */ + pte[PTE_EdSec] = (BYTE)(((n >> 2) & 0xC0) | 63); /* End sector */ pte[PTE_EdCyl] = (BYTE)n; /* End cylinder */ st_dword(pte + PTE_StLba, b_vol); /* Start offset in LBA */ st_dword(pte + PTE_SizLba, sz_vol); /* Size in sectors */ - if (disk_write(pdrv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the MBR */ + if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the MBR */ } } - if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) return FR_DISK_ERR; + if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); - return FR_OK; + LEAVE_MKFS(FR_OK); } -#if _MULTI_PARTITION +#if FF_MULTI_PARTITION /*-----------------------------------------------------------------------*/ -/* Create partition table on the physical drive */ +/* Create Partition Table on the Physical Drive */ /*-----------------------------------------------------------------------*/ FRESULT f_fdisk ( void *pdrv, /* Physical drive number */ const DWORD* szt, /* Pointer to the size table for each partitions */ - void* work /* Pointer to the working buffer */ + void* work /* Pointer to the working buffer (null: use heap memory) */ ) { UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl; BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; DSTATUS stat; DWORD sz_disk, sz_part, s_part; + FRESULT res; disk_ioctl(pdrv, IOCTL_INIT, &stat); @@ -5546,19 +5860,25 @@ FRESULT f_fdisk ( if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; - /* Determine the CHS without any care of the drive geometry */ + buf = (BYTE*)work; +#if FF_USE_LFN == 3 + if (!buf) buf = ff_memalloc(FF_MAX_SS); /* Use heap memory for working buffer */ +#endif + if (!buf) return FR_NOT_ENOUGH_CORE; + + /* Determine the CHS without any consideration of the drive geometry */ for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; if (n == 256) n--; - e_hd = n - 1; + e_hd = (BYTE)(n - 1); sz_cyl = 63 * n; tot_cyl = sz_disk / sz_cyl; /* Create partition table */ - mem_set(buf, 0, _MAX_SS); + mem_set(buf, 0, FF_MAX_SS); p = buf + MBR_Table; b_cyl = 0; for (i = 0; i < 4; i++, p += SZ_PTE) { - p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; - if (!p_cyl) continue; + p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; /* Number of cylinders */ + if (p_cyl == 0) continue; s_part = (DWORD)sz_cyl * b_cyl; sz_part = (DWORD)sz_cyl * p_cyl; if (i == 0) { /* Exclude first track of cylinder 0 */ @@ -5567,28 +5887,60 @@ FRESULT f_fdisk ( } else { s_hd = 0; } - e_cyl = b_cyl + p_cyl - 1; - if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER; + e_cyl = b_cyl + p_cyl - 1; /* End cylinder */ + if (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER); /* Set partition table */ p[1] = s_hd; /* Start head */ - p[2] = (BYTE)((b_cyl >> 2) + 1); /* Start sector */ + p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1); /* Start sector */ p[3] = (BYTE)b_cyl; /* Start cylinder */ - p[4] = 0x06; /* System type (temporary setting) */ + p[4] = 0x07; /* System type (temporary setting) */ p[5] = e_hd; /* End head */ - p[6] = (BYTE)((e_cyl >> 2) + 63); /* End sector */ + p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63); /* End sector */ p[7] = (BYTE)e_cyl; /* End cylinder */ st_dword(p + 8, s_part); /* Start sector in LBA */ - st_dword(p + 12, sz_part); /* Partition size */ + st_dword(p + 12, sz_part); /* Number of sectors */ /* Next partition */ b_cyl += p_cyl; } - st_word(p, 0xAA55); + st_word(p, 0xAA55); /* MBR signature (always at offset 510) */ /* Write it to the MBR */ - return (disk_write(pdrv, buf, 0, 1) != RES_OK || disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) ? FR_DISK_ERR : FR_OK; + res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; + LEAVE_MKFS(res); } -#endif /* _MULTI_PARTITION */ -#endif /* _USE_MKFS && !_FS_READONLY */ +#endif /* FF_MULTI_PARTITION */ +#endif /* FF_USE_MKFS && !FF_FS_READONLY */ + + + +#if FF_CODE_PAGE == 0 +/*-----------------------------------------------------------------------*/ +/* Set Active Codepage for the Path Name */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setcp ( + WORD cp /* Value to be set as active code page */ +) +{ + static const WORD validcp[] = { 437, 720, 737, 771, 775, 850, 852, 857, 860, 861, 862, 863, 864, 865, 866, 869, 932, 936, 949, 950, 0}; + static const BYTE* const tables[] = {Ct437, Ct720, Ct737, Ct771, Ct775, Ct850, Ct852, Ct857, Ct860, Ct861, Ct862, Ct863, Ct864, Ct865, Ct866, Ct869, Dc932, Dc936, Dc949, Dc950, 0}; + UINT i; + + + for (i = 0; validcp[i] != 0 && validcp[i] != cp; i++) ; /* Find the code page */ + if (validcp[i] != cp) return FR_INVALID_PARAMETER; /* Not found? */ + + CodePage = cp; + if (cp >= 900) { /* DBCS */ + ExCvt = 0; + DbcTbl = tables[i]; + } else { /* SBCS */ + ExCvt = tables[i]; + DbcTbl = 0; + } + return FR_OK; +} +#endif /* FF_CODE_PAGE == 0 */ diff --git a/lib/oofatfs/ff.h b/lib/oofatfs/ff.h index 068de11660..a8aa00e9af 100644 --- a/lib/oofatfs/ff.h +++ b/lib/oofatfs/ff.h @@ -3,10 +3,10 @@ */ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT file system module R0.12b / +/ FatFs - Generic FAT Filesystem module R0.13c / /-----------------------------------------------------------------------------/ / -/ Copyright (C) 2016, ChaN, all right reserved. +/ Copyright (C) 2018, ChaN, all right reserved. / / FatFs module is an open source software. Redistribution and use of FatFs in / source and binary forms, with or without modification, are permitted provided @@ -19,81 +19,93 @@ / and any warranties related to this software are DISCLAIMED. / The copyright owner or contributors be NOT LIABLE for any damages caused / by use of this software. +/ /----------------------------------------------------------------------------*/ -#ifndef _FATFS -#define _FATFS 68020 /* Revision ID */ +#ifndef FF_DEFINED +#define FF_DEFINED 86604 /* Revision ID */ #ifdef __cplusplus extern "C" { #endif -#include +#include FFCONF_H /* FatFs configuration options */ -/* This type MUST be 8-bit */ -typedef uint8_t BYTE; - -/* These types MUST be 16-bit */ -typedef int16_t SHORT; -typedef uint16_t WORD; -typedef uint16_t WCHAR; - -/* These types MUST be 16-bit or 32-bit */ -typedef int INT; -typedef unsigned int UINT; - -/* These types MUST be 32-bit */ -typedef int32_t LONG; -typedef uint32_t DWORD; - -/* This type MUST be 64-bit (Remove this for C89 compatibility) */ -typedef uint64_t QWORD; - -#include FFCONF_H /* FatFs configuration options */ - -#if _FATFS != _FFCONF +#if FF_DEFINED != FFCONF_DEF #error Wrong configuration file (ffconf.h). #endif +/* Integer types used for FatFs API */ + +#if defined(_WIN32) /* Main development platform */ +#define FF_INTDEF 2 +#include +typedef unsigned __int64 QWORD; +#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ +#define FF_INTDEF 2 +#include +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef uint16_t WORD; /* 16-bit unsigned integer */ +typedef uint16_t WCHAR; /* 16-bit unsigned integer */ +typedef uint32_t DWORD; /* 32-bit unsigned integer */ +typedef uint64_t QWORD; /* 64-bit unsigned integer */ +#else /* Earlier than C99 */ +#define FF_INTDEF 1 +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef unsigned short WORD; /* 16-bit unsigned integer */ +typedef unsigned short WCHAR; /* 16-bit unsigned integer */ +typedef unsigned long DWORD; /* 32-bit unsigned integer */ +#endif + /* Definitions of volume management */ -#if _MULTI_PARTITION /* Multiple partition configuration */ -#define LD2PT(fs) (fs->part) /* Get partition index */ -#else /* Single partition configuration */ -#define LD2PT(fs) 0 /* Find first valid partition or in SFD */ +#if FF_STR_VOLUME_ID +#ifndef FF_VOLUME_STRS +extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */ +#endif #endif /* Type of path name strings on FatFs API */ -#if _LFN_UNICODE /* Unicode (UTF-16) string */ -#if _USE_LFN == 0 -#error _LFN_UNICODE must be 0 at non-LFN cfg. -#endif #ifndef _INC_TCHAR +#define _INC_TCHAR + +#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */ typedef WCHAR TCHAR; #define _T(x) L ## x #define _TEXT(x) L ## x -#endif -#else /* ANSI/OEM string */ -#ifndef _INC_TCHAR +#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */ +typedef char TCHAR; +#define _T(x) u8 ## x +#define _TEXT(x) u8 ## x +#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */ +typedef DWORD TCHAR; +#define _T(x) U ## x +#define _TEXT(x) U ## x +#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3) +#error Wrong FF_LFN_UNICODE setting +#else /* ANSI/OEM code in SBCS/DBCS */ typedef char TCHAR; #define _T(x) x #define _TEXT(x) x #endif + #endif /* Type of file size variables */ -#if _FS_EXFAT -#if _USE_LFN == 0 -#error LFN must be enabled when enable exFAT +#if FF_FS_EXFAT +#if FF_INTDEF != 2 +#error exFAT feature wants C99 or later #endif typedef QWORD FSIZE_t; #else @@ -102,39 +114,39 @@ typedef DWORD FSIZE_t; -/* File system object structure (FATFS) */ +/* Filesystem object structure (FATFS) */ typedef struct { void *drv; // block device underlying this filesystem -#if _MULTI_PARTITION /* Multiple partition configuration */ +#if FF_MULTI_PARTITION /* Multiple partition configuration */ BYTE part; // Partition: 0:Auto detect, 1-4:Forced partition #endif - BYTE fs_type; /* File system type (0:N/A) */ + BYTE fs_type; /* Filesystem type (0:not mounted) */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ - WORD id; /* File system mount ID */ + WORD id; /* Volume mount ID */ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ WORD csize; /* Cluster size [sectors] */ -#if _MAX_SS != _MIN_SS +#if FF_MAX_SS != FF_MIN_SS WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ #endif -#if _USE_LFN != 0 +#if FF_USE_LFN WCHAR* lfnbuf; /* LFN working buffer */ #endif -#if _FS_EXFAT - BYTE* dirbuf; /* Directory entry block scratchpad buffer */ +#if FF_FS_EXFAT + BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ #endif -#if _FS_REENTRANT - _SYNC_t sobj; /* Identifier of sync object */ +#if FF_FS_REENTRANT + FF_SYNC_t sobj; /* Identifier of sync object */ #endif -#if !_FS_READONLY +#if !FF_FS_READONLY DWORD last_clst; /* Last allocated cluster */ DWORD free_clst; /* Number of free clusters */ #endif -#if _FS_RPATH != 0 +#if FF_FS_RPATH DWORD cdir; /* Current directory start cluster (0:root) */ -#if _FS_EXFAT +#if FF_FS_EXFAT DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ @@ -146,52 +158,56 @@ typedef struct { DWORD fatbase; /* FAT base sector */ DWORD dirbase; /* Root directory base sector/cluster */ DWORD database; /* Data base sector */ +#if FF_FS_EXFAT + DWORD bitbase; /* Allocation bitmap base sector */ +#endif DWORD winsect; /* Current sector appearing in the win[] */ - BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ + BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFS; -/* Object ID and allocation information (_FDID) */ +/* Object ID and allocation information (FFOBJID) */ typedef struct { - FATFS* fs; /* Pointer to the owner file system object */ - WORD id; /* Owner file system mount ID */ - BYTE attr; /* Object attribute */ - BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */ - DWORD sclust; /* Object start cluster (0:no cluster or root directory) */ - FSIZE_t objsize; /* Object size (valid when sclust != 0) */ -#if _FS_EXFAT - DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */ - DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ - DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ - DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */ + FATFS* fs; /* Pointer to the hosting volume of this object */ + WORD id; /* Hosting volume mount ID */ + BYTE attr; /* Object attribute */ + BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ + DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ + FSIZE_t objsize; /* Object size (valid when sclust != 0) */ +#if FF_FS_EXFAT + DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */ + DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */ + DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ + DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ + DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */ #endif -#if _FS_LOCK != 0 - UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ +#if FF_FS_LOCK + UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ #endif -} _FDID; +} FFOBJID; /* File object structure (FIL) */ typedef struct { - _FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ + FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ BYTE flag; /* File status flags */ BYTE err; /* Abort flag (error code) */ FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ - DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */ + DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ DWORD sect; /* Sector number appearing in buf[] (0:invalid) */ -#if !_FS_READONLY - DWORD dir_sect; /* Sector number containing the directory entry */ - BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */ +#if !FF_FS_READONLY + DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ + BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ #endif -#if _USE_FASTSEEK +#if FF_USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ #endif -#if !_FS_TINY - BYTE buf[_MAX_SS]; /* File private data read/write window */ +#if !FF_FS_TINY + BYTE buf[FF_MAX_SS]; /* File private data read/write window */ #endif } FIL; @@ -200,16 +216,16 @@ typedef struct { /* Directory object structure (FF_DIR) */ typedef struct { - _FDID obj; /* Object identifier */ + FFOBJID obj; /* Object identifier */ DWORD dptr; /* Current read/write offset */ DWORD clust; /* Current cluster */ - DWORD sect; /* Current sector */ + DWORD sect; /* Current sector (0:Read operation has terminated) */ BYTE* dir; /* Pointer to the directory item in the win[] */ BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ -#if _USE_LFN != 0 +#if FF_USE_LFN DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ #endif -#if _USE_FIND +#if FF_USE_FIND const TCHAR* pat; /* Pointer to the name matching pattern */ #endif } FF_DIR; @@ -223,11 +239,11 @@ typedef struct { WORD fdate; /* Modified date */ WORD ftime; /* Modified time */ BYTE fattrib; /* File attribute */ -#if _USE_LFN != 0 - TCHAR altname[13]; /* Altenative file name */ - TCHAR fname[_MAX_LFN + 1]; /* Primary file name */ +#if FF_USE_LFN + TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */ + TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */ #else - TCHAR fname[13]; /* File name */ + TCHAR fname[12 + 1]; /* File name */ #endif } FILINFO; @@ -254,7 +270,7 @@ typedef enum { FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ - FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ } FRESULT; @@ -292,6 +308,7 @@ FRESULT f_mount (FATFS* fs); /* Mount/Unm FRESULT f_umount (FATFS* fs); /* Unmount a logical drive */ FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ +FRESULT f_setcp (WORD cp); /* Set current code page */ #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) #define f_error(fp) ((fp)->err) @@ -299,6 +316,8 @@ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a #define f_size(fp) ((fp)->obj.objsize) #define f_rewind(fp) f_lseek((fp), 0) #define f_rewinddir(dp) f_readdir((dp), 0) +#define f_rmdir(path) f_unlink(path) +#define f_unmount(path) f_mount(0, path, 0) #ifndef EOF #define EOF (-1) @@ -311,26 +330,27 @@ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a /* Additional user defined functions */ /* RTC function */ -#if !_FS_READONLY && !_FS_NORTC +#if !FF_FS_READONLY && !FF_FS_NORTC DWORD get_fattime (void); #endif -/* Unicode support functions */ -#if _USE_LFN != 0 /* Unicode - OEM code conversion */ -WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ -WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ -#if _USE_LFN == 3 /* Memory functions */ +/* LFN support functions */ +#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */ +WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ +WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */ +DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */ +#endif +#if FF_USE_LFN == 3 /* Dynamic memory allocation */ void* ff_memalloc (UINT msize); /* Allocate memory block */ void ff_memfree (void* mblock); /* Free memory block */ #endif -#endif /* Sync functions */ -#if _FS_REENTRANT -int ff_cre_syncobj (FATFS *fatfs, _SYNC_t* sobj); /* Create a sync object */ -int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ -void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ -int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ +#if FF_FS_REENTRANT +int ff_cre_syncobj (FATFS *fatfs, FF_SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */ #endif @@ -377,4 +397,4 @@ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ } #endif -#endif /* _FATFS */ +#endif /* FF_DEFINED */ diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index d8485a293a..7072edf153 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -2,11 +2,11 @@ * This file is part of the MicroPython project, http://micropython.org/ * * Original file from: - * FatFs - FAT file system module configuration file R0.12a (C)ChaN, 2016 + * FatFs - FAT file system module configuration file R0.13c (C)ChaN, 2018 * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,73 +30,72 @@ #include "py/mpconfig.h" /*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module configuration file +/ FatFs Functional Configurations /---------------------------------------------------------------------------*/ -#define _FFCONF 68020 /* Revision ID */ +#define FFCONF_DEF 86604 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations /---------------------------------------------------------------------------*/ -#define _FS_READONLY 0 +#define FF_FS_READONLY 0 /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) / Read-only configuration removes writing API functions, f_write(), f_sync(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() / and optional writing functions as well. */ -#define _FS_MINIMIZE 0 +#define FF_FS_MINIMIZE 0 /* This option defines minimization level to remove some basic API functions. / -/ 0: All basic functions are enabled. +/ 0: Basic functions are fully enabled. / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() / are removed. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 3: f_lseek() function is removed in addition to 2. */ -#define _USE_STRFUNC 0 -/* This option switches string functions, f_gets(), f_putc(), f_puts() and -/ f_printf(). +#define FF_USE_STRFUNC 0 +/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). / / 0: Disable string functions. / 1: Enable without LF-CRLF conversion. / 2: Enable with LF-CRLF conversion. */ -#define _USE_FIND 0 +#define FF_USE_FIND 0 /* This option switches filtered directory read functions, f_findfirst() and / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ -#define _USE_MKFS 1 +#define FF_USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define _USE_FASTSEEK 1 +#define FF_USE_FASTSEEK 1 /* This option switches fast seek function. (0:Disable or 1:Enable) */ -#define _USE_EXPAND 0 +#define FF_USE_EXPAND 0 /* This option switches f_expand function. (0:Disable or 1:Enable) */ -#define _USE_CHMOD 1 +#define FF_USE_CHMOD 1 /* This option switches attribute manipulation functions, f_chmod() and f_utime(). -/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */ +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ #ifdef MICROPY_FATFS_USE_LABEL -#define _USE_LABEL (MICROPY_FATFS_USE_LABEL) +#define FF_USE_LABEL (MICROPY_FATFS_USE_LABEL) #else -#define _USE_LABEL 0 +#define FF_USE_LABEL 0 #endif /* This option switches volume label functions, f_getlabel() and f_setlabel(). / (0:Disable or 1:Enable) */ -#define _USE_FORWARD 0 +#define FF_USE_FORWARD 0 /* This option switches f_forward() function. (0:Disable or 1:Enable) */ @@ -105,14 +104,13 @@ /---------------------------------------------------------------------------*/ #ifdef MICROPY_FATFS_LFN_CODE_PAGE -#define _CODE_PAGE (MICROPY_FATFS_LFN_CODE_PAGE) +#define FF_CODE_PAGE MICROPY_FATFS_LFN_CODE_PAGE #else -#define _CODE_PAGE 1 +#define FF_CODE_PAGE 437 #endif /* This option specifies the OEM code page to be used on the target system. -/ Incorrect setting of the code page can cause a file open failure. +/ Incorrect code page setting can cause a file open failure. / -/ 1 - ASCII (No extended character. Non-LFN cfg. only) / 437 - U.S. / 720 - Arabic / 737 - Greek @@ -134,59 +132,77 @@ / 936 - Simplified Chinese (DBCS) / 949 - Korean (DBCS) / 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() */ #ifdef MICROPY_FATFS_ENABLE_LFN -#define _USE_LFN (MICROPY_FATFS_ENABLE_LFN) +#define FF_USE_LFN (MICROPY_FATFS_ENABLE_LFN) #else -#define _USE_LFN 0 +#define FF_USE_LFN 0 #endif #ifdef MICROPY_FATFS_MAX_LFN -#define _MAX_LFN (MICROPY_FATFS_MAX_LFN) +#define FF_MAX_LFN (MICROPY_FATFS_MAX_LFN) #else -#define _MAX_LFN 255 +#define FF_MAX_LFN 255 #endif -/* The _USE_LFN switches the support of long file name (LFN). +/* The FF_USE_LFN switches the support for LFN (long file name). / -/ 0: Disable support of LFN. _MAX_LFN has no effect. +/ 0: Disable LFN. FF_MAX_LFN has no effect. / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. / 2: Enable LFN with dynamic working buffer on the STACK. / 3: Enable LFN with dynamic working buffer on the HEAP. / -/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added -/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and -/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255. -/ It should be set 255 to support full featured LFN operations. +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN +/ specification. / When use stack for the working buffer, take care on stack overflow. When use heap / memory for the working buffer, memory management functions, ff_memalloc() and -/ ff_memfree(), must be added to the project. */ +/ ff_memfree() in ffsystem.c, need to be added to the project. */ -#define _LFN_UNICODE 0 -/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16) -/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. -/ This option also affects behavior of string I/O functions. */ - - -#define _STRF_ENCODE 3 -/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to -/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). +#define FF_LFN_UNICODE 0 +/* This option switches the character encoding on the API when LFN is enabled. / -/ 0: ANSI/OEM -/ 1: UTF-16LE -/ 2: UTF-16BE -/ 3: UTF-8 +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) / -/ This option has no effect when _LFN_UNICODE == 0. */ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + + +#define FF_STRF_ENCODE 3 +/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), +/ f_putc(), f_puts and f_printf() convert the character encoding in it. +/ This option selects assumption of character encoding ON THE FILE to be +/ read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ #ifdef MICROPY_FATFS_RPATH -#define _FS_RPATH (MICROPY_FATFS_RPATH) +#define FF_FS_RPATH (MICROPY_FATFS_RPATH) #else -#define _FS_RPATH 0 +#define FF_FS_RPATH 0 #endif -/* This option configures support of relative path. +/* This option configures support for relative path. / / 0: Disable relative path and remove related functions. / 1: Enable relative path. f_chdir() and f_chdrive() are available. @@ -198,53 +214,58 @@ / Drive/Volume Configurations /---------------------------------------------------------------------------*/ -#define _VOLUMES 1 -/* Number of volumes (logical drives) to be used. */ +#define FF_VOLUMES 1 +/* Number of volumes (logical drives) to be used. (1-10) */ -#define _STR_VOLUME_ID 0 -#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" -/* _STR_VOLUME_ID switches string support of volume ID. -/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive -/ number in the path name. _VOLUME_STRS defines the drive ID strings for each -/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for -/ the drive ID strings are: A-Z and 0-9. */ +#define FF_STR_VOLUME_ID 0 +#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table needs to be defined as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +*/ #ifdef MICROPY_FATFS_MULTI_PARTITION -#define _MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION) +#define FF_MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION) #else -#define _MULTI_PARTITION 0 +#define FF_MULTI_PARTITION 0 #endif -/* This option switches support of multi-partition on a physical drive. +/* This option switches support for multiple volumes on the physical drive. / By default (0), each logical drive number is bound to the same physical drive / number and only an FAT volume found on the physical drive will be mounted. -/ When multi-partition is enabled (1), each logical drive number can be bound to +/ When this function is enabled (1), each logical drive number can be bound to / arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() / funciton will be available. */ -#define _MIN_SS 512 +#define FF_MIN_SS 512 #ifdef MICROPY_FATFS_MAX_SS -#define _MAX_SS (MICROPY_FATFS_MAX_SS) +#define FF_MAX_SS (MICROPY_FATFS_MAX_SS) #else -#define _MAX_SS 512 +#define FF_MAX_SS 512 #endif -/* These options configure the range of sector size to be supported. (512, 1024, -/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and / harddisk. But a larger value may be required for on-board flash memory and some -/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured -/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the -/ disk_ioctl() function. */ +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ -#define _USE_TRIM 0 -/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable) +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) / To enable Trim function, also CTRL_TRIM command should be implemented to the / disk_ioctl() function. */ -#define _FS_NOFSINFO 0 +#define FF_FS_NOFSINFO 0 /* If you need to know correct free space on the FAT32 volume, set bit 0 of this / option, and f_getfree() function at first time after volume mount will force / a full FAT scan. Bit 1 controls the use of last allocated cluster number. @@ -261,44 +282,44 @@ / System Configurations /---------------------------------------------------------------------------*/ -#define _FS_TINY 1 +#define FF_FS_TINY 1 /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) -/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes. +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector -/ buffer in the file system object (FATFS) is used for the file data transfer. */ +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ #ifdef MICROPY_FATFS_EXFAT -#define _FS_EXFAT (MICROPY_FATFS_EXFAT) +#define FF_FS_EXFAT (MICROPY_FATFS_EXFAT) #else -#define _FS_EXFAT 0 +#define FF_FS_EXFAT 0 #endif -/* This option switches support of exFAT file system. (0:Disable or 1:Enable) -/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1) -/ Note that enabling exFAT discards C89 compatibility. */ +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ #ifdef MICROPY_FATFS_NORTC -#define _FS_NORTC (MICROPY_FATFS_NORTC) +#define FF_FS_NORTC (MICROPY_FATFS_NORTC) #else -#define _FS_NORTC 0 +#define FF_FS_NORTC 0 #endif -#define _NORTC_MON 1 -#define _NORTC_MDAY 1 -#define _NORTC_YEAR 2016 -/* The option _FS_NORTC switches timestamp functiton. If the system does not have -/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable -/ the timestamp function. All objects modified by FatFs will have a fixed timestamp -/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time. -/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be -/ added to the project to get current time form real-time clock. _NORTC_MON, -/ _NORTC_MDAY and _NORTC_YEAR have no effect. -/ These options have no effect at read-only configuration (_FS_READONLY = 1). */ +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2018 +/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable +/ the timestamp function. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ -#define _FS_LOCK 0 -/* The option _FS_LOCK switches file lock function to control duplicated file open -/ and illegal operation to open objects. This option must be 0 when _FS_READONLY +#define FF_FS_LOCK 0 +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY / is 1. / / 0: Disable file lock function. To avoid volume corruption, application program @@ -309,41 +330,40 @@ #ifdef MICROPY_FATFS_REENTRANT -#define _FS_REENTRANT (MICROPY_FATFS_REENTRANT) +#define FF_FS_REENTRANT (MICROPY_FATFS_REENTRANT) #else -#define _FS_REENTRANT 0 +#define FF_FS_REENTRANT 0 #endif // milliseconds #ifdef MICROPY_FATFS_TIMEOUT -#define _FS_TIMEOUT (MICROPY_FATFS_TIMEOUT) +#define FF_FS_TIMEOUT (MICROPY_FATFS_TIMEOUT) #else -#define _FS_TIMEOUT 1000 +#define FF_FS_TIMEOUT 1000 #endif #ifdef MICROPY_FATFS_SYNC_T -#define _SYNC_t MICROPY_FATFS_SYNC_T +#define FF_SYNC_t MICROPY_FATFS_SYNC_T #else -#define _SYNC_t HANDLE +#define FF_SYNC_t HANDLE #endif -/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs / module itself. Note that regardless of this option, file access to different / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() / and f_fdisk() function, are always not re-entrant. Only file/directory access / to the same volume is under control of this function. / -/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. +/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. / 1: Enable re-entrancy. Also user provided synchronization handlers, / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() / function, must be added to the project. Samples are available in / option/syscall.c. / -/ The _FS_TIMEOUT defines timeout period in unit of time tick. -/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, -/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be +/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. +/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / included somewhere in the scope of ff.h. */ -/* #include // O/S definitions */ /*--- End of configuration options ---*/ diff --git a/lib/oofatfs/option/ccsbcs.c b/lib/oofatfs/ffunicode.c similarity index 58% rename from lib/oofatfs/option/ccsbcs.c rename to lib/oofatfs/ffunicode.c index f0c7e90a5c..4153f9131c 100644 --- a/lib/oofatfs/option/ccsbcs.c +++ b/lib/oofatfs/ffunicode.c @@ -1,33 +1,46 @@ /*------------------------------------------------------------------------*/ -/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */ -/* (SBCS code pages) */ +/* Unicode handling functions for FatFs R0.13c */ /*------------------------------------------------------------------------*/ -/* 437 U.S. -/ 720 Arabic -/ 737 Greek -/ 771 KBL -/ 775 Baltic -/ 850 Latin 1 -/ 852 Latin 2 -/ 855 Cyrillic -/ 857 Turkish -/ 860 Portuguese -/ 861 Icelandic -/ 862 Hebrew -/ 863 Canadian French -/ 864 Arabic -/ 865 Nordic -/ 866 Russian -/ 869 Greek 2 +/* This module will occupy a huge memory in the .const section when the / +/ FatFs is configured for LFN with DBCS. If the system has any Unicode / +/ utilitiy for the code conversion, this module should be modified to use / +/ that function to avoid silly memory consumption. / +/-------------------------------------------------------------------------*/ +/* +/ Copyright (C) 2018, ChaN, all right reserved. +/ +/ FatFs module is an open source software. Redistribution and use of FatFs in +/ source and binary forms, with or without modification, are permitted provided +/ that the following condition is met: +/ +/ 1. Redistributions of source code must retain the above copyright notice, +/ this condition and the following disclaimer. +/ +/ This software is provided by the copyright holder and contributors "AS IS" +/ and any warranties related to this software are DISCLAIMED. +/ The copyright owner or contributors be NOT LIABLE for any damages caused +/ by use of this software. */ -#include "../ff.h" + +#include "ff.h" + +#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */ + +#if FF_DEFINED != 86604 /* Revision ID */ +#error Wrong include file (ff.h). +#endif + +#define MERGE2(a, b) a ## b +#define CVTBL(tbl, cp) MERGE2(tbl, cp) -#if _CODE_PAGE == 437 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ +/*------------------------------------------------------------------------*/ +/* Code Conversion Tables */ +/*------------------------------------------------------------------------*/ + +#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0 +static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -37,11 +50,9 @@ const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 720 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0 +static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */ 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, @@ -51,11 +62,9 @@ const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 737 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0 +static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, @@ -65,11 +74,9 @@ const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 771 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0 +static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, @@ -79,11 +86,9 @@ const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 775 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0 +static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */ 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, @@ -93,11 +98,9 @@ const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 850 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0 +static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -107,11 +110,9 @@ const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 852 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0 +static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, @@ -121,11 +122,9 @@ const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 855 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0 +static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */ 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, @@ -135,11 +134,9 @@ const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 857 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0 +static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -149,11 +146,9 @@ const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 860 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0 +static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -163,11 +158,9 @@ const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 861 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0 +static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -177,11 +170,9 @@ const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 862 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0 +static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, @@ -191,11 +182,9 @@ const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 863 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0 +static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0, 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, @@ -205,11 +194,9 @@ const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 864 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0 +static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */ 0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518, 0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000, 0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5, @@ -219,11 +206,9 @@ const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */ 0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1, 0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000 }; - -#elif _CODE_PAGE == 865 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0 +static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */ 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, @@ -233,11 +218,9 @@ const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */ 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 866 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0 +static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, @@ -247,11 +230,9 @@ const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 }; - -#elif _CODE_PAGE == 869 -#define _TBLDEF 1 -static -const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */ +#endif +#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0 +static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */ 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, 0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF, 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB, @@ -261,36 +242,32 @@ const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */ 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384, 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0 }; - -#endif - - -#if !_TBLDEF || !_USE_LFN -#error This file is not needed at current configuration. Remove from the project. #endif -WCHAR ff_convert ( /* Converted character, Returns zero on error */ - WCHAR chr, /* Character code to be converted */ - UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +/*------------------------------------------------------------------------*/ +/* OEM <==> Unicode conversions for static code page configuration */ +/* SBCS fixed code page */ +/*------------------------------------------------------------------------*/ + +#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900 +WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ + DWORD uni, /* UTF-16 encoded character to be converted */ + WORD cp /* Code page for the conversion */ ) { - WCHAR c; + WCHAR c = 0; + const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); - if (chr < 0x80) { /* ASCII */ - c = chr; + if (uni < 0x80) { /* ASCII? */ + c = (WCHAR)uni; - } else { - if (dir) { /* OEM code to Unicode */ - c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80]; - - } else { /* Unicode to OEM code */ - for (c = 0; c < 0x80; c++) { - if (chr == Tbl[c]) break; - } + } else { /* Non-ASCII */ + if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ + for (c = 0; c < 0x80 && uni != p[c]; c++) ; c = (c + 0x80) & 0xFF; } } @@ -298,56 +275,314 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */ return c; } - - -WCHAR ff_wtoupper ( /* Returns upper converted character */ - WCHAR chr /* Unicode character to be upper converted (BMP only) */ +WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ + WCHAR oem, /* OEM code to be converted */ + WORD cp /* Code page for the conversion */ ) { - /* Compressed upper conversion table */ - static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */ + WCHAR c = 0; + const WCHAR *p = CVTBL(uc, FF_CODE_PAGE); + + + if (oem < 0x80) { /* ASCII? */ + c = oem; + + } else { /* Extended char */ + if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */ + if (oem < 0x100) c = p[oem - 0x80]; + } + } + + return c; +} + +#endif + + + +/*------------------------------------------------------------------------*/ +/* OEM <==> Unicode conversions for static code page configuration */ +/* DBCS fixed code page */ +/*------------------------------------------------------------------------*/ + +#if FF_CODE_PAGE >= 900 +WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ + DWORD uni, /* UTF-16 encoded character to be converted */ + WORD cp /* Code page for the conversion */ +) +{ + const WCHAR *p; + WCHAR c = 0, uc; + UINT i = 0, n, li, hi; + + + if (uni < 0x80) { /* ASCII? */ + c = (WCHAR)uni; + + } else { /* Non-ASCII */ + if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */ + uc = (WCHAR)uni; + p = CVTBL(uni2oem, FF_CODE_PAGE); + hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1; + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (uc == p[i * 2]) break; + if (uc > p[i * 2]) { + li = i; + } else { + hi = i; + } + } + if (n != 0) c = p[i * 2 + 1]; + } + } + + return c; +} + + +WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ + WCHAR oem, /* OEM code to be converted */ + WORD cp /* Code page for the conversion */ +) +{ + const WCHAR *p; + WCHAR c = 0; + UINT i = 0, n, li, hi; + + + if (oem < 0x80) { /* ASCII? */ + c = oem; + + } else { /* Extended char */ + if (cp == FF_CODE_PAGE) { /* Is it valid code page? */ + p = CVTBL(oem2uni, FF_CODE_PAGE); + hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1; + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (oem == p[i * 2]) break; + if (oem > p[i * 2]) { + li = i; + } else { + hi = i; + } + } + if (n != 0) c = p[i * 2 + 1]; + } + } + + return c; +} +#endif + + + +/*------------------------------------------------------------------------*/ +/* OEM <==> Unicode conversions for dynamic code page configuration */ +/*------------------------------------------------------------------------*/ + +#if FF_CODE_PAGE == 0 + +static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0}; +static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0}; + + +WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */ + DWORD uni, /* UTF-16 encoded character to be converted */ + WORD cp /* Code page for the conversion */ +) +{ + const WCHAR *p; + WCHAR c = 0, uc; + UINT i, n, li, hi; + + + if (uni < 0x80) { /* ASCII? */ + c = (WCHAR)uni; + + } else { /* Non-ASCII */ + if (uni < 0x10000) { /* Is it in BMP? */ + uc = (WCHAR)uni; + p = 0; + if (cp < 900) { /* SBCS */ + for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */ + p = cp_table[i]; + if (p) { /* Is it valid code page ? */ + for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */ + c = (c + 0x80) & 0xFF; + } + } else { /* DBCS */ + switch (cp) { /* Get conversion table */ + case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break; + case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break; + case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break; + case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break; + } + if (p) { /* Is it valid code page? */ + li = 0; + for (n = 16; n; n--) { /* Find OEM code */ + i = li + (hi - li) / 2; + if (uc == p[i * 2]) break; + if (uc > p[i * 2]) { + li = i; + } else { + hi = i; + } + } + if (n != 0) c = p[i * 2 + 1]; + } + } + } + } + + return c; +} + + +WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */ + WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */ + WORD cp /* Code page for the conversion */ +) +{ + const WCHAR *p; + WCHAR c = 0; + UINT i, n, li, hi; + + + if (oem < 0x80) { /* ASCII? */ + c = oem; + + } else { /* Extended char */ + p = 0; + if (cp < 900) { /* SBCS */ + for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */ + p = cp_table[i]; + if (p) { /* Is it a valid CP ? */ + if (oem < 0x100) c = p[oem - 0x80]; + } + } else { /* DBCS */ + switch (cp) { + case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break; + case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break; + case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break; + case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break; + } + if (p) { + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (oem == p[i * 2]) break; + if (oem > p[i * 2]) { + li = i; + } else { + hi = i; + } + } + if (n != 0) c = p[i * 2 + 1]; + } + } + } + + return c; +} +#endif + + + +/*------------------------------------------------------------------------*/ +/* Unicode up-case conversion */ +/*------------------------------------------------------------------------*/ + +DWORD ff_wtoupper ( /* Returns up-converted code point */ + DWORD uni /* Unicode code point to be up-converted */ +) +{ + const WORD *p; + WORD uc, bc, nc, cmd; + static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */ /* Basic Latin */ 0x0061,0x031A, /* Latin-1 Supplement */ - 0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178, + 0x00E0,0x0317, + 0x00F8,0x0307, + 0x00FF,0x0001,0x0178, /* Latin Extended-A */ - 0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106, + 0x0100,0x0130, + 0x0132,0x0106, + 0x0139,0x0110, + 0x014A,0x012E, + 0x0179,0x0106, /* Latin Extended-B */ 0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA, - 0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128, - 0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A, + 0x01CD,0x0110, + 0x01DD,0x0001,0x018E, + 0x01DE,0x0112, + 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, + 0x01F8,0x0128, + 0x0222,0x0112, + 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, + 0x0246,0x010A, /* IPA Extensions */ 0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7, /* Greek, Coptic */ - 0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311, - 0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118, + 0x037B,0x0003,0x03FD,0x03FE,0x03FF, + 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, + 0x03B1,0x0311, + 0x03C2,0x0002,0x03A3,0x03A3, + 0x03C4,0x0308, + 0x03CC,0x0003,0x038C,0x038E,0x038F, + 0x03D8,0x0118, 0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA, /* Cyrillic */ - 0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144, + 0x0430,0x0320, + 0x0450,0x0710, + 0x0460,0x0122, + 0x048A,0x0136, + 0x04C1,0x010E, + 0x04CF,0x0001,0x04C0, + 0x04D0,0x0144, /* Armenian */ 0x0561,0x0426, - 0x0000 + 0x0000 /* EOT */ }; - static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */ + static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */ /* Phonetic Extensions */ 0x1D7D,0x0001,0x2C63, /* Latin Extended Additional */ - 0x1E00,0x0196, 0x1EA0,0x015A, + 0x1E00,0x0196, + 0x1EA0,0x015A, /* Greek Extended */ - 0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606, - 0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608, + 0x1F00,0x0608, + 0x1F10,0x0606, + 0x1F20,0x0608, + 0x1F30,0x0608, + 0x1F40,0x0606, + 0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, + 0x1F60,0x0608, 0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB, - 0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC, - 0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC, + 0x1F80,0x0608, + 0x1F90,0x0608, + 0x1FA0,0x0608, + 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC, + 0x1FCC,0x0001,0x1FC3, + 0x1FD0,0x0602, + 0x1FE0,0x0602, + 0x1FE5,0x0001,0x1FEC, + 0x1FF3,0x0001,0x1FFC, /* Letterlike Symbols */ 0x214E,0x0001,0x2132, /* Number forms */ - 0x2170,0x0210, 0x2184,0x0001,0x2183, + 0x2170,0x0210, + 0x2184,0x0001,0x2183, /* Enclosed Alphanumerics */ - 0x24D0,0x051A, 0x2C30,0x042F, + 0x24D0,0x051A, + 0x2C30,0x042F, /* Latin Extended-C */ - 0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102, + 0x2C60,0x0102, + 0x2C67,0x0106, 0x2C75,0x0102, /* Coptic */ 0x2C80,0x0164, /* Georgian Supplement */ @@ -355,33 +590,38 @@ WCHAR ff_wtoupper ( /* Returns upper converted character */ /* Full-width */ 0xFF41,0x031A, - 0x0000 + 0x0000 /* EOT */ }; - const WCHAR *p; - WCHAR bc, nc, cmd; - p = chr < 0x1000 ? cvt1 : cvt2; - for (;;) { - bc = *p++; /* Get block base */ - if (!bc || chr < bc) break; - nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */ - if (chr < bc + nc) { /* In the block? */ - switch (cmd) { - case 0: chr = p[chr - bc]; break; /* Table conversion */ - case 1: chr -= (chr - bc) & 1; break; /* Case pairs */ - case 2: chr -= 16; break; /* Shift -16 */ - case 3: chr -= 32; break; /* Shift -32 */ - case 4: chr -= 48; break; /* Shift -48 */ - case 5: chr -= 26; break; /* Shift -26 */ - case 6: chr += 8; break; /* Shift +8 */ - case 7: chr -= 80; break; /* Shift -80 */ - case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */ + if (uni < 0x10000) { /* Is it in BMP? */ + uc = (WORD)uni; + p = uc < 0x1000 ? cvt1 : cvt2; + for (;;) { + bc = *p++; /* Get the block base */ + if (bc == 0 || uc < bc) break; /* Not matched? */ + nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */ + if (uc < bc + nc) { /* In the block? */ + switch (cmd) { + case 0: uc = p[uc - bc]; break; /* Table conversion */ + case 1: uc -= (uc - bc) & 1; break; /* Case pairs */ + case 2: uc -= 16; break; /* Shift -16 */ + case 3: uc -= 32; break; /* Shift -32 */ + case 4: uc -= 48; break; /* Shift -48 */ + case 5: uc -= 26; break; /* Shift -26 */ + case 6: uc += 8; break; /* Shift +8 */ + case 7: uc -= 80; break; /* Shift -80 */ + case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */ + } + break; } - break; + if (cmd == 0) p += nc; /* Skip table if needed */ } - if (!cmd) p += nc; + uni = uc; } - return chr; + return uni; } + + +#endif /* #if FF_USE_LFN */ diff --git a/lib/oofatfs/option/unicode.c b/lib/oofatfs/option/unicode.c deleted file mode 100644 index e48d09c6b0..0000000000 --- a/lib/oofatfs/option/unicode.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "../ff.h" - -#if _USE_LFN != 0 - -#if _CODE_PAGE == 932 /* Japanese Shift_JIS */ -#include "cc932.c" -#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ -#include "cc936.c" -#elif _CODE_PAGE == 949 /* Korean */ -#include "cc949.c" -#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ -#include "cc950.c" -#else /* Single Byte Character-Set */ -#include "ccsbcs.c" -#endif - -#endif diff --git a/lib/utils/gchelper.h b/lib/utils/gchelper.h new file mode 100644 index 0000000000..7149b6a72e --- /dev/null +++ b/lib/utils/gchelper.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * + * 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 MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H +#define MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H + +#include + +uintptr_t gc_helper_get_sp(void); +uintptr_t gc_helper_get_regs_and_sp(uintptr_t *regs); + +#endif // MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H diff --git a/lib/utils/gchelper_m0.s b/lib/utils/gchelper_m0.s new file mode 100644 index 0000000000..db0d9738d1 --- /dev/null +++ b/lib/utils/gchelper_m0.s @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Damien P. George + * + * 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. + */ + + .syntax unified + .cpu cortex-m0 + .thumb + + .section .text + .align 2 + + .global gc_helper_get_regs_and_sp + .type gc_helper_get_regs_and_sp, %function + +@ uint gc_helper_get_regs_and_sp(r0=uint regs[10]) +gc_helper_get_regs_and_sp: + @ store registers into given array + str r4, [r0, #0] + str r5, [r0, #4] + str r6, [r0, #8] + str r7, [r0, #12] + mov r1, r8 + str r1, [r0, #16] + mov r1, r9 + str r1, [r0, #20] + mov r1, r10 + str r1, [r0, #24] + mov r1, r11 + str r1, [r0, #28] + mov r1, r12 + str r1, [r0, #32] + mov r1, r13 + str r1, [r0, #36] + + @ return the sp + mov r0, sp + bx lr + + .size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp diff --git a/lib/utils/gchelper_m3.s b/lib/utils/gchelper_m3.s new file mode 100644 index 0000000000..3aac0dedfd --- /dev/null +++ b/lib/utils/gchelper_m3.s @@ -0,0 +1,67 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2014 Damien P. George + * + * 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. + */ + + .syntax unified + .cpu cortex-m3 + .thumb + + .section .text + .align 2 + + .global gc_helper_get_sp + .type gc_helper_get_sp, %function + +@ uint gc_helper_get_sp(void) +gc_helper_get_sp: + @ return the sp + mov r0, sp + bx lr + + .size gc_helper_get_sp, .-gc_helper_get_sp + + + .global gc_helper_get_regs_and_sp + .type gc_helper_get_regs_and_sp, %function + +@ uint gc_helper_get_regs_and_sp(r0=uint regs[10]) +gc_helper_get_regs_and_sp: + @ store registers into given array + str r4, [r0], #4 + str r5, [r0], #4 + str r6, [r0], #4 + str r7, [r0], #4 + str r8, [r0], #4 + str r9, [r0], #4 + str r10, [r0], #4 + str r11, [r0], #4 + str r12, [r0], #4 + str r13, [r0], #4 + + @ return the sp + mov r0, sp + bx lr + + .size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c index 7410ac1e5d..372479f3a7 100644 --- a/lib/utils/interrupt_char.c +++ b/lib/utils/interrupt_char.c @@ -29,7 +29,7 @@ #if MICROPY_KBD_EXCEPTION -int mp_interrupt_char; +int mp_interrupt_char = -1; void mp_hal_set_interrupt_char(int c) { if (c != -1) { diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 9a105a42ca..e8c182e9bc 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -197,6 +197,7 @@ typedef struct _repl_t { // will be added later. // vstr_t line; bool cont_line; + bool paste_mode; } repl_t; repl_t repl; @@ -207,6 +208,7 @@ STATIC int pyexec_friendly_repl_process_char(int c); void pyexec_event_repl_init(void) { MP_STATE_VM(repl_line) = vstr_new(32); repl.cont_line = false; + repl.paste_mode = false; // no prompt before printing friendly REPL banner or entering raw REPL readline_init(MP_STATE_VM(repl_line), ""); if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { @@ -226,6 +228,7 @@ STATIC int pyexec_raw_repl_process_char(int c) { pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; vstr_reset(MP_STATE_VM(repl_line)); repl.cont_line = false; + repl.paste_mode = false; pyexec_friendly_repl_process_char(CHAR_CTRL_B); return 0; } else if (c == CHAR_CTRL_C) { @@ -263,6 +266,32 @@ reset: } STATIC int pyexec_friendly_repl_process_char(int c) { + if (repl.paste_mode) { + if (c == CHAR_CTRL_C) { + // cancel everything + mp_hal_stdout_tx_str("\r\n"); + goto input_restart; + } else if (c == CHAR_CTRL_D) { + // end of input + mp_hal_stdout_tx_str("\r\n"); + int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR); + if (ret & PYEXEC_FORCED_EXIT) { + return ret; + } + goto input_restart; + } else { + // add char to buffer and echo + vstr_add_byte(MP_STATE_VM(repl_line), c); + if (c == '\r') { + mp_hal_stdout_tx_str("\r\n=== "); + } else { + char buf[1] = {c}; + mp_hal_stdout_tx_strn(buf, 1); + } + return 0; + } + } + int ret = readline_process_char(c); if (!repl.cont_line) { @@ -289,6 +318,12 @@ STATIC int pyexec_friendly_repl_process_char(int c) { mp_hal_stdout_tx_str("\r\n"); vstr_clear(MP_STATE_VM(repl_line)); return PYEXEC_FORCED_EXIT; + } else if (ret == CHAR_CTRL_E) { + // paste mode + mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== "); + vstr_reset(MP_STATE_VM(repl_line)); + repl.paste_mode = true; + return 0; } if (ret < 0) { @@ -335,6 +370,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) { input_restart: vstr_reset(MP_STATE_VM(repl_line)); repl.cont_line = false; + repl.paste_mode = false; readline_init(MP_STATE_VM(repl_line), ">>> "); return 0; } @@ -450,7 +486,7 @@ friendly_repl_reset: // do the user a favor and reenable interrupts. if (query_irq() == IRQ_STATE_DISABLED) { enable_irq(IRQ_STATE_ENABLED); - mp_hal_stdout_tx_str("PYB: enabling IRQs\r\n"); + mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n"); } } #endif @@ -541,20 +577,32 @@ int pyexec_file(const char *filename, pyexec_result_t *result) { return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME, result); } +int pyexec_file_if_exists(const char *filename, pyexec_result_t *result) { + #if MICROPY_MODULE_FROZEN + if (mp_frozen_stat(filename) == MP_IMPORT_STAT_FILE) { + return pyexec_frozen_module(filename, result); + } + #endif + if (mp_import_stat(filename) != MP_IMPORT_STAT_FILE) { + return 1; // success (no file is the same as an empty file executing without fail) + } + return pyexec_file(filename, result); +} + #if MICROPY_MODULE_FROZEN -int pyexec_frozen_module(const char *name) { +int pyexec_frozen_module(const char *name, pyexec_result_t *result) { void *frozen_data; int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data); switch (frozen_type) { #if MICROPY_MODULE_FROZEN_STR case MP_FROZEN_STR: - return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, NULL); + return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, result); #endif #if MICROPY_MODULE_FROZEN_MPY case MP_FROZEN_MPY: - return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, NULL); + return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, result); #endif default: diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h index bde2960c29..9baef2b9fe 100644 --- a/lib/utils/pyexec.h +++ b/lib/utils/pyexec.h @@ -54,7 +54,8 @@ extern int pyexec_system_exit; int pyexec_raw_repl(void); int pyexec_friendly_repl(void); int pyexec_file(const char *filename, pyexec_result_t *result); -int pyexec_frozen_module(const char *name); +int pyexec_file_if_exists(const char *filename, pyexec_result_t *result); +int pyexec_frozen_module(const char *name, pyexec_result_t *result); void pyexec_event_repl_init(void); int pyexec_event_repl_process_char(int c); extern uint8_t pyexec_repl_active; diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 7b019191e3..d05380fc28 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -733,14 +733,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2560,10 +2552,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3071,6 +3059,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3190,6 +3186,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "" @@ -3199,10 +3199,6 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3233,10 +3229,6 @@ msgstr "" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "" - #: py/compile.c msgid "invalid micropython decorator" msgstr "" diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 200080bbe5..6e4d7ef316 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -13,6 +13,8 @@ override undefine MICROPY_FORCE_32BIT override undefine CROSS_COMPILE override undefine FROZEN_DIR override undefine FROZEN_MPY_DIR +override undefine USER_C_MODULES +override undefine SRC_MOD override undefine BUILD override undefine PROG endif diff --git a/mpy-cross/gccollect.c b/mpy-cross/gccollect.c index 9a975af8db..117a903869 100644 --- a/mpy-cross/gccollect.c +++ b/mpy-cross/gccollect.c @@ -122,9 +122,6 @@ void gc_collect(void) { // GC stack (and regs because we captured them) void **regs_ptr = (void **)(void *)®s; gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)®s) / sizeof(mp_uint_t)); - #if MICROPY_EMIT_NATIVE - mp_unix_mark_exec(); - #endif gc_collect_end(); } diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 6e99ea2408..786f0635e3 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -13,6 +13,7 @@ #include "py/runtime.h" #include "py/gc.h" #include "py/stackctrl.h" +#include "genhdr/mpversion.h" #ifdef _WIN32 #include "fmode.h" #endif @@ -46,9 +47,7 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha } #if MICROPY_PY___FILE__ - if (input_kind == MP_PARSE_FILE_INPUT) { - mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); - } + mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); @@ -77,20 +76,22 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha STATIC int usage(char **argv) { printf( - "usage: %s [] [-X ] \n" - "Options:\n" - "-o : output file for compiled bytecode (defaults to input with .mpy extension)\n" - "-s : source filename to embed in the compiled bytecode (defaults to input file)\n" - "-v : verbose (trace various operations); can be multiple\n" - "-O[N] : apply bytecode optimizations of level N\n" - "\n" - "Target specific options:\n" - "-msmall-int-bits=number : set the maximum bits used to encode a small-int\n" - "-mno-unicode : don't support unicode in compiled strings\n" - "-mcache-lookup-bc : cache map lookups in the bytecode\n" - "\n" - "Implementation specific options:\n", argv[0] - ); +"usage: %s [] [-X ] \n" +"Options:\n" +"--version : show version information\n" +"-o : output file for compiled bytecode (defaults to input with .mpy extension)\n" +"-s : source filename to embed in the compiled bytecode (defaults to input file)\n" +"-v : verbose (trace various operations); can be multiple\n" +"-O[N] : apply bytecode optimizations of level N\n" +"\n" +"Target specific options:\n" +"-msmall-int-bits=number : set the maximum bits used to encode a small-int\n" +"-mno-unicode : don't support unicode in compiled strings\n" +"-mcache-lookup-bc : cache map lookups in the bytecode\n" +"-march= : set architecture for native emitter; x86, x64, armv6, armv7m, xtensa\n" +"\n" +"Implementation specific options:\n", argv[0] +); int impl_opts_cnt = 0; printf( " emit={bytecode,native,viper} -- set the default code emitter\n" @@ -172,6 +173,15 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_dynamic_compiler.small_int_bits = 31; mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0; mp_dynamic_compiler.py_builtins_str_unicode = 1; + #if defined(__i386__) + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86; + #elif defined(__x86_64__) + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X64; + #elif defined(__arm__) && !defined(__thumb2__) + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6; + #else + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_NONE; + #endif const char *input_file = NULL; const char *output_file = NULL; @@ -182,6 +192,10 @@ MP_NOINLINE int main_(int argc, char **argv) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-X") == 0) { a += 1; + } else if (strcmp(argv[a], "--version") == 0) { + printf("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE + "; mpy-cross emitting mpy v" MP_STRINGIFY(MPY_VERSION) "\n"); + return 0; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; } else if (strncmp(argv[a], "-O", 2) == 0) { @@ -220,6 +234,21 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_dynamic_compiler.py_builtins_str_unicode = 0; } else if (strcmp(argv[a], "-municode") == 0) { mp_dynamic_compiler.py_builtins_str_unicode = 1; + } else if (strncmp(argv[a], "-march=", sizeof("-march=") - 1) == 0) { + const char *arch = argv[a] + sizeof("-march=") - 1; + if (strcmp(arch, "x86") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86; + } else if (strcmp(arch, "x64") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X64; + } else if (strcmp(arch, "armv6") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6; + } else if (strcmp(arch, "armv7m") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV7M; + } else if (strcmp(arch, "xtensa") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_XTENSA; + } else { + return usage(argv); + } } else { return usage(argv); } diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index 74bb774afc..fc94c27c38 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -9,13 +9,15 @@ #define MICROPY_PERSISTENT_CODE_LOAD (0) #define MICROPY_PERSISTENT_CODE_SAVE (1) -#define MICROPY_EMIT_X64 (0) -#define MICROPY_EMIT_X86 (0) -#define MICROPY_EMIT_THUMB (0) -#define MICROPY_EMIT_INLINE_THUMB (0) -#define MICROPY_EMIT_INLINE_THUMB_ARMV7M (0) -#define MICROPY_EMIT_INLINE_THUMB_FLOAT (0) -#define MICROPY_EMIT_ARM (0) +#define MICROPY_EMIT_X64 (1) +#define MICROPY_EMIT_X86 (1) +#define MICROPY_EMIT_THUMB (1) +#define MICROPY_EMIT_INLINE_THUMB (1) +#define MICROPY_EMIT_INLINE_THUMB_ARMV7M (1) +#define MICROPY_EMIT_INLINE_THUMB_FLOAT (1) +#define MICROPY_EMIT_ARM (1) +#define MICROPY_EMIT_XTENSA (1) +#define MICROPY_EMIT_INLINE_XTENSA (1) #define MICROPY_DYNAMIC_COMPILER (1) #define MICROPY_COMP_CONST_FOLDING (1) @@ -134,10 +136,6 @@ typedef long mp_off_t; #define MP_PLAT_PRINT_STRN(str, len) (void)0 -#ifndef MP_NOINLINE -#define MP_NOINLINE __attribute__((noinline)) -#endif - // We need to provide a declaration/definition of alloca() #ifdef __FreeBSD__ #include diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 48724af0c8..574d115260 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -302,18 +302,7 @@ SRC_C += \ eic_handler.c \ fatfs_port.c \ freetouch/adafruit_ptc.c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ mphalport.c \ peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/adc.c \ peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/cache.c \ @@ -331,7 +320,6 @@ SRC_C += \ peripherals/samd/sercom.c \ peripherals/samd/timers.c \ reset.c \ - supervisor/shared/memory.c \ timer_handler.c \ ifeq ($(CIRCUITPY_SDIOIO),1) @@ -390,6 +378,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index dd012cb487..5921bd2f1a 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -12,28 +12,16 @@ LONGINT_IMPL = MPZ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_COUNTIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_MSGPACK = 0 # supersized, not ultra-supersized CIRCUITPY_VECTORIO = 0 -CIRCUITPY_BUSDEVICE = 0 -CFLAGS_INLINE_LIMIT = 60 +CFLAGS_INLINE_LIMIT = 35 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), ja) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 8c51315429..e97f9884da 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -17,6 +17,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_COUNTIO = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index 467c6af47a..106eef89cf 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -19,6 +19,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_RTC = 0 # too itsy bitsy for all of displayio CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index 964d335537..01e6094cdf 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -17,6 +17,7 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_VECTORIO = 0 CIRCUITPY_BUSDEVICE = 0 +MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk index 99dddfa892..d500b81112 100644 --- a/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew_m4/mpconfigboard.mk @@ -21,6 +21,7 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_PIXELBUF = 0 CIRCUITPY_PS2IO = 0 +CIRCUITPY_PULSEIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_SAMD = 0 diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk index a88bea91de..1ffe1669e7 100644 --- a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk @@ -18,6 +18,7 @@ CIRCUITPY_COUNTIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_MSGPACK = 0 +CIRCUITPY_VECTORIO = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/serpente/mpconfigboard.mk b/ports/atmel-samd/boards/serpente/mpconfigboard.mk index 32ba32f386..422baf46ad 100644 --- a/ports/atmel-samd/boards/serpente/mpconfigboard.mk +++ b/ports/atmel-samd/boards/serpente/mpconfigboard.mk @@ -12,9 +12,10 @@ LONGINT_IMPL = NONE CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_GAMEPAD = 0 -CIRCUITPY_BUSDEVICE = 0 +CIRCUITPY_MSGPACK = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk index 197dea6fe2..aca557cec6 100755 --- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk @@ -13,8 +13,9 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BITMAPTOOLS = 0 -CIRCUITPY_VECTORIO = 0 CIRCUITPY_BUSDEVICE = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_VECTORIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk index fb46e99dae..0f9b8a3c18 100644 --- a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk +++ b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk @@ -19,6 +19,7 @@ CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_VECTORIO = 0 CIRCUITPY_BUSDEVICE = 0 +MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk index 8c9dc71699..e91c94e56d 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -20,18 +20,8 @@ CIRCUITPY_I2CPERIPHERAL = 0 MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 + +CFLAGS_INLINE_LIMIT = 35 CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), ja) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile index 15eb5e64c7..1fea295194 100644 --- a/ports/cxd56/Makefile +++ b/ports/cxd56/Makefile @@ -168,18 +168,6 @@ SRC_C += \ mphalport.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ - lib/utils/stdout_helpers.c \ - lib/utils/pyexec.c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/timeutils/timeutils.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/utils/interrupt_char.c \ - lib/utils/sys_stdio_mphal.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/buffer_helper.c \ - supervisor/shared/memory.c \ lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c \ OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) @@ -189,6 +177,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) # List of sources for qstr extraction diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index b4ff0612b3..22a2bdd3d7 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -182,24 +182,12 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ modules/$(CIRCUITPY_MODULE).c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ lib/netutils/netutils.c \ peripherals/timer.c \ peripherals/touch.c \ peripherals/pcnt.c \ peripherals/pins.c \ - peripherals/rmt.c \ - supervisor/shared/memory.c + peripherals/rmt.c ifneq ($(USB),FALSE) SRC_C += lib/tinyusb/src/portable/espressif/esp32s2/dcd_esp32s2.c @@ -227,6 +215,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index 9ccb5700cb..872c0f7124 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -104,7 +104,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al // First, check to see if we match any given alarms. uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status; for (size_t i = 0; i < n_alarms; i++) { - if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) { + if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) { continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); @@ -179,7 +179,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob for (size_t i = 0; i < n_alarms; i++) { // TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms. - if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) { + if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) { continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); diff --git a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c index 93e4f18091..848ce32a93 100644 --- a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c +++ b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c @@ -45,7 +45,7 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { // First, check to see if we match for (size_t i = 0; i < n_alarms; i++) { - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { + if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) { return alarms[i]; } } @@ -82,7 +82,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL; for (size_t i = 0; i < n_alarms; i++) { - if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { + if (!mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) { continue; } if (timealarm_set) { diff --git a/ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c b/ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c index 8c139afaf3..15e3c736a8 100644 --- a/ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c @@ -45,7 +45,7 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) { // First, check to see if we match any given alarms. for (size_t i = 0; i < n_alarms; i++) { - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { + if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) { return alarms[i]; } } @@ -88,7 +88,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar alarm_touch_touchalarm_obj_t *touch_alarm = MP_OBJ_NULL; for (size_t i = 0; i < n_alarms; i++) { - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) { + if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) { if (deep_sleep && touch_alarm_set) { mp_raise_ValueError(translate("Only one TouchAlarm can be set in deep sleep.")); } diff --git a/ports/esp32s2/common-hal/wifi/__init__.c b/ports/esp32s2/common-hal/wifi/__init__.c index 3ec4ebc24d..720b49c009 100644 --- a/ports/esp32s2/common-hal/wifi/__init__.c +++ b/ports/esp32s2/common-hal/wifi/__init__.c @@ -158,7 +158,7 @@ void wifi_reset(void) { } void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address) { - if (!MP_OBJ_IS_TYPE(ip_address, &ipaddress_ipv4address_type)) { + if (!mp_obj_is_type(ip_address, &ipaddress_ipv4address_type)) { mp_raise_ValueError(translate("Only IPv4 addresses supported")); } mp_obj_t packed = common_hal_ipaddress_ipv4address_get_packed(ip_address); diff --git a/ports/litex/Makefile b/ports/litex/Makefile index f384f24577..373a6465b7 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -122,19 +122,7 @@ SRC_C += \ fatfs_port.c \ mphalport.c \ boards/$(BOARD)/board.c \ - boards/$(BOARD)/pins.c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ - supervisor/shared/memory.c + boards/$(BOARD)/pins.c ifneq ($(USB),FALSE) SRC_C += lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c @@ -163,6 +151,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index 33507086ea..fcbb3ecf31 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -154,24 +154,13 @@ SRC_C += \ boards/$(BOARD)/flash_config.c \ boards/$(BOARD)/pins.c \ fatfs_port.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c \ mphalport.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/periph.c \ peripherals/mimxrt10xx/$(CHIP_FAMILY)/pins.c \ reset.c \ - supervisor/flexspi_nor_flash_ops.c \ - supervisor/shared/memory.c + supervisor/flexspi_nor_flash_ops.c ifeq ($(CIRCUITPY_NETWORK),1) @@ -224,6 +213,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 278625e92d..13dd955c20 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -156,17 +156,6 @@ SRC_C += \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ bluetooth/ble_drv.c \ common-hal/_bleio/bonding.c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ nrfx/mdk/system_$(MCU_SUB_VARIANT).c \ peripherals/nrf/cache.c \ peripherals/nrf/clocks.c \ @@ -174,8 +163,7 @@ SRC_C += \ peripherals/nrf/$(MCU_CHIP)/power.c \ peripherals/nrf/nvm.c \ peripherals/nrf/timers.c \ - sd_mutex.c \ - supervisor/shared/memory.c + sd_mutex.c # USB source files for nrf52840 ifeq ($(MCU_SUB_VARIANT),nrf52840) @@ -235,6 +223,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 005ec8af2f..f3fdb19f4e 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -27,6 +27,7 @@ CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_SYNTHIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 CIRCUITPY_USB_CDC = 0 diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c index 7e0b7a10e9..cdc6fd3d68 100644 --- a/ports/nrf/common-hal/_bleio/Connection.c +++ b/ports/nrf/common-hal/_bleio/Connection.c @@ -645,7 +645,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); mp_obj_t uuid_obj; while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist")); } bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 2a054516be..9333f5d1f4 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -199,21 +199,9 @@ SRC_C += \ peripherals/pins.c \ extmod/crypto-algorithms/sha256.c \ fatfs_port.c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \ lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ mphalport.c \ - supervisor/shared/memory.c \ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ @@ -248,6 +236,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index fe36423256..342a223693 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -599,7 +599,7 @@ const mp_obj_type_t rp2pio_statemachine_type = { }; rp2pio_statemachine_obj_t *validate_obj_is_statemachine(mp_obj_t obj) { - if (!MP_OBJ_IS_TYPE(obj, &rp2pio_statemachine_type)) { + if (!mp_obj_is_type(obj, &rp2pio_statemachine_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), rp2pio_statemachine_type.name); } return MP_OBJ_TO_PTR(obj); diff --git a/ports/stm/Makefile b/ports/stm/Makefile index e09fe736cc..1b0e981997 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -117,7 +117,7 @@ MCU_FLAGS_H7 = -mcpu=cortex-m7 CFLAGS += $(MCU_FLAGS_$(MCU_SERIES)) # Select HAL file for distribution via mpconfigport -CFLAGS += -DSTM32_HAL_H='' +CFLAGS += -DSTM32_HAL_H="" CFLAGS += -DSTM32_SERIES_LOWER='"stm32$(MCU_SERIES_LOWER)"' @@ -224,19 +224,7 @@ SRC_C += \ peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/pins.c \ peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/gpio.c \ peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/periph.c \ - packages/$(MCU_PACKAGE).c \ - lib/libc/string0.c \ - lib/mp-readline/readline.c \ - lib/oofatfs/ff.c \ - lib/oofatfs/option/ccsbcs.c \ - lib/timeutils/timeutils.c \ - lib/utils/buffer_helper.c \ - lib/utils/context_manager_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/utils/stdout_helpers.c \ - lib/utils/sys_stdio_mphal.c \ - supervisor/shared/memory.c + packages/$(MCU_PACKAGE).c ifneq ($(USB),FALSE) SRC_C += lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c @@ -267,6 +255,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) diff --git a/ports/unix/Makefile b/ports/unix/Makefile index bb900a29b3..555e76a6aa 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -166,7 +166,7 @@ LIB_SRC_C = $(addprefix lib/,\ # FatFS VFS support LIB_SRC_C += $(addprefix lib/,\ oofatfs/ff.c \ - oofatfs/option/unicode.c \ + oofatfs/ffunicode.c \ ) OBJ = $(PY_O) @@ -259,10 +259,11 @@ coverage: coverage_test: coverage $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 -d thread - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --emit native - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --via-mpy -d basics float + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float micropython + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy --emit native -d basics float micropython cat $(TOP)/tests/basics/0prelim.py | ./micropython_coverage | grep -q 'abc' gcov -o build-coverage/py $(TOP)/py/*.c gcov -o build-coverage/extmod $(TOP)/extmod/*.c diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 2d377bc8fe..e498d165cc 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -163,6 +163,7 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "%x\n", 0x80000000); // should print unsigned mp_printf(&mp_plat_print, "%X\n", 0x80000000); // should print unsigned mp_printf(&mp_plat_print, "abc\n%"); // string ends in middle of format specifier + mp_printf(&mp_plat_print, "%%\n"); // literal % character } // GC @@ -252,7 +253,7 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# str\n"); // intern string - mp_printf(&mp_plat_print, "%d\n", MP_OBJ_IS_QSTR(mp_obj_str_intern(mp_obj_new_str("intern me", 9)))); + mp_printf(&mp_plat_print, "%d\n", mp_obj_is_qstr(mp_obj_str_intern(mp_obj_new_str("intern me", 9)))); } // bytearray diff --git a/ports/unix/file.c b/ports/unix/file.c index 745593c81c..d0d0b106a7 100644 --- a/ports/unix/file.c +++ b/ports/unix/file.c @@ -193,7 +193,7 @@ STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) { mp_obj_t fid = args[0].u_obj; - if (MP_OBJ_IS_SMALL_INT(fid)) { + if (mp_obj_is_small_int(fid)) { o->fd = MP_OBJ_SMALL_INT_VALUE(fid); return MP_OBJ_FROM_PTR(o); } diff --git a/ports/unix/gccollect.c b/ports/unix/gccollect.c index 45ad1e0430..efe6205a68 100644 --- a/ports/unix/gccollect.c +++ b/ports/unix/gccollect.c @@ -149,9 +149,14 @@ STATIC void gc_helper_get_regs(regs_t arr) { #endif // MICROPY_GCREGS_SETJMP // this function is used by mpthreadport.c -void gc_collect_regs_and_stack(void); +MP_NOINLINE void gc_collect_regs_and_stack(void); -void gc_collect_regs_and_stack(void) { +// Explicitly mark this as noinline to make sure the regs variable +// is effectively at the top of the stack: otherwise, in builds where +// LTO is enabled and a lot of inlining takes place we risk a stack +// layout where regs is lower on the stack than pointers which have +// just been allocated but not yet marked, and get incorrectly sweeped. +MP_NOINLINE void gc_collect_regs_and_stack(void) { regs_t regs; gc_helper_get_regs(regs); // GC stack (and regs because we captured them) diff --git a/ports/unix/main.c b/ports/unix/main.c index 715ad56589..cc225e7d6a 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -653,6 +654,10 @@ MP_NOINLINE int main_(int argc, char **argv) { } #endif + #if MICROPY_PY_THREAD + mp_thread_deinit(); + #endif + #if defined(MICROPY_UNIX_COVERAGE) gc_sweep_all(); #endif diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 894702330f..9e953ca81d 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -141,7 +141,7 @@ STATIC ffi_type *char2ffi_type(char c) { } STATIC ffi_type *get_ffi_type(mp_obj_t o_in) { - if (MP_OBJ_IS_STR(o_in)) { + if (mp_obj_is_str(o_in)) { const char *s = mp_obj_str_get_str(o_in); ffi_type *t = char2ffi_type(*s); if (t != NULL) { @@ -365,6 +365,7 @@ STATIC void ffifunc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki } STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + (void)n_kw; mp_obj_ffifunc_t *self = MP_OBJ_TO_PTR(self_in); assert(n_kw == 0); assert(n_args == self->cif.nargs); @@ -386,9 +387,9 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const #endif } else if (a == mp_const_none) { values[i] = 0; - } else if (MP_OBJ_IS_INT(a)) { + } else if (mp_obj_is_int(a)) { values[i] = mp_obj_int_get_truncated(a); - } else if (MP_OBJ_IS_STR(a)) { + } else if (mp_obj_is_str(a)) { const char *s = mp_obj_str_get_str(a); values[i] = (ffi_arg)(intptr_t)s; } else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) { @@ -399,7 +400,7 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const goto error; } values[i] = (ffi_arg)(intptr_t)bufinfo.buf; - } else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) { + } else if (mp_obj_is_type(a, &fficallback_type)) { mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a); values[i] = (ffi_arg)(intptr_t)p->func; } else { diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 3ff5c61f50..4a9fdb4a58 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -658,12 +658,12 @@ STATIC mp_obj_t mod_jni_array(mp_obj_t type_in, mp_obj_t size_in) { mp_int_t size = mp_obj_get_int(size_in); jobject res = NULL; - if (MP_OBJ_IS_TYPE(type_in, &jclass_type)) { + if (mp_obj_is_type(type_in, &jclass_type)) { mp_obj_jclass_t *jcls = MP_OBJ_TO_PTR(type_in); res = JJ(NewObjectArray, size, jcls->cls, NULL); - } else if (MP_OBJ_IS_STR(type_in)) { + } else if (mp_obj_is_str(type_in)) { const char *type = mp_obj_str_get_str(type_in); switch (*type) { case 'Z': diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c index af3a9d88fe..0871d84d02 100644 --- a/ports/unix/modmachine.c +++ b/ports/unix/modmachine.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,10 +60,11 @@ uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) { static uintptr_t last_base = (uintptr_t)-1; static uintptr_t map_page; if (!fd) { - fd = open("/dev/mem", O_RDWR | O_SYNC); - if (fd == -1) { + int _fd = open("/dev/mem", O_RDWR | O_SYNC); + if (_fd == -1) { mp_raise_OSError(errno); } + fd = _fd; } uintptr_t cur_base = addr & ~MICROPY_PAGE_MASK; diff --git a/ports/unix/modos.c b/ports/unix/modos.c index 43d7590518..6a6b8e5e61 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/modtermios.c b/ports/unix/modtermios.c index bd723085de..0355a8ce73 100644 --- a/ports/unix/modtermios.c +++ b/ports/unix/modtermios.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2014-2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -77,7 +77,7 @@ STATIC mp_obj_t mod_termios_tcsetattr(mp_obj_t fd_in, mp_obj_t when_in, mp_obj_t when = TCSANOW; } - assert(MP_OBJ_IS_TYPE(attrs_in, &mp_type_list)); + assert(mp_obj_is_type(attrs_in, &mp_type_list)); mp_obj_list_t *attrs = MP_OBJ_TO_PTR(attrs_in); term.c_iflag = mp_obj_get_int(attrs->items[0]); diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index 94ae8d2f1e..6ea85359da 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index d4c6a8e179..299fa20039 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -66,7 +66,7 @@ typedef struct _mp_obj_poll_t { } mp_obj_poll_t; STATIC int get_fd(mp_obj_t fdlike) { - if (MP_OBJ_IS_OBJ(fdlike)) { + if (mp_obj_is_obj(fdlike)) { const mp_stream_p_t *stream_p = mp_get_stream_raise(fdlike, MP_STREAM_OP_IOCTL); int err; mp_uint_t res = stream_p->ioctl(fdlike, MP_STREAM_GET_FILENO, 0, &err); @@ -80,7 +80,7 @@ STATIC int get_fd(mp_obj_t fdlike) { /// \method register(obj[, eventmask]) STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) { mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]); - bool is_fd = MP_OBJ_IS_INT(args[1]); + bool is_fd = mp_obj_is_int(args[1]); int fd = get_fd(args[1]); mp_uint_t flags; diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 24778b6b55..984c6d914d 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -162,7 +162,12 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ); int r = connect(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len); - RAISE_ERRNO(r, errno); + int err = errno; + if (r == -1 && self->blocking && err == EINPROGRESS) { + // EINPROGRESS on a blocking socket means the operation timed out + err = MP_ETIMEDOUT; + } + RAISE_ERRNO(r, err); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); @@ -192,7 +197,12 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) { byte addr[32]; socklen_t addr_len = sizeof(addr); int fd = accept(self->fd, (struct sockaddr *)&addr, &addr_len); - RAISE_ERRNO(fd, errno); + int err = errno; + if (fd == -1 && self->blocking && err == EAGAIN) { + // EAGAIN on a blocking socket means the operation timed out + err = MP_ETIMEDOUT; + } + RAISE_ERRNO(fd, err); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); t->items[0] = MP_OBJ_FROM_PTR(socket_new(fd)); @@ -301,7 +311,7 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) { const void *optval; socklen_t optlen; int val; - if (MP_OBJ_IS_INT(args[3])) { + if (mp_obj_is_int(args[3])) { val = mp_obj_int_get_truncated(args[3]); optval = &val; optlen = sizeof(val); @@ -339,10 +349,9 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { struct timeval tv = {0,}; bool new_blocking = true; - if (timeout_in == mp_const_none) { - setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, NULL, 0); - setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, NULL, 0); - } else { + // Timeout of None means no timeout, which in POSIX is signified with 0 timeout, + // and that's how 'tv' is initialized above + if (timeout_in != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t val = mp_obj_get_float(timeout_in); double ipart; @@ -356,14 +365,17 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { // for Python API it means non-blocking. if (tv.tv_sec == 0 && tv.tv_usec == 0) { new_blocking = false; - } else { - setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, - &tv, sizeof(struct timeval)); - setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, - &tv, sizeof(struct timeval)); } } + if (new_blocking) { + int r; + r = setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)); + RAISE_ERRNO(r, errno); + r = setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval)); + RAISE_ERRNO(r, errno); + } + if (self->blocking != new_blocking) { socket_setblocking(self_in, mp_obj_new_bool(new_blocking)); } @@ -393,13 +405,13 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, con int proto = 0; if (n_args > 0) { - assert(MP_OBJ_IS_SMALL_INT(args[0])); + assert(mp_obj_is_small_int(args[0])); family = MP_OBJ_SMALL_INT_VALUE(args[0]); if (n_args > 1) { - assert(MP_OBJ_IS_SMALL_INT(args[1])); + assert(mp_obj_is_small_int(args[1])); type = MP_OBJ_SMALL_INT_VALUE(args[1]); if (n_args > 2) { - assert(MP_OBJ_IS_SMALL_INT(args[2])); + assert(mp_obj_is_small_int(args[2])); proto = MP_OBJ_SMALL_INT_VALUE(args[2]); } } @@ -497,7 +509,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) { memset(&hints, 0, sizeof(hints)); // getaddrinfo accepts port in string notation, so however // it may seem stupid, we need to convert int to str - if (MP_OBJ_IS_SMALL_INT(args[1])) { + if (mp_obj_is_small_int(args[1])) { unsigned port = (unsigned short)MP_OBJ_SMALL_INT_VALUE(args[1]); snprintf(buf, sizeof(buf), "%u", port); serv = buf; diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 01e5876b0b..a13b25090e 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -135,7 +135,7 @@ #ifndef MICROPY_PY_USELECT_POSIX #define MICROPY_PY_USELECT_POSIX (1) #endif -#define MICROPY_PY_WEBSOCKET (0) +#define MICROPY_PY_UWEBSOCKET (0) #define MICROPY_PY_MACHINE (0) #define MICROPY_PY_MACHINE_PULSE (0) #define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr @@ -144,7 +144,7 @@ #define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MAX_SS (4096) -#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ +#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ #define MICROPY_VFS_FAT (0) // Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h index 27086a167d..456968cf33 100644 --- a/ports/unix/mpconfigport_coverage.h +++ b/ports/unix/mpconfigport_coverage.h @@ -36,9 +36,12 @@ #define MICROPY_FLOAT_HIGH_QUALITY_HASH (1) #define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_READER_VFS (1) +#define MICROPY_WARNINGS_CATEGORY (1) #define MICROPY_MODULE_GETATTR (1) #define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (1) +#define MICROPY_PY_BUILTINS_NEXT2 (1) #define MICROPY_PY_BUILTINS_RANGE_BINOP (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_MODULES (1) @@ -58,6 +61,7 @@ #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) #define MICROPY_PY_UCRYPTOLIB (1) +#define MICROPY_PY_UCRYPTOLIB_CTR (1) // TODO these should be generic, not bound to fatfs #define mp_type_fileio mp_type_vfs_posix_fileio diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c index 864cf795e7..40545485db 100644 --- a/ports/unix/mpthreadport.c +++ b/ports/unix/mpthreadport.c @@ -34,8 +34,10 @@ #if MICROPY_PY_THREAD +#include #include #include +#include // this structure forms a linked list, one node per active thread typedef struct _thread_t { @@ -53,7 +55,12 @@ STATIC thread_t *thread; // this is used to synchronise the signal handler of the thread // it's needed because we can't use any pthread calls in a signal handler -STATIC volatile int thread_signal_done; +#if defined(__APPLE__) +STATIC char thread_signal_done_name[25]; +STATIC sem_t *thread_signal_done_p; +#else +STATIC sem_t thread_signal_done; +#endif // this signal handler is used to scan the regs and stack of a thread STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) { @@ -70,7 +77,11 @@ STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) { void **ptrs = (void **)(void *)MP_STATE_THREAD(pystack_start); gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void *)); #endif - thread_signal_done = 1; + #if defined(__APPLE__) + sem_post(thread_signal_done_p); + #else + sem_post(&thread_signal_done); + #endif } } @@ -85,6 +96,13 @@ void mp_thread_init(void) { thread->arg = NULL; thread->next = NULL; + #if defined(__APPLE__) + snprintf(thread_signal_done_name, sizeof(thread_signal_done_name), "micropython_sem_%d", (int)thread->id); + thread_signal_done_p = sem_open(thread_signal_done_name, O_CREAT | O_EXCL, 0666, 0); + #else + sem_init(&thread_signal_done, 0, 0); + #endif + // enable signal handler for garbage collection struct sigaction sa; sa.sa_flags = SA_SIGINFO; @@ -93,6 +111,23 @@ void mp_thread_init(void) { sigaction(SIGUSR1, &sa, NULL); } +void mp_thread_deinit(void) { + pthread_mutex_lock(&thread_mutex); + while (thread->next != NULL) { + thread_t *th = thread; + thread = thread->next; + pthread_cancel(th->id); + free(th); + } + pthread_mutex_unlock(&thread_mutex); + #if defined(__APPLE__) + sem_close(thread_signal_done_p); + sem_unlink(thread_signal_done_name); + #endif + assert(thread->id == pthread_self()); + free(thread); +} + // This function scans all pointers that are external to the current thread. // It does this by signalling all other threads and getting them to scan their // own registers and stack. Note that there may still be some edge cases left @@ -109,11 +144,12 @@ void mp_thread_gc_others(void) { if (!th->ready) { continue; } - thread_signal_done = 0; pthread_kill(th->id, SIGUSR1); - while (thread_signal_done == 0) { - sched_yield(); - } + #if defined(__APPLE__) + sem_wait(thread_signal_done_p); + #else + sem_wait(&thread_signal_done); + #endif } pthread_mutex_unlock(&thread_mutex); } @@ -127,6 +163,7 @@ void mp_thread_set_state(void *state) { } void mp_thread_start(void) { + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_mutex_lock(&thread_mutex); for (thread_t *th = thread; th != NULL; th = th->next) { if (th->id == pthread_self()) { @@ -159,6 +196,11 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { goto er; } + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (ret != 0) { + goto er; + } + pthread_mutex_lock(&thread_mutex); // create thread @@ -191,12 +233,18 @@ er: void mp_thread_finish(void) { pthread_mutex_lock(&thread_mutex); - // TODO unlink from list + thread_t *prev = NULL; for (thread_t *th = thread; th != NULL; th = th->next) { if (th->id == pthread_self()) { - th->ready = 0; + if (prev == NULL) { + thread = th->next; + } else { + prev->next = th->next; + } + free(th); break; } + prev = th; } pthread_mutex_unlock(&thread_mutex); } diff --git a/ports/unix/mpthreadport.h b/ports/unix/mpthreadport.h index bd712ebee0..c27144a9c8 100644 --- a/ports/unix/mpthreadport.h +++ b/ports/unix/mpthreadport.h @@ -29,4 +29,5 @@ typedef pthread_mutex_t mp_thread_mutex_t; void mp_thread_init(void); +void mp_thread_deinit(void); void mp_thread_gc_others(void); diff --git a/py/asmarm.c b/py/asmarm.c index 871f0bb486..5850b52073 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -197,7 +197,16 @@ void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src) { emit_al(as, asm_arm_op_mov_reg(reg_dest, reg_src)); } -void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) { +size_t asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) { + // Insert immediate into code and jump over it + emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc] + emit_al(as, 0xa000000); // b pc + size_t loc = mp_asm_base_get_code_pos(&as->base); + emit(as, imm); + return loc; +} + +void asm_arm_mov_reg_i32_optimised(asm_arm_t *as, uint rd, int imm) { // TODO: There are more variants of immediate values if ((imm & 0xFF) == imm) { emit_al(as, asm_arm_op_mov_imm(rd, imm)); @@ -205,10 +214,7 @@ void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) { // mvn is "move not", not "move negative" emit_al(as, asm_arm_op_mvn_imm(rd, ~imm)); } else { - // Insert immediate into code and jump over it - emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc] - emit_al(as, 0xa000000); // b pc - emit(as, imm); + asm_arm_mov_reg_i32(as, rd, imm); } } diff --git a/py/asmarm.h b/py/asmarm.h index 76850cb468..7ec4490599 100644 --- a/py/asmarm.h +++ b/py/asmarm.h @@ -81,7 +81,8 @@ void asm_arm_bkpt(asm_arm_t *as); // mov void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src); -void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm); +size_t asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm); +void asm_arm_mov_reg_i32_optimised(asm_arm_t *as, uint rd, int imm); void asm_arm_mov_local_reg(asm_arm_t *as, int local_num, uint rd); void asm_arm_mov_reg_local(asm_arm_t *as, uint rd, int local_num); void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond); @@ -177,7 +178,9 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src); #define ASM_CALL_IND(as, idx) asm_arm_bl_ind(as, idx, ASM_ARM_REG_R3) #define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_arm_mov_local_reg((as), (local_num), (reg_src)) -#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_arm_mov_reg_i32_optimised((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_arm_mov_reg_local((as), (reg_dest), (local_num)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_arm_mov_reg_reg((as), (reg_dest), (reg_src)) #define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_arm_mov_reg_local_addr((as), (reg_dest), (local_num)) diff --git a/py/asmthumb.c b/py/asmthumb.c index df7c88568c..3ea0163303 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -33,6 +33,8 @@ // wrapper around everything in this file #if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB +#include "py/mpstate.h" +#include "py/persistentcode.h" #include "py/mphal.h" #include "py/asmthumb.h" @@ -118,6 +120,21 @@ STATIC void asm_thumb_write_word32(asm_thumb_t *as, int w32) { void asm_thumb_entry(asm_thumb_t *as, int num_locals) { assert(num_locals >= 0); + // If this Thumb machine code is run from ARM state then add a prelude + // to switch to Thumb state for the duration of the function. + #if MICROPY_DYNAMIC_COMPILER || MICROPY_EMIT_ARM || (defined(__arm__) && !defined(__thumb2__)) + #if MICROPY_DYNAMIC_COMPILER + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_ARMV6) + #endif + { + asm_thumb_op32(as, 0x4010, 0xe92d); // push {r4, lr} + asm_thumb_op32(as, 0xe009, 0xe28f); // add lr, pc, 8 + 1 + asm_thumb_op32(as, 0xff3e, 0xe12f); // blx lr + asm_thumb_op32(as, 0x4010, 0xe8bd); // pop {r4, lr} + asm_thumb_op32(as, 0xff1e, 0xe12f); // bx lr + } + #endif + // work out what to push and how many extra spaces to reserve on stack // so that we have enough for all locals and it's aligned an 8-byte boundary // we push extra regs (r1, r2, r3) to help do the stack adjustment @@ -225,10 +242,12 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { } // if loading lo half with movw, the i16 value will be zero extended into the r32 register! -void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { +size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { assert(reg_dest < ASM_THUMB_REG_R15); + size_t loc = mp_asm_base_get_code_pos(&as->base); // mov[wt] reg_dest, #i16_src asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); + return loc; } #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff)) @@ -271,12 +290,16 @@ bool asm_thumb_bl_label(asm_thumb_t *as, uint label) { return as->base.pass != MP_ASM_PASS_EMIT || SIGNED_FIT23(rel); } -void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) { +size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) { // movw, movt does it in 8 bytes // ldr [pc, #], dw does it in 6 bytes, but we might not reach to end of code for dw + size_t loc = mp_asm_base_get_code_pos(&as->base); + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVT, reg_dest, i32 >> 16); + + return loc; } void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { diff --git a/py/asmthumb.h b/py/asmthumb.h index b4828b125d..c37358e886 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -263,14 +263,14 @@ static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uin #define ASM_THUMB_OP_MOVT (0xf2c0) void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src); -void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); +size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); // these return true if the destination is in range, false otherwise bool asm_thumb_b_n_label(asm_thumb_t *as, uint label); bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide); bool asm_thumb_bl_label(asm_thumb_t *as, uint label); -void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32_src); // convenience +size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32_src); // convenience void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience @@ -337,6 +337,8 @@ void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp); // convenien #define ASM_MOV_LOCAL_REG(as, local_num, reg) asm_thumb_mov_local_reg((as), (local_num), (reg)) #define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_thumb_mov_reg_i32_optimised((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_reg_i16((as), ASM_THUMB_OP_MOVW, (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_thumb_mov_reg_i32((as), (reg_dest), (imm)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_thumb_mov_reg_local((as), (reg_dest), (local_num)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_thumb_mov_reg_reg((as), (reg_dest), (reg_src)) #define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_thumb_mov_reg_local_addr((as), (reg_dest), (local_num)) diff --git a/py/asmx64.c b/py/asmx64.c index b881491121..723671d5a3 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -334,14 +334,16 @@ void asm_x64_mov_i8_to_r8(asm_x64_t *as, int src_i8, int dest_r64) { } */ -STATIC void asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64) { +size_t asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64) { // cpu defaults to i32 to r64, with zero extension if (dest_r64 < 8) { asm_x64_write_byte_1(as, OPCODE_MOV_I64_TO_R64 | dest_r64); } else { asm_x64_write_byte_2(as, REX_PREFIX | REX_B, OPCODE_MOV_I64_TO_R64 | (dest_r64 & 7)); } + size_t loc = mp_asm_base_get_code_pos(&as->base); asm_x64_write_word32(as, src_i32); + return loc; } void asm_x64_mov_i64_to_r64(asm_x64_t *as, int64_t src_i64, int dest_r64) { diff --git a/py/asmx64.h b/py/asmx64.h index ceea426d74..f4d36154f7 100644 --- a/py/asmx64.h +++ b/py/asmx64.h @@ -83,6 +83,7 @@ void asm_x64_nop(asm_x64_t *as); void asm_x64_push_r64(asm_x64_t *as, int src_r64); void asm_x64_pop_r64(asm_x64_t *as, int dest_r64); void asm_x64_mov_r64_r64(asm_x64_t *as, int dest_r64, int src_r64); +size_t asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64); void asm_x64_mov_i64_to_r64(asm_x64_t *as, int64_t src_i64, int dest_r64); void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64); void asm_x64_mov_r8_to_mem8(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp); @@ -181,6 +182,8 @@ void asm_x64_call_ind(asm_x64_t *as, size_t fun_id, int temp_r32); #define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_x64_mov_r64_to_local((as), (reg_src), (local_num)) #define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_x64_mov_i64_to_r64_optimised((as), (imm), (reg_dest)) +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_x64_mov_i32_to_r64((as), (imm), (reg_dest)) +#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_x64_mov_i32_to_r64((as), (imm), (reg_dest)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_x64_mov_local_to_r64((as), (local_num), (reg_dest)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x64_mov_r64_r64((as), (reg_dest), (reg_src)) #define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_x64_mov_local_addr_to_r64((as), (local_num), (reg_dest)) diff --git a/py/asmx86.c b/py/asmx86.c index b238321bda..c730a0c9a4 100644 --- a/py/asmx86.c +++ b/py/asmx86.c @@ -236,9 +236,11 @@ void asm_x86_mov_i8_to_r8(asm_x86_t *as, int src_i8, int dest_r32) { } #endif -void asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32) { +size_t asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32) { asm_x86_write_byte_1(as, OPCODE_MOV_I32_TO_R32 | dest_r32); + size_t loc = mp_asm_base_get_code_pos(&as->base); asm_x86_write_word32(as, src_i32); + return loc; } void asm_x86_and_r32_r32(asm_x86_t *as, int dest_r32, int src_r32) { diff --git a/py/asmx86.h b/py/asmx86.h index 930350d11b..5c2d9df08c 100644 --- a/py/asmx86.h +++ b/py/asmx86.h @@ -83,7 +83,7 @@ static inline void asm_x86_end_pass(asm_x86_t *as) { } void asm_x86_mov_r32_r32(asm_x86_t *as, int dest_r32, int src_r32); -void asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32); +size_t asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32); void asm_x86_mov_r8_to_mem8(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp); void asm_x86_mov_r16_to_mem16(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp); void asm_x86_mov_r32_to_mem32(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp); @@ -179,6 +179,8 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r #define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_x86_mov_r32_to_local((as), (reg_src), (local_num)) #define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest)) +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest)) +#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_x86_mov_local_to_r32((as), (local_num), (reg_dest)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x86_mov_r32_r32((as), (reg_dest), (reg_src)) #define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_x86_mov_local_addr_to_r32((as), (local_num), (reg_dest)) diff --git a/py/asmxtensa.c b/py/asmxtensa.c index a8e3a2655c..e10fd17333 100644 --- a/py/asmxtensa.c +++ b/py/asmxtensa.c @@ -156,18 +156,24 @@ void asm_xtensa_setcc_reg_reg_reg(asm_xtensa_t *as, uint cond, uint reg_dest, ui asm_xtensa_op_movi_n(as, reg_dest, 0); } -void asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) { +size_t asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) { + // load the constant + uint32_t const_table_offset = (uint8_t *)as->const_table - as->base.code_base; + size_t loc = const_table_offset + as->cur_const * WORD_SIZE; + asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, loc); + // store the constant in the table + if (as->const_table != NULL) { + as->const_table[as->cur_const] = i32; + } + ++as->cur_const; + return loc; +} + +void asm_xtensa_mov_reg_i32_optimised(asm_xtensa_t *as, uint reg_dest, uint32_t i32) { if (SIGNED_FIT12(i32)) { asm_xtensa_op_movi(as, reg_dest, i32); } else { - // load the constant - uint32_t const_table_offset = (uint8_t *)as->const_table - as->base.code_base; - asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, const_table_offset + as->cur_const * WORD_SIZE); - // store the constant in the table - if (as->const_table != NULL) { - as->const_table[as->cur_const] = i32; - } - ++as->cur_const; + asm_xtensa_mov_reg_i32(as, reg_dest, i32); } } diff --git a/py/asmxtensa.h b/py/asmxtensa.h index 685b3f9492..48c27d557d 100644 --- a/py/asmxtensa.h +++ b/py/asmxtensa.h @@ -26,6 +26,7 @@ #ifndef MICROPY_INCLUDED_PY_ASMXTENSA_H #define MICROPY_INCLUDED_PY_ASMXTENSA_H +#include "py/misc.h" #include "py/asmbase.h" // calling conventions: @@ -238,7 +239,8 @@ void asm_xtensa_j_label(asm_xtensa_t *as, uint label); void asm_xtensa_bccz_reg_label(asm_xtensa_t *as, uint cond, uint reg, uint label); void asm_xtensa_bcc_reg_reg_label(asm_xtensa_t *as, uint cond, uint reg1, uint reg2, uint label); void asm_xtensa_setcc_reg_reg_reg(asm_xtensa_t *as, uint cond, uint reg_dest, uint reg_src1, uint reg_src2); -void asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32); +size_t asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32); +void asm_xtensa_mov_reg_i32_optimised(asm_xtensa_t *as, uint reg_dest, uint32_t i32); void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src); void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num); @@ -289,7 +291,9 @@ void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx); #define ASM_CALL_IND(as, idx) asm_xtensa_call_ind((as), (idx)) #define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_xtensa_mov_local_reg((as), (local_num), (reg_src)) -#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_xtensa_mov_reg_i32((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_xtensa_mov_reg_i32_optimised((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_xtensa_mov_reg_i32((as), (reg_dest), (imm)) +#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_xtensa_mov_reg_i32((as), (reg_dest), (imm)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_xtensa_mov_reg_local((as), (reg_dest), (local_num)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_mov_n((as), (reg_dest), (reg_src)) #define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_xtensa_mov_reg_local_addr((as), (reg_dest), (local_num)) diff --git a/py/bc.c b/py/bc.c index 1e2c0bbae1..f315dfe94f 100644 --- a/py/bc.c +++ b/py/bc.c @@ -192,7 +192,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw for (size_t i = 0; i < n_kw; i++) { // the keys in kwargs are expected to be qstr objects mp_obj_t wanted_arg_name = kwargs[2 * i]; - if (MP_UNLIKELY(!MP_OBJ_IS_QSTR(wanted_arg_name))) { + if (MP_UNLIKELY(!mp_obj_is_qstr(wanted_arg_name))) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(translate("unexpected keyword argument")); #else @@ -331,7 +331,7 @@ STATIC const byte opcode_format_table[64] = { OC4(O, O, U, U), // 0x38-0x3b OC4(U, O, B, O), // 0x3c-0x3f OC4(O, B, B, O), // 0x40-0x43 - OC4(B, B, O, B), // 0x44-0x47 + OC4(O, U, O, B), // 0x44-0x47 OC4(U, U, U, U), // 0x48-0x4b OC4(U, U, U, U), // 0x4c-0x4f OC4(V, V, U, V), // 0x50-0x53 @@ -392,7 +392,7 @@ STATIC const byte opcode_format_table[64] = { #undef V #undef O -uint mp_opcode_format(const byte *ip, size_t *opcode_size) { +uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint) { uint f = (opcode_format_table[*ip >> 2] >> (2 * (*ip & 3))) & 3; const byte *ip_start = ip; if (f == MP_OPCODE_QSTR) { @@ -413,7 +413,9 @@ uint mp_opcode_format(const byte *ip, size_t *opcode_size) { ); ip += 1; if (f == MP_OPCODE_VAR_UINT) { - while ((*ip++ & 0x80) != 0) { + if (count_var_uint) { + while ((*ip++ & 0x80) != 0) { + } } } else if (f == MP_OPCODE_OFFSET) { ip += 2; diff --git a/py/bc.h b/py/bc.h index 6f62711c87..a3c1a45b94 100644 --- a/py/bc.h +++ b/py/bc.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -114,7 +115,7 @@ const byte *mp_bytecode_print_str(const byte *ip); #define MP_OPCODE_VAR_UINT (2) #define MP_OPCODE_OFFSET (3) -uint mp_opcode_format(const byte *ip, size_t *opcode_size); +uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint); #endif diff --git a/py/bc0.h b/py/bc0.h index a031bcc88b..05fc2c3ee6 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -77,8 +77,7 @@ #define MP_BC_END_FINALLY (0x41) #define MP_BC_GET_ITER (0x42) #define MP_BC_FOR_ITER (0x43) // rel byte code offset, 16-bit unsigned -#define MP_BC_POP_BLOCK (0x44) -#define MP_BC_POP_EXCEPT (0x45) +#define MP_BC_POP_EXCEPT_JUMP (0x44) // rel byte code offset, 16-bit unsigned #define MP_BC_UNWIND_JUMP (0x46) // rel byte code offset, 16-bit signed, in excess; then a byte #define MP_BC_GET_ITER_STACK (0x47) diff --git a/py/binary.c b/py/binary.c index cd61d74fa8..15ad49e555 100644 --- a/py/binary.c +++ b/py/binary.c @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -348,7 +349,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte ** default: { bool signed_type = is_signed(val_type); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) { + if (mp_obj_is_type(val_in, &mp_type_int)) { // It's a longint. mp_obj_int_buffer_overflow_check(val_in, size, signed_type); mp_obj_int_to_bytes_impl(val_in, struct_type == '>', size, p); @@ -395,7 +396,7 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v bool signed_type = is_signed(typecode); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) { + if (mp_obj_is_type(val_in, &mp_type_int)) { // It's a long int. mp_obj_int_buffer_overflow_check(val_in, size, signed_type); mp_obj_int_to_bytes_impl(val_in, MP_ENDIANNESS_BIG, diff --git a/py/binary.h b/py/binary.h index 6c70d93339..f13eb9260b 100644 --- a/py/binary.h +++ b/py/binary.h @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/builtin.h b/py/builtin.h index 58c4c1e524..52aa8c2123 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -63,7 +63,11 @@ MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_len_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_builtin_locals_obj); MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_max_obj); MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_min_obj); +#if MICROPY_PY_BUILTINS_NEXT2 +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_next_obj); +#else MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_next_obj); +#endif MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_oct_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_ord_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_pow_obj); @@ -114,7 +118,7 @@ extern const mp_obj_module_t mp_module_ussl; extern const mp_obj_module_t mp_module_utimeq; extern const mp_obj_module_t mp_module_machine; extern const mp_obj_module_t mp_module_lwip; -extern const mp_obj_module_t mp_module_websocket; +extern const mp_obj_module_t mp_module_uwebsocket; extern const mp_obj_module_t mp_module_webrepl; extern const mp_obj_module_t mp_module_framebuf; extern const mp_obj_module_t mp_module_btree; diff --git a/py/builtinevex.c b/py/builtinevex.c index 5538ac783c..db2dcd5efe 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -54,7 +54,7 @@ STATIC mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj // a bit of a hack: fun_bc will re-set globals, so need to make sure it's // the correct one - if (MP_OBJ_IS_TYPE(self->module_fun, &mp_type_fun_bc)) { + if (mp_obj_is_type(self->module_fun, &mp_type_fun_bc)) { mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(self->module_fun); fun_bc->globals = globals; } @@ -122,7 +122,7 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i mp_obj_dict_t *locals = mp_locals_get(); for (size_t i = 1; i < 3 && i < n_args; ++i) { if (args[i] != mp_const_none) { - if (!MP_OBJ_IS_TYPE(args[i], &mp_type_dict)) { + if (!mp_obj_is_type(args[i], &mp_type_dict)) { mp_raise_TypeError(NULL); } locals = MP_OBJ_TO_PTR(args[i]); @@ -133,7 +133,7 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i } #if MICROPY_PY_BUILTINS_COMPILE - if (MP_OBJ_IS_TYPE(args[0], &mp_type_code)) { + if (mp_obj_is_type(args[0], &mp_type_code)) { return code_execute(MP_OBJ_TO_PTR(args[0]), globals, locals); } #endif diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 225126029e..828ab4feb8 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -60,7 +60,7 @@ STATIC void mp_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) { #if MICROPY_PY_BUILTINS_HELP_MODULES STATIC void mp_help_add_from_map(mp_obj_t list, const mp_map_t *map) { for (size_t i = 0; i < map->alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { mp_obj_list_append(list, map->table[i].key); } } @@ -133,11 +133,13 @@ STATIC void mp_help_print_modules(void) { mp_print_str(MP_PYTHON_PRINTER, "\n"); } + #if MICROPY_ENABLE_EXTERNAL_IMPORT // let the user know there may be other modules available from the filesystem const compressed_string_t *compressed = translate("Plus any modules on the filesystem\n"); char decompressed[decompress_length(compressed)]; decompress(compressed, decompressed); mp_print_str(MP_PYTHON_PRINTER, decompressed); + #endif } #endif diff --git a/py/builtinimport.c b/py/builtinimport.c index 8462c146b1..0fa35f6e9f 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -122,7 +122,6 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d vstr_reset(dest); size_t p_len; const char *p = mp_obj_str_get_data(path_items[i], &p_len); - DEBUG_printf("Looking in path: %d =%s=\n", i, p); if (p_len > 0) { vstr_add_strn(dest, p, p_len); vstr_add_char(dest, PATH_SEP_CHAR); @@ -140,7 +139,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d #endif } -#if MICROPY_ENABLE_COMPILER +#if MICROPY_MODULE_FROZEN_STR || MICROPY_ENABLE_COMPILER STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) { #if MICROPY_PY___FILE__ qstr source_name = lex->source_name; @@ -192,7 +191,7 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, co #endif STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { - #if MICROPY_MODULE_FROZEN || MICROPY_PERSISTENT_CODE_LOAD || MICROPY_ENABLE_COMPILER + #if MICROPY_MODULE_FROZEN || MICROPY_ENABLE_COMPILER || (MICROPY_PERSISTENT_CODE_LOAD && MICROPY_HAS_FILE_READER) char *file_str = vstr_null_terminated_str(file); #endif @@ -230,7 +229,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // If we support loading .mpy files then check if the file extension is of // the correct format and, if so, load and execute the file. - #if MICROPY_PERSISTENT_CODE_LOAD + #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); do_execute_raw_code(module_obj, raw_code, file_str); @@ -246,7 +245,6 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { return; } #else - // If we get here then the file was not frozen and we can't compile scripts. mp_raise_ImportError(translate("script compilation not supported")); #endif @@ -421,7 +419,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { MP_MAP_LOOKUP); } - if (el != NULL && MP_OBJ_IS_TYPE(el->value, &mp_type_module)) { + if (el != NULL && mp_obj_is_type(el->value, &mp_type_module)) { module_obj = el->value; mp_module_call_init(mod_name, module_obj); } else { diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 5745c4f1d2..e550cdbbde 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -639,6 +639,19 @@ $(addprefix lib/,\ endif endif +SRC_CIRCUITPY_COMMON = \ + lib/libc/string0.c \ + lib/mp-readline/readline.c \ + lib/oofatfs/ff.c \ + lib/oofatfs/ffunicode.c \ + lib/timeutils/timeutils.c \ + lib/utils/buffer_helper.c \ + lib/utils/context_manager_helpers.c \ + lib/utils/interrupt_char.c \ + lib/utils/pyexec.c \ + lib/utils/stdout_helpers.c \ + lib/utils/sys_stdio_mphal.c + ifdef LD_TEMPLATE_FILE # Generate a linker script (.ld file) from a template, for those builds that use it. GENERATED_LD_FILE = $(BUILD)/$(notdir $(patsubst %.template.ld,%.ld,$(LD_TEMPLATE_FILE))) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 801e1867e7..fb14f2871b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -130,7 +130,9 @@ // // 1 = SFN/ANSI 437=LFN/U.S.(OEM) #define MICROPY_FATFS_ENABLE_LFN (1) -#define MICROPY_FATFS_LFN_CODE_PAGE (437) +// Don't use parens on the value below because it gets combined with a prefix in +// the preprocessor. +#define MICROPY_FATFS_LFN_CODE_PAGE 437 #define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MULTI_PARTITION (1) diff --git a/py/compile.c b/py/compile.c index a484022bb9..f0c9221db7 100644 --- a/py/compile.c +++ b/py/compile.c @@ -35,6 +35,7 @@ #include "py/compile.h" #include "py/runtime.h" #include "py/asmbase.h" +#include "py/persistentcode.h" #include "supervisor/shared/translate.h" @@ -80,7 +81,25 @@ typedef enum { #endif -#if MICROPY_EMIT_NATIVE +#if MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER + +#define NATIVE_EMITTER(f) emit_native_table[mp_dynamic_compiler.native_arch]->emit_##f +#define NATIVE_EMITTER_TABLE emit_native_table[mp_dynamic_compiler.native_arch] + +STATIC const emit_method_table_t *emit_native_table[] = { + NULL, + &emit_native_x86_method_table, + &emit_native_x64_method_table, + &emit_native_arm_method_table, + &emit_native_thumb_method_table, + &emit_native_thumb_method_table, + &emit_native_thumb_method_table, + &emit_native_thumb_method_table, + &emit_native_thumb_method_table, + &emit_native_xtensa_method_table, +}; + +#elif MICROPY_EMIT_NATIVE // define a macro to access external native emitter #if MICROPY_EMIT_X64 #define NATIVE_EMITTER(f) emit_native_x64_##f @@ -95,9 +114,28 @@ typedef enum { #else #error "unknown native emitter" #endif +#define NATIVE_EMITTER_TABLE &NATIVE_EMITTER(method_table) #endif -#if MICROPY_EMIT_INLINE_ASM +#if MICROPY_EMIT_INLINE_ASM && MICROPY_DYNAMIC_COMPILER + +#define ASM_EMITTER(f) emit_asm_table[mp_dynamic_compiler.native_arch]->asm_##f +#define ASM_EMITTER_TABLE emit_asm_table[mp_dynamic_compiler.native_arch] + +STATIC const emit_inline_asm_method_table_t *emit_asm_table[] = { + NULL, + NULL, + NULL, + &emit_inline_thumb_method_table, + &emit_inline_thumb_method_table, + &emit_inline_thumb_method_table, + &emit_inline_thumb_method_table, + &emit_inline_thumb_method_table, + &emit_inline_thumb_method_table, + &emit_inline_xtensa_method_table, +}; + +#elif MICROPY_EMIT_INLINE_ASM // define macros for inline assembler #if MICROPY_EMIT_INLINE_THUMB #define ASM_DECORATOR_QSTR MP_QSTR_asm_thumb @@ -108,6 +146,7 @@ typedef enum { #else #error "unknown asm emitter" #endif +#define ASM_EMITTER_TABLE &ASM_EMITTER(method_table) #endif #define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm)) @@ -166,6 +205,7 @@ STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const com STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra); STATIC void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_kind_t kind); +STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t *pns, bool create_map); STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn); STATIC uint comp_next_label(compiler_t *comp) { @@ -808,14 +848,32 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ *emit_options = MP_EMIT_OPT_VIPER; #endif #if MICROPY_EMIT_INLINE_ASM - // @micropython.asm_thumb decorator. + #if MICROPY_DYNAMIC_COMPILER + } else if (attr == MP_QSTR_asm_thumb) { + *emit_options = MP_EMIT_OPT_ASM; + } else if (attr == MP_QSTR_asm_xtensa) { + *emit_options = MP_EMIT_OPT_ASM; + #else } else if (attr == ASM_DECORATOR_QSTR) { *emit_options = MP_EMIT_OPT_ASM; + #endif #endif } else { compile_syntax_error(comp, name_nodes[1], translate("invalid micropython decorator")); } + #if MICROPY_DYNAMIC_COMPILER + if (*emit_options == MP_EMIT_OPT_NATIVE_PYTHON || *emit_options == MP_EMIT_OPT_VIPER) { + if (emit_native_table[mp_dynamic_compiler.native_arch] == NULL) { + compile_syntax_error(comp, name_nodes[1], translate("invalid architecture")); + } + } else if (*emit_options == MP_EMIT_OPT_ASM) { + if (emit_asm_table[mp_dynamic_compiler.native_arch] == NULL) { + compile_syntax_error(comp, name_nodes[1], translate("invalid architecture")); + } + } + #endif + return true; } @@ -1545,8 +1603,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ compile_increase_except_level(comp, l1, MP_EMIT_SETUP_BLOCK_EXCEPT); compile_node(comp, pn_body); // body - EMIT(pop_block); - EMIT_ARG(jump, success_label); // jump over exception handler + EMIT_ARG(pop_except_jump, success_label, false); // jump over exception handler EMIT_ARG(label_assign, l1); // start of exception handler EMIT(start_except_handler); @@ -1593,26 +1650,31 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ compile_store_id(comp, qstr_exception_local); } + // If the exception is bound to a variable then the of the + // exception handler is wrapped in a try-finally so that the name can + // be deleted (per Python semantics) even if the has an exception. + // In such a case the generated code for the exception handler is: + // try: + // + // finally: + // = None + // del uint l3 = 0; if (qstr_exception_local != 0) { l3 = comp_next_label(comp); compile_increase_except_level(comp, l3, MP_EMIT_SETUP_BLOCK_FINALLY); } - compile_node(comp, pns_except->nodes[1]); - if (qstr_exception_local != 0) { - EMIT(pop_block); - } - EMIT(pop_except); + compile_node(comp, pns_except->nodes[1]); // the if (qstr_exception_local != 0) { EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(label_assign, l3); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); compile_store_id(comp, qstr_exception_local); compile_delete_id(comp, qstr_exception_local); - compile_decrease_except_level(comp); } - EMIT_ARG(jump, l2); + + EMIT_ARG(pop_except_jump, l2, true); EMIT_ARG(label_assign, end_finally_label); EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance } @@ -1638,7 +1700,6 @@ STATIC void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n } else { compile_try_except(comp, pn_body, n_except, pn_except, pn_else); } - EMIT(pop_block); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(label_assign, l_finally_block); compile_node(comp, pn_finally); @@ -1761,8 +1822,7 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns compile_load_id(comp, context); compile_await_object_method(comp, MP_QSTR___anext__); c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable - EMIT(pop_block); - EMIT_ARG(jump, try_else_label); + EMIT_ARG(pop_except_jump, try_else_label, false); EMIT_ARG(label_assign, try_exception_label); EMIT(start_except_handler); @@ -1771,8 +1831,7 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH); EMIT_ARG(pop_jump_if, false, try_finally_label); EMIT(pop_top); // pop exception instance - EMIT(pop_except); - EMIT_ARG(jump, while_else_label); + EMIT_ARG(pop_except_jump, while_else_label, true); EMIT_ARG(label_assign, try_finally_label); EMIT_ARG(adjust_stack_size, 1); // if we jump here, the exc is on the stack @@ -1829,8 +1888,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod compile_async_with_stmt_helper(comp, n - 1, nodes + 1, body); EMIT_ARG(adjust_stack_size, -3); - // Finish the "try" block - EMIT(pop_block); + // We have now finished the "try" block and fall through to the "finally" // At this point, after the with body has executed, we have 3 cases: // 1. no exception, we just fall through to this point; stack: (..., ctx_mgr) @@ -1849,7 +1907,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod // Detect if TOS an exception or not EMIT(dup_top); - EMIT_LOAD_GLOBAL(MP_QSTR_Exception); + EMIT_LOAD_GLOBAL(MP_QSTR_BaseException); EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH); EMIT_ARG(pop_jump_if, false, l_ret_unwind_jump); // if not an exception then we have case 3 @@ -2327,6 +2385,20 @@ STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *p EMIT_ARG(call_function, 2, 0, 0); i = 1; } + + #if MICROPY_COMP_CONST_LITERAL && MICROPY_PY_COLLECTIONS_ORDEREDDICT + // handle special OrderedDict constructor + } else if (MP_PARSE_NODE_IS_ID(pns->nodes[0]) + && MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]) == MP_QSTR_OrderedDict + && MP_PARSE_NODE_STRUCT_KIND(pns_trail[0]) == PN_trailer_paren + && MP_PARSE_NODE_IS_STRUCT_KIND(pns_trail[0]->nodes[0], PN_atom_brace)) { + // at this point we have matched "OrderedDict({...})" + + EMIT_ARG(call_function, 0, 0, 0); + mp_parse_node_struct_t *pns_dict = (mp_parse_node_struct_t *)pns_trail[0]->nodes[0]; + compile_atom_brace_helper(comp, pns_dict, false); + i = 1; + #endif } // compile the remaining trailers @@ -2535,16 +2607,20 @@ STATIC void compile_atom_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) } } -STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { +STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t *pns, bool create_map) { mp_parse_node_t pn = pns->nodes[0]; if (MP_PARSE_NODE_IS_NULL(pn)) { // empty dict - EMIT_ARG(build, 0, MP_EMIT_BUILD_MAP); + if (create_map) { + EMIT_ARG(build, 0, MP_EMIT_BUILD_MAP); + } } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { pns = (mp_parse_node_struct_t *)pn; if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) { // dict with one element - EMIT_ARG(build, 1, MP_EMIT_BUILD_MAP); + if (create_map) { + EMIT_ARG(build, 1, MP_EMIT_BUILD_MAP); + } compile_node(comp, pn); EMIT(store_map); } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) { @@ -2561,7 +2637,9 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { bool is_dict; if (!MICROPY_PY_BUILTINS_SET || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { // a dictionary - EMIT_ARG(build, 1 + n, MP_EMIT_BUILD_MAP); + if (create_map) { + EMIT_ARG(build, 1 + n, MP_EMIT_BUILD_MAP); + } compile_node(comp, pns->nodes[0]); EMIT(store_map); is_dict = true; @@ -2631,6 +2709,10 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { } } +STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { + compile_atom_brace_helper(comp, pns, true); +} + STATIC void compile_trailer_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_trailer_paren_helper(comp, pns->nodes[0], false, 0); } @@ -2769,9 +2851,6 @@ STATIC mp_obj_t get_const_object(mp_parse_node_struct_t *pns) { } STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) { - #if MICROPY_EMIT_NATIVE - comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; - #endif EMIT_ARG(load_const_obj, get_const_object(pns)); } @@ -2806,9 +2885,6 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { } else { EMIT_ARG(load_const_obj, mp_obj_new_int_from_ll(arg)); } - #if MICROPY_EMIT_NATIVE - comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; - #endif } #else EMIT_ARG(load_const_small_int, arg); @@ -2831,9 +2907,6 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { const byte *data = qstr_data(arg, &len); EMIT_ARG(load_const_obj, mp_obj_new_bytes(data, len)); } - #if MICROPY_EMIT_NATIVE - comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; - #endif break; case MP_PARSE_NODE_TOKEN: default: @@ -2875,6 +2948,8 @@ STATIC int compile_viper_type_annotation(compiler_t *comp, mp_parse_node_t pn_an #endif STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star) { + (void)pn_dbl_star; + // check that **kw is last if ((comp->scope_cur->scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { compile_syntax_error(comp, pn, translate("invalid syntax")); @@ -3038,7 +3113,7 @@ STATIC void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) { if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && MP_PARSE_NODE_LEAF_KIND(pns->nodes[0]) == MP_PARSE_NODE_STRING) || (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object) - && MP_OBJ_IS_STR(get_const_object((mp_parse_node_struct_t *)pns->nodes[0])))) { + && mp_obj_is_str(get_const_object((mp_parse_node_struct_t *)pns->nodes[0])))) { // compile the doc string compile_node(comp, pns->nodes[0]); // store the doc string @@ -3364,7 +3439,11 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind void *f = mp_asm_base_get_code((mp_asm_base_t *)comp->emit_inline_asm); mp_emit_glue_assign_native(comp->scope_cur->raw_code, MP_CODE_NATIVE_ASM, f, mp_asm_base_get_code_size((mp_asm_base_t *)comp->emit_inline_asm), - NULL, comp->scope_cur->num_pos_args, 0, type_sig); + NULL, + #if MICROPY_PERSISTENT_CODE_SAVE + 0, 0, 0, 0, NULL, + #endif + comp->scope_cur->num_pos_args, 0, type_sig); } } @@ -3495,12 +3574,12 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f #endif uint max_num_labels = 0; for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) { - if (false) { #if MICROPY_EMIT_INLINE_ASM - } else if (s->emit_options == MP_EMIT_OPT_ASM) { + if (s->emit_options == MP_EMIT_OPT_ASM) { compile_scope_inline_asm(comp, s, MP_PASS_SCOPE); + } else #endif - } else { + { compile_scope(comp, s, MP_PASS_SCOPE); // Check if any implicitly declared variables should be closed over @@ -3531,30 +3610,32 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f emit_t *emit_native = NULL; #endif for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) { - if (false) { - // dummy - #if MICROPY_EMIT_INLINE_ASM - } else if (s->emit_options == MP_EMIT_OPT_ASM) { + if (s->emit_options == MP_EMIT_OPT_ASM) { // inline assembly if (comp->emit_inline_asm == NULL) { comp->emit_inline_asm = ASM_EMITTER(new)(max_num_labels); } comp->emit = NULL; - comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table); + comp->emit_inline_asm_method_table = ASM_EMITTER_TABLE; compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE); #if MICROPY_EMIT_INLINE_XTENSA // Xtensa requires an extra pass to compute size of l32r const table // TODO this can be improved by calculating it during SCOPE pass // but that requires some other structural changes to the asm emitters - compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE); + #if MICROPY_DYNAMIC_COMPILER + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_XTENSA) + #endif + { + compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE); + } #endif if (comp->compile_error == MP_OBJ_NULL) { compile_scope_inline_asm(comp, s, MP_PASS_EMIT); } + } else #endif - - } else { + { // choose the emit type @@ -3566,7 +3647,7 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f if (emit_native == NULL) { emit_native = NATIVE_EMITTER(new)(&comp->compile_error, &comp->next_label, max_num_labels); } - comp->emit_method_table = &NATIVE_EMITTER(method_table); + comp->emit_method_table = NATIVE_EMITTER_TABLE; comp->emit = emit_native; break; #endif // MICROPY_EMIT_NATIVE diff --git a/py/emit.h b/py/emit.h index 24a31f8e23..63911fc593 100644 --- a/py/emit.h +++ b/py/emit.h @@ -98,6 +98,11 @@ typedef struct _mp_emit_method_table_id_ops_t { } mp_emit_method_table_id_ops_t; typedef struct _emit_method_table_t { + #if MICROPY_DYNAMIC_COMPILER + emit_t *(*emit_new)(mp_obj_t * error_slot, uint *label_slot, mp_uint_t max_num_labels); + void (*emit_free)(emit_t *emit); + #endif + void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope); void (*end_pass)(emit_t *emit); bool (*last_emit_was_return_value)(emit_t *emit); @@ -134,8 +139,7 @@ typedef struct _emit_method_table_t { void (*get_iter)(emit_t *emit, bool use_stack); void (*for_iter)(emit_t *emit, mp_uint_t label); void (*for_iter_end)(emit_t *emit); - void (*pop_block)(emit_t *emit); - void (*pop_except)(emit_t *emit); + void (*pop_except_jump)(emit_t *emit, mp_uint_t label, bool within_exc_handler); void (*unary_op)(emit_t *emit, mp_unary_op_t op); void (*binary_op)(emit_t *emit, mp_binary_op_t op); void (*build)(emit_t *emit, mp_uint_t n_args, int kind); @@ -157,8 +161,6 @@ typedef struct _emit_method_table_t { void (*end_except_handler)(emit_t *emit); } emit_method_table_t; -int mp_native_type_from_qstr(qstr qst); - static inline void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst) { scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT); } @@ -232,8 +234,7 @@ void mp_emit_bc_end_finally(emit_t *emit); void mp_emit_bc_get_iter(emit_t *emit, bool use_stack); void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label); void mp_emit_bc_for_iter_end(emit_t *emit); -void mp_emit_bc_pop_block(emit_t *emit); -void mp_emit_bc_pop_except(emit_t *emit); +void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler); void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op); void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op); void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind); @@ -254,6 +255,11 @@ void mp_emit_bc_end_except_handler(emit_t *emit); typedef struct _emit_inline_asm_t emit_inline_asm_t; typedef struct _emit_inline_asm_method_table_t { + #if MICROPY_DYNAMIC_COMPILER + emit_inline_asm_t *(*asm_new)(mp_uint_t max_num_labels); + void (*asm_free)(emit_inline_asm_t *emit); + #endif + void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, mp_obj_t *error_slot); void (*end_pass)(emit_inline_asm_t *emit, mp_uint_t type_sig); mp_uint_t (*count_params)(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params); diff --git a/py/emitbc.c b/py/emitbc.c index 7e2989276f..740d7e24e9 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -744,7 +744,6 @@ void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) { } void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) { - mp_emit_bc_pop_block(emit); mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE); mp_emit_bc_label_assign(emit, label); emit_bc_pre(emit, 2); // ensure we have enough stack space to call the __exit__ method @@ -771,14 +770,10 @@ void mp_emit_bc_for_iter_end(emit_t *emit) { emit_bc_pre(emit, -MP_OBJ_ITER_BUF_NSLOTS); } -void mp_emit_bc_pop_block(emit_t *emit) { +void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { + (void)within_exc_handler; emit_bc_pre(emit, 0); - emit_write_bytecode_byte(emit, MP_BC_POP_BLOCK); -} - -void mp_emit_bc_pop_except(emit_t *emit) { - emit_bc_pre(emit, 0); - emit_write_bytecode_byte(emit, MP_BC_POP_EXCEPT); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_POP_EXCEPT_JUMP, label); } void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) { @@ -920,6 +915,11 @@ void mp_emit_bc_end_except_handler(emit_t *emit) { #if MICROPY_EMIT_NATIVE const emit_method_table_t emit_bc_method_table = { + #if MICROPY_DYNAMIC_COMPILER + NULL, + NULL, + #endif + mp_emit_bc_start_pass, mp_emit_bc_end_pass, mp_emit_bc_last_emit_was_return_value, @@ -965,8 +965,7 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_get_iter, mp_emit_bc_for_iter, mp_emit_bc_for_iter_end, - mp_emit_bc_pop_block, - mp_emit_bc_pop_except, + mp_emit_bc_pop_except_jump, mp_emit_bc_unary_op, mp_emit_bc_binary_op, mp_emit_bc_build, diff --git a/py/emitglue.c b/py/emitglue.c index 4949053410..f821af3150 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -67,12 +67,12 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, rc->kind = MP_CODE_BYTECODE; rc->scope_flags = scope_flags; - rc->data.u_byte.bytecode = code; - rc->data.u_byte.const_table = const_table; + rc->fun_data = code; + rc->const_table = const_table; #if MICROPY_PERSISTENT_CODE_SAVE - rc->data.u_byte.bc_len = len; - rc->data.u_byte.n_obj = n_obj; - rc->data.u_byte.n_raw_code = n_raw_code; + rc->fun_data_len = len; + rc->n_obj = n_obj; + rc->n_raw_code = n_raw_code; #endif #ifdef DEBUG_PRINT @@ -89,14 +89,31 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, } #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) { +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, + #if MICROPY_PERSISTENT_CODE_SAVE + uint16_t prelude_offset, + uint16_t n_obj, uint16_t n_raw_code, + uint16_t n_qstr, mp_qstr_link_entry_t *qstr_link, + #endif + mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) { + assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); + rc->kind = kind; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; - rc->data.u_native.fun_data = fun_data; - rc->data.u_native.const_table = const_table; - rc->data.u_native.type_sig = type_sig; + rc->fun_data = fun_data; + rc->const_table = const_table; + rc->type_sig = type_sig; + + #if MICROPY_PERSISTENT_CODE_SAVE + rc->fun_data_len = fun_len; + rc->prelude_offset = prelude_offset; + rc->n_obj = n_obj; + rc->n_raw_code = n_raw_code; + rc->n_qstr = n_qstr; + rc->qstr_link = qstr_link; + #endif #ifdef DEBUG_PRINT DEBUG_printf("assign native: kind=%d fun=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " flags=%x\n", kind, fun_data, fun_len, n_pos_args, (uint)scope_flags); @@ -124,10 +141,10 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar assert(rc != NULL); // def_args must be MP_OBJ_NULL or a tuple - assert(def_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_args, &mp_type_tuple)); + assert(def_args == MP_OBJ_NULL || mp_obj_is_type(def_args, &mp_type_tuple)); // def_kw_args must be MP_OBJ_NULL or a dict - assert(def_kw_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_kw_args, &mp_type_dict)); + assert(def_kw_args == MP_OBJ_NULL || mp_obj_is_type(def_kw_args, &mp_type_dict)); // make the function, depending on the raw code kind mp_obj_t fun; @@ -135,20 +152,19 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar #if MICROPY_EMIT_NATIVE case MP_CODE_NATIVE_PY: case MP_CODE_NATIVE_VIPER: - fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->data.u_native.fun_data, rc->data.u_native.const_table); + fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->fun_data, rc->const_table); break; #endif #if MICROPY_EMIT_INLINE_ASM case MP_CODE_NATIVE_ASM: - fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig); + fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->fun_data, rc->type_sig); break; #endif - case MP_CODE_BYTECODE: - fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.bytecode, rc->data.u_byte.const_table); - break; default: - // All other kinds are invalid. - mp_raise_RuntimeError(translate("Corrupt raw code")); + // rc->kind should always be set and BYTECODE is the only remaining case + assert(rc->kind == MP_CODE_BYTECODE); + fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->fun_data, rc->const_table); + break; } // check for generator functions and if so wrap in generator object diff --git a/py/emitglue.h b/py/emitglue.h index fc352fdbab..d8a8f4ba64 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -48,26 +48,30 @@ typedef enum { MP_CODE_NATIVE_ASM, } mp_raw_code_kind_t; +typedef struct _mp_qstr_link_entry_t { + uint16_t off; + uint16_t qst; +} mp_qstr_link_entry_t; + typedef struct _mp_raw_code_t { mp_uint_t kind : 3; // of type mp_raw_code_kind_t mp_uint_t scope_flags : 7; mp_uint_t n_pos_args : 11; - union { - struct { - const byte *bytecode; - const mp_uint_t *const_table; - #if MICROPY_PERSISTENT_CODE_SAVE - mp_uint_t bc_len; - uint16_t n_obj; - uint16_t n_raw_code; - #endif - } u_byte; - struct { - void *fun_data; - const mp_uint_t *const_table; - mp_uint_t type_sig; // for viper, compressed as 2-bit types; ret is MSB, then arg0, arg1, etc - } u_native; - } data; + const void *fun_data; + const mp_uint_t *const_table; + #if MICROPY_PERSISTENT_CODE_SAVE + size_t fun_data_len; + uint16_t n_obj; + uint16_t n_raw_code; + #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM + uint16_t prelude_offset; + uint16_t n_qstr; + mp_qstr_link_entry_t *qstr_link; + #endif + #endif + #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM + mp_uint_t type_sig; // for viper, compressed as 2-bit types; ret is MSB, then arg0, arg1, etc + #endif } mp_raw_code_t; mp_raw_code_t *mp_emit_glue_new_raw_code(void); @@ -81,7 +85,15 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, uint16_t n_obj, uint16_t n_raw_code, #endif mp_uint_t scope_flags); -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig); + +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, + const mp_uint_t *const_table, + #if MICROPY_PERSISTENT_CODE_SAVE + uint16_t prelude_offset, + uint16_t n_obj, uint16_t n_raw_code, + uint16_t n_qstr, mp_qstr_link_entry_t *qstr_link, + #endif + mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig); mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 1faeccbd27..1602f505b3 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -824,6 +824,11 @@ branch_not_in_range: } const emit_inline_asm_method_table_t emit_inline_thumb_method_table = { + #if MICROPY_DYNAMIC_COMPILER + emit_inline_thumb_new, + emit_inline_thumb_free, + #endif + emit_inline_thumb_start_pass, emit_inline_thumb_end_pass, emit_inline_thumb_count_params, diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c index 8094c0befa..e6f7e755bf 100644 --- a/py/emitinlinextensa.c +++ b/py/emitinlinextensa.c @@ -337,6 +337,11 @@ branch_not_in_range: } const emit_inline_asm_method_table_t emit_inline_xtensa_method_table = { + #if MICROPY_DYNAMIC_COMPILER + emit_inline_xtensa_new, + emit_inline_xtensa_free, + #endif + emit_inline_xtensa_start_pass, emit_inline_xtensa_end_pass, emit_inline_xtensa_count_params, diff --git a/py/emitnative.c b/py/emitnative.c index bcf7793c86..98788d992b 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -156,29 +156,6 @@ typedef enum { VTYPE_BUILTIN_CAST = 0x70 | MP_NATIVE_TYPE_OBJ, } vtype_kind_t; -int mp_native_type_from_qstr(qstr qst) { - switch (qst) { - case MP_QSTR_object: - return MP_NATIVE_TYPE_OBJ; - case MP_QSTR_bool: - return MP_NATIVE_TYPE_BOOL; - case MP_QSTR_int: - return MP_NATIVE_TYPE_INT; - case MP_QSTR_uint: - return MP_NATIVE_TYPE_UINT; - case MP_QSTR_ptr: - return MP_NATIVE_TYPE_PTR; - case MP_QSTR_ptr8: - return MP_NATIVE_TYPE_PTR8; - case MP_QSTR_ptr16: - return MP_NATIVE_TYPE_PTR16; - case MP_QSTR_ptr32: - return MP_NATIVE_TYPE_PTR32; - default: - return -1; - } -} - STATIC qstr vtype_to_qstr(vtype_kind_t vtype) { switch (vtype) { case VTYPE_PYOBJ: @@ -253,6 +230,11 @@ struct _emit_t { uint16_t const_table_cur_raw_code; mp_uint_t *const_table; + #if MICROPY_PERSISTENT_CODE_SAVE + uint16_t qstr_link_cur; + mp_qstr_link_entry_t *qstr_link; + #endif + bool last_emit_was_return_value; scope_t *scope; @@ -264,6 +246,7 @@ STATIC const uint8_t reg_local_table[REG_LOCAL_NUM] = {REG_LOCAL_1, REG_LOCAL_2, STATIC void emit_native_global_exc_entry(emit_t *emit); STATIC void emit_native_global_exc_exit(emit_t *emit); +STATIC void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj); emit_t *EXPORT_FUN(new)(mp_obj_t * error_slot, uint *label_slot, mp_uint_t max_num_labels) { emit_t *emit = m_new0(emit_t, 1); @@ -318,6 +301,32 @@ STATIC void emit_native_mov_reg_state_addr(emit_t *emit, int reg_dest, int local } } +STATIC void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) { + #if MICROPY_PERSISTENT_CODE_SAVE + size_t loc = ASM_MOV_REG_IMM_FIX_U16(emit->as, arg_reg, qst); + size_t link_idx = emit->qstr_link_cur++; + if (emit->pass == MP_PASS_EMIT) { + emit->qstr_link[link_idx].off = loc << 2 | 1; + emit->qstr_link[link_idx].qst = qst; + } + #else + ASM_MOV_REG_IMM(emit->as, arg_reg, qst); + #endif +} + +STATIC void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) { + #if MICROPY_PERSISTENT_CODE_SAVE + size_t loc = ASM_MOV_REG_IMM_FIX_WORD(emit->as, reg_dest, (mp_uint_t)MP_OBJ_NEW_QSTR(qst)); + size_t link_idx = emit->qstr_link_cur++; + if (emit->pass == MP_PASS_EMIT) { + emit->qstr_link[link_idx].off = loc << 2 | 2; + emit->qstr_link[link_idx].qst = qst; + } + #else + ASM_MOV_REG_IMM(emit->as, reg_dest, (mp_uint_t)MP_OBJ_NEW_QSTR(qst)); + #endif +} + #define emit_native_mov_state_imm_via(emit, local_num, imm, reg_temp) \ do { \ ASM_MOV_REG_IMM((emit)->as, (reg_temp), (imm)); \ @@ -330,8 +339,11 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop emit->pass = pass; emit->do_viper_types = scope->emit_options == MP_EMIT_OPT_VIPER; emit->stack_size = 0; - emit->const_table_cur_obj = 1; // first entry is for mp_fun_table + emit->const_table_cur_obj = 0; emit->const_table_cur_raw_code = 0; + #if MICROPY_PERSISTENT_CODE_SAVE + emit->qstr_link_cur = 0; + #endif emit->last_emit_was_return_value = false; emit->scope = scope; @@ -619,7 +631,7 @@ STATIC void emit_native_end_pass(emit_t *emit) { assert(emit->pass <= MP_PASS_STACK_SIZE || (emit->const_table_num_obj == emit->const_table_cur_obj)); emit->const_table_num_obj = emit->const_table_cur_obj; if (emit->pass == MP_PASS_CODE_SIZE) { - size_t const_table_alloc = emit->const_table_num_obj + emit->const_table_cur_raw_code; + size_t const_table_alloc = 1 + emit->const_table_num_obj + emit->const_table_cur_raw_code; size_t nqstr = 0; if (!emit->do_viper_types) { // Add room for qstr names of arguments @@ -629,6 +641,13 @@ STATIC void emit_native_end_pass(emit_t *emit) { emit->const_table = m_new(mp_uint_t, const_table_alloc); // Store mp_fun_table pointer just after qstrs emit->const_table[nqstr] = (mp_uint_t)(uintptr_t)mp_fun_table; + + #if MICROPY_PERSISTENT_CODE_SAVE + size_t qstr_link_alloc = emit->qstr_link_cur; + if (qstr_link_alloc > 0) { + emit->qstr_link = m_new(mp_qstr_link_entry_t, qstr_link_alloc); + } + #endif } if (emit->pass == MP_PASS_EMIT) { @@ -638,6 +657,11 @@ STATIC void emit_native_end_pass(emit_t *emit) { mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, f, f_len, emit->const_table, + #if MICROPY_PERSISTENT_CODE_SAVE + emit->prelude_offset, + emit->const_table_cur_obj, emit->const_table_cur_raw_code, + emit->qstr_link_cur, emit->qstr_link, + #endif emit->scope->num_pos_args, emit->scope->scope_flags, 0); } } @@ -922,6 +946,12 @@ STATIC void emit_call_with_2_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, mp_i ASM_CALL_IND(emit->as, fun_kind); } +STATIC void emit_call_with_qstr_arg(emit_t *emit, mp_fun_kind_t fun_kind, qstr qst, int arg_reg) { + need_reg_all(emit); + emit_native_mov_reg_qstr(emit, arg_reg, qst); + ASM_CALL_IND(emit->as, fun_kind); +} + // vtype of all n_pop objects is VTYPE_PYOBJ // Will convert any items that are not VTYPE_PYOBJ to this type and put them back on the stack. // If any conversions of non-immediate values are needed, then it uses REG_ARG_1, REG_ARG_2 and REG_RET. @@ -1038,12 +1068,14 @@ STATIC void emit_load_reg_with_ptr(emit_t *emit, int reg, mp_uint_t ptr, size_t } STATIC void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) { - size_t table_off = emit->const_table_cur_obj++; + // First entry is for mp_fun_table + size_t table_off = 1 + emit->const_table_cur_obj++; emit_load_reg_with_ptr(emit, reg, (mp_uint_t)obj, table_off); } STATIC void emit_load_reg_with_raw_code(emit_t *emit, int reg, mp_raw_code_t *rc) { - size_t table_off = emit->const_table_num_obj + emit->const_table_cur_raw_code++; + // First entry is for mp_fun_table, then constant objects + size_t table_off = 1 + emit->const_table_num_obj + emit->const_table_cur_raw_code++; emit_load_reg_with_ptr(emit, reg, (mp_uint_t)rc, table_off); } @@ -1220,7 +1252,7 @@ STATIC void emit_native_import_name(emit_t *emit, qstr qst) { assert(vtype_level == VTYPE_PYOBJ); emit->do_viper_types = orig_do_viper_types; - emit_call_with_imm_arg(emit, MP_F_IMPORT_NAME, qst, REG_ARG_1); // arg1 = import name + emit_call_with_qstr_arg(emit, MP_F_IMPORT_NAME, qst, REG_ARG_1); // arg1 = import name emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -1230,7 +1262,7 @@ STATIC void emit_native_import_from(emit_t *emit, qstr qst) { vtype_kind_t vtype_module; emit_access_stack(emit, 1, &vtype_module, REG_ARG_1); // arg1 = module assert(vtype_module == VTYPE_PYOBJ); - emit_call_with_imm_arg(emit, MP_F_IMPORT_FROM, qst, REG_ARG_2); // arg2 = import name + emit_call_with_qstr_arg(emit, MP_F_IMPORT_FROM, qst, REG_ARG_2); // arg2 = import name emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -1256,7 +1288,11 @@ STATIC void emit_native_import(emit_t *emit, qstr qst, int kind) { STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) { DEBUG_printf("load_const_tok(tok=%u)\n", tok); if (tok == MP_TOKEN_ELLIPSIS) { + #if MICROPY_PERSISTENT_CODE_SAVE + emit_native_load_const_obj(emit, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj)); + #else emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj)); + #endif } else { emit_native_pre(emit); if (tok == MP_TOKEN_KW_NONE) { @@ -1284,11 +1320,14 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) { } else */ { - emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_NEW_QSTR(qst)); + need_reg_single(emit, REG_TEMP0, 0); + emit_native_mov_reg_qstr_obj(emit, REG_TEMP0, qst); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_TEMP0); } } STATIC void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) { + emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; emit_native_pre(emit); need_reg_single(emit, REG_RET, 0); emit_load_reg_with_object(emit, REG_RET, obj); @@ -1347,13 +1386,13 @@ STATIC void emit_native_load_global(emit_t *emit, qstr qst, int kind) { if (emit->do_viper_types) { // check for builtin casting operators int native_type = mp_native_type_from_qstr(qst); - if (native_type >= MP_NATIVE_TYPE_INT) { + if (native_type >= MP_NATIVE_TYPE_BOOL) { emit_post_push_imm(emit, VTYPE_BUILTIN_CAST, native_type); return; } } } - emit_call_with_imm_arg(emit, MP_F_LOAD_NAME + kind, qst, REG_ARG_1); + emit_call_with_qstr_arg(emit, MP_F_LOAD_NAME + kind, qst, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -1365,7 +1404,7 @@ STATIC void emit_native_load_attr(emit_t *emit, qstr qst) { vtype_kind_t vtype_base; emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base assert(vtype_base == VTYPE_PYOBJ); - emit_call_with_imm_arg(emit, MP_F_LOAD_ATTR, qst, REG_ARG_2); // arg2 = attribute name + emit_call_with_qstr_arg(emit, MP_F_LOAD_ATTR, qst, REG_ARG_2); // arg2 = attribute name emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -1373,13 +1412,13 @@ STATIC void emit_native_load_method(emit_t *emit, qstr qst, bool is_super) { if (is_super) { emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, 3); // arg2 = dest ptr emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, 2); // arg2 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_SUPER_METHOD, qst, REG_ARG_1); // arg1 = method name + emit_call_with_qstr_arg(emit, MP_F_LOAD_SUPER_METHOD, qst, REG_ARG_1); // arg1 = method name } else { vtype_kind_t vtype_base; emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base assert(vtype_base == VTYPE_PYOBJ); emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name + emit_call_with_qstr_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name } } @@ -1586,7 +1625,7 @@ STATIC void emit_native_store_global(emit_t *emit, qstr qst, int kind) { ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_RET); } } - emit_call_with_imm_arg(emit, MP_F_STORE_NAME + kind, qst, REG_ARG_1); // arg1 = name + emit_call_with_qstr_arg(emit, MP_F_STORE_NAME + kind, qst, REG_ARG_1); // arg1 = name emit_post(emit); } @@ -1595,7 +1634,7 @@ STATIC void emit_native_store_attr(emit_t *emit, qstr qst) { emit_pre_pop_reg_reg(emit, &vtype_base, REG_ARG_1, &vtype_val, REG_ARG_3); // arg1 = base, arg3 = value assert(vtype_base == VTYPE_PYOBJ); assert(vtype_val == VTYPE_PYOBJ); - emit_call_with_imm_arg(emit, MP_F_STORE_ATTR, qst, REG_ARG_2); // arg2 = attribute name + emit_call_with_qstr_arg(emit, MP_F_STORE_ATTR, qst, REG_ARG_2); // arg2 = attribute name emit_post(emit); } @@ -1792,7 +1831,7 @@ STATIC void emit_native_delete_global(emit_t *emit, qstr qst, int kind) { MP_STATIC_ASSERT(MP_F_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_F_DELETE_NAME); MP_STATIC_ASSERT(MP_F_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_F_DELETE_GLOBAL); emit_native_pre(emit); - emit_call_with_imm_arg(emit, MP_F_DELETE_NAME + kind, qst, REG_ARG_1); + emit_call_with_qstr_arg(emit, MP_F_DELETE_NAME + kind, qst, REG_ARG_1); emit_post(emit); } @@ -1800,7 +1839,8 @@ STATIC void emit_native_delete_attr(emit_t *emit, qstr qst) { vtype_kind_t vtype_base; emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base assert(vtype_base == VTYPE_PYOBJ); - emit_call_with_2_imm_args(emit, MP_F_STORE_ATTR, qst, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL, REG_ARG_3); // arg2 = attribute name, arg3 = value (null for delete) + ASM_XOR_REG_REG(emit->as, REG_ARG_3, REG_ARG_3); // arg3 = value (null for delete) + emit_call_with_qstr_arg(emit, MP_F_STORE_ATTR, qst, REG_ARG_2); // arg2 = attribute name emit_post(emit); } @@ -1955,7 +1995,7 @@ STATIC void emit_native_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t exc prev_finally->unwind_label = UNWIND_LABEL_DO_FINAL_UNWIND; ASM_MOV_REG_PCREL(emit->as, REG_RET, label & ~MP_EMIT_BREAK_FROM_FOR); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_RET); - // Cancel any active exception (see also emit_native_pop_except) + // Cancel any active exception (see also emit_native_pop_except_jump) emit_native_mov_reg_const(emit, REG_RET, MP_F_CONST_NONE_OBJ); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_RET); // Jump to the innermost active finally @@ -1974,7 +2014,7 @@ STATIC void emit_native_setup_with(emit_t *emit, mp_uint_t label) { emit_access_stack(emit, 1, &vtype, REG_ARG_1); // arg1 = ctx_mgr assert(vtype == VTYPE_PYOBJ); emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___exit__, REG_ARG_2); + emit_call_with_qstr_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___exit__, REG_ARG_2); // stack: (..., ctx_mgr, __exit__, self) emit_pre_pop_reg(emit, &vtype, REG_ARG_3); // self @@ -1987,7 +2027,7 @@ STATIC void emit_native_setup_with(emit_t *emit, mp_uint_t label) { // get __enter__ method emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___enter__, REG_ARG_2); // arg2 = method name + emit_call_with_qstr_arg(emit, MP_F_LOAD_METHOD, MP_QSTR___enter__, REG_ARG_2); // arg2 = method name // stack: (..., __exit__, self, __enter__, self) // call __enter__ method @@ -2133,12 +2173,12 @@ STATIC void emit_native_for_iter(emit_t *emit, mp_uint_t label) { emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_1, MP_OBJ_ITER_BUF_NSLOTS); adjust_stack(emit, MP_OBJ_ITER_BUF_NSLOTS); emit_call(emit, MP_F_NATIVE_ITERNEXT); - #ifdef NDEBUG - MP_STATIC_ASSERT(MP_OBJ_STOP_ITERATION == 0); - ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, label, false); - #else + #if MICROPY_DEBUG_MP_OBJ_SENTINELS ASM_MOV_REG_IMM(emit->as, REG_TEMP1, (mp_uint_t)MP_OBJ_STOP_ITERATION); ASM_JUMP_IF_REG_EQ(emit->as, REG_RET, REG_TEMP1, label); + #else + MP_STATIC_ASSERT(MP_OBJ_STOP_ITERATION == 0); + ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, label, false); #endif emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -2150,18 +2190,15 @@ STATIC void emit_native_for_iter_end(emit_t *emit) { emit_post(emit); } -STATIC void emit_native_pop_block(emit_t *emit) { - emit_native_pre(emit); - if (!emit->exc_stack[emit->exc_stack_size - 1].is_finally) { +STATIC void emit_native_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { + if (within_exc_handler) { + // Cancel any active exception so subsequent handlers don't see it + emit_native_mov_reg_const(emit, REG_TEMP0, MP_F_CONST_NONE_OBJ); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + } else { emit_native_leave_exc_stack(emit, false); } - emit_post(emit); -} - -STATIC void emit_native_pop_except(emit_t *emit) { - // Cancel any active exception so subsequent handlers don't see it - emit_native_mov_reg_const(emit, REG_TEMP0, MP_F_CONST_NONE_OBJ); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + emit_native_jump(emit, label); } STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) { @@ -2220,17 +2257,16 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { int reg_rhs = REG_ARG_3; emit_pre_pop_reg_flexible(emit, &vtype_rhs, ®_rhs, REG_RET, REG_ARG_2); emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2); - if (0) { - // dummy #if !(N_X64 || N_X86) - } else if (op == MP_BINARY_OP_LSHIFT) { + if (op == MP_BINARY_OP_LSHIFT) { ASM_LSL_REG_REG(emit->as, REG_ARG_2, reg_rhs); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); } else if (op == MP_BINARY_OP_RSHIFT) { ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); + } else #endif - } else if (op == MP_BINARY_OP_OR) { + if (op == MP_BINARY_OP_OR) { ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs); emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2); } else if (op == MP_BINARY_OP_XOR) { @@ -2613,6 +2649,7 @@ STATIC void emit_native_return_value(emit_t *emit) { } STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) { + (void)n_args; assert(n_args == 1); vtype_kind_t vtype_exc; emit_pre_pop_reg(emit, &vtype_exc, REG_ARG_1); // arg1 = object to raise @@ -2719,6 +2756,11 @@ STATIC void emit_native_end_except_handler(emit_t *emit) { } const emit_method_table_t EXPORT_FUN(method_table) = { + #if MICROPY_DYNAMIC_COMPILER + EXPORT_FUN(new), + EXPORT_FUN(free), + #endif + emit_native_start_pass, emit_native_end_pass, emit_native_last_emit_was_return_value, @@ -2764,8 +2806,7 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_get_iter, emit_native_for_iter, emit_native_for_iter_end, - emit_native_pop_block, - emit_native_pop_except, + emit_native_pop_except_jump, emit_native_unary_op, emit_native_binary_op, emit_native_build, diff --git a/py/enum.c b/py/enum.c index 8dc83a9fba..5e77f42827 100644 --- a/py/enum.c +++ b/py/enum.c @@ -39,7 +39,7 @@ mp_obj_t cp_enum_find(const mp_obj_type_t *type, int value) { } int cp_enum_value(const mp_obj_type_t *type, mp_obj_t *obj) { - if (!MP_OBJ_IS_TYPE(obj, type)) { + if (!mp_obj_is_type(obj, type)) { mp_raise_TypeError_varg(translate("Expected a %q"), type->name); } return ((cp_enum_obj_t *)MP_OBJ_TO_PTR(obj))->value; diff --git a/py/frozenmod.h b/py/frozenmod.h index 668b7ac17e..51c86f29f8 100644 --- a/py/frozenmod.h +++ b/py/frozenmod.h @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2015 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/gc.c b/py/gc.c index c29624c3af..003ab6c30f 100644 --- a/py/gc.c +++ b/py/gc.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c index 8ee8a4a4e1..df3f72e3cd 100644 --- a/py/gc_long_lived.c +++ b/py/gc_long_lived.c @@ -46,8 +46,8 @@ mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_dep // Try to detect raw code. mp_raw_code_t *raw_code = MP_OBJ_TO_PTR(fun_bc->const_table[i]); if (raw_code->kind == MP_CODE_BYTECODE) { - raw_code->data.u_byte.bytecode = gc_make_long_lived((byte *)raw_code->data.u_byte.bytecode); - raw_code->data.u_byte.const_table = gc_make_long_lived((byte *)raw_code->data.u_byte.const_table); + raw_code->fun_data = gc_make_long_lived((byte *)raw_code->fun_data); + raw_code->const_table = gc_make_long_lived((byte *)raw_code->const_table); } ((mp_uint_t *)fun_bc->const_table)[i] = (mp_uint_t)make_obj_long_lived( (mp_obj_t)fun_bc->const_table[i], max_depth - 1); @@ -62,7 +62,7 @@ mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_dep if (fun_bc->extra_args[i] == NULL) { continue; } - if (MP_OBJ_IS_TYPE(fun_bc->extra_args[i], &mp_type_dict)) { + if (mp_obj_is_type(fun_bc->extra_args[i], &mp_type_dict)) { fun_bc->extra_args[i] = make_dict_long_lived(fun_bc->extra_args[i], max_depth - 1); } else { fun_bc->extra_args[i] = make_obj_long_lived(fun_bc->extra_args[i], max_depth - 1); @@ -103,7 +103,7 @@ mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) { // copies. dict->map.table = gc_make_long_lived(dict->map.table); for (size_t i = 0; i < dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { + if (mp_map_slot_is_filled(&dict->map, i)) { mp_obj_t value = dict->map.table[i].value; dict->map.table[i].value = make_obj_long_lived(value, max_depth - 1); } @@ -131,16 +131,16 @@ mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth) { if (!VERIFY_PTR((void *)obj)) { return obj; } - if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) { + if (mp_obj_is_type(obj, &mp_type_fun_bc)) { mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj); return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth)); - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_property)) { + } else if (mp_obj_is_type(obj, &mp_type_property)) { mp_obj_property_t *prop = MP_OBJ_TO_PTR(obj); return MP_OBJ_FROM_PTR(make_property_long_lived(prop, max_depth)); - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_str) || MP_OBJ_IS_TYPE(obj, &mp_type_bytes)) { + } else if (mp_obj_is_type(obj, &mp_type_str) || mp_obj_is_type(obj, &mp_type_bytes)) { mp_obj_str_t *str = MP_OBJ_TO_PTR(obj); return MP_OBJ_FROM_PTR(make_str_long_lived(str)); - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) { + } else if (mp_obj_is_type(obj, &mp_type_type)) { // Types are already long lived during creation. return obj; } else { diff --git a/py/makemoduledefs.py b/py/makemoduledefs.py index 7745607131..e20bff1eb0 100644 --- a/py/makemoduledefs.py +++ b/py/makemoduledefs.py @@ -8,6 +8,7 @@ from __future__ import print_function import re +import io import os import argparse @@ -46,7 +47,7 @@ def find_module_registrations(c_file): # No c file to match the object file, skip return set() - with open(c_file) as c_file_obj: + with io.open(c_file, encoding="utf-8") as c_file_obj: return set(re.findall(pattern, c_file_obj.read())) @@ -60,6 +61,7 @@ def generate_module_table_header(modules): # Print header file for all external modules. mod_defs = [] print("// Automatically generated by makemoduledefs.py.\n") + print("#include \"py/mpconfig.h\"") for module_name, obj_module, enabled_define in modules: mod_def = "MODULE_DEF_{}".format(module_name.upper()) mod_defs.append(mod_def) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 6a6125fe20..40942ed106 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -82,6 +82,176 @@ C_ESCAPES = { '"': '\\"', } +# static qstrs, should be sorted +# These are qstrs that are always included and always have the same number. It allows mpy files to omit them. +static_qstr_list = [ + "", + "__dir__", # Put __dir__ after empty qstr for builtin dir() to work + "\n", + " ", + "*", + "/", + "", + "_", + "__call__", + "__class__", + "__delitem__", + "__enter__", + "__exit__", + "__getattr__", + "__getitem__", + "__hash__", + "__init__", + "__int__", + "__iter__", + "__len__", + "__main__", + "__module__", + "__name__", + "__new__", + "__next__", + "__qualname__", + "__repr__", + "__setitem__", + "__str__", + "ArithmeticError", + "AssertionError", + "AttributeError", + "BaseException", + "EOFError", + "Ellipsis", + "Exception", + "GeneratorExit", + "ImportError", + "IndentationError", + "IndexError", + "KeyError", + "KeyboardInterrupt", + "LookupError", + "MemoryError", + "NameError", + "NoneType", + "NotImplementedError", + "OSError", + "OverflowError", + "RuntimeError", + "StopIteration", + "SyntaxError", + "SystemExit", + "TypeError", + "ValueError", + "ZeroDivisionError", + "abs", + "all", + "any", + "append", + "args", + "bool", + "builtins", + "bytearray", + "bytecode", + "bytes", + "callable", + "chr", + "classmethod", + "clear", + "close", + "const", + "copy", + "count", + "dict", + "dir", + "divmod", + "end", + "endswith", + "eval", + "exec", + "extend", + "find", + "format", + "from_bytes", + "get", + "getattr", + "globals", + "hasattr", + "hash", + "id", + "index", + "insert", + "int", + "isalpha", + "isdigit", + "isinstance", + "islower", + "isspace", + "issubclass", + "isupper", + "items", + "iter", + "join", + "key", + "keys", + "len", + "list", + "little", + "locals", + "lower", + "lstrip", + "main", + "map", + "micropython", + "next", + "object", + "open", + "ord", + "pop", + "popitem", + "pow", + "print", + "range", + "read", + "readinto", + "readline", + "remove", + "replace", + "repr", + "reverse", + "rfind", + "rindex", + "round", + "rsplit", + "rstrip", + "self", + "send", + "sep", + "set", + "setattr", + "setdefault", + "sort", + "sorted", + "split", + "start", + "startswith", + "staticmethod", + "step", + "stop", + "str", + "strip", + "sum", + "super", + "throw", + "to_bytes", + "tuple", + "type", + "update", + "upper", + "utf-8", + "value", + "values", + "write", + "zip", +] + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): hash = 5381 @@ -385,10 +555,23 @@ def qstr_escape(qst): def parse_input_headers(infiles): - # read the qstrs in from the input files qcfgs = {} qstrs = {} i18ns = set() + + # add static qstrs + for qstr in static_qstr_list: + # work out the corresponding qstr name + ident = qstr_escape(qstr) + + # don't add duplicates + assert ident not in qstrs + + # add the qstr to the list, with order number to retain original order in file + order = len(qstrs) - 300000 + qstrs[ident] = (order, ident, qstr) + + # read the qstrs in from the input files for infile in infiles: with open(infile, "rt") as f: for line in f: @@ -486,6 +669,7 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns): for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): qbytes = make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr) print("QDEF(MP_QSTR_%s, %s)" % (ident, qbytes)) + total_qstr_size += len(qstr) total_text_size = 0 @@ -531,6 +715,7 @@ def print_qstr_enums(qstrs): print("QENUM(MP_QSTR_%s)" % (ident,)) + if __name__ == "__main__": import argparse diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index e6c0033113..c143a0bedc 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -9,6 +9,7 @@ from __future__ import print_function import re import sys +import io import os # Python 2/3 compatibility: @@ -175,7 +176,7 @@ if __name__ == "__main__": pass if args.command == "split": - with open(args.input_filename) as infile: + with io.open(args.input_filename, encoding="utf-8") as infile: process_file(infile) if args.command == "cat": diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index 41e5956542..1ab15ecd95 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -65,6 +65,7 @@ def get_version_info_from_git(): return git_tag, git_hash, ver + def get_version_info_from_docs_conf(): with open(os.path.join(os.path.dirname(sys.argv[0]), "..", "conf.py")) as f: for line in f: diff --git a/py/map.c b/py/map.c index 06695c8de8..2f2c11c639 100644 --- a/py/map.c +++ b/py/map.c @@ -152,9 +152,9 @@ mp_map_elem_t *PLACE_IN_ITCM(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_m // Work out if we can compare just pointers bool compare_only_ptrs = map->all_keys_are_qstrs; if (compare_only_ptrs) { - if (MP_OBJ_IS_QSTR(index)) { + if (mp_obj_is_qstr(index)) { // Index is a qstr, so can just do ptr comparison. - } else if (MP_OBJ_IS_TYPE(index, &mp_type_str)) { + } else if (mp_obj_is_type(index, &mp_type_str)) { // Index is a non-interned string. // We can either intern the string, or force a full equality comparison. // We chose the latter, since interning costs time and potentially RAM, @@ -199,7 +199,7 @@ mp_map_elem_t *PLACE_IN_ITCM(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_m } mp_map_elem_t *elem = map->table + map->used++; elem->key = index; - if (!MP_OBJ_IS_QSTR(index)) { + if (!mp_obj_is_qstr(index)) { map->all_keys_are_qstrs = 0; } return elem; @@ -220,7 +220,7 @@ mp_map_elem_t *PLACE_IN_ITCM(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_m // get hash of index, with fast path for common case of qstr mp_uint_t hash; - if (MP_OBJ_IS_QSTR(index)) { + if (mp_obj_is_qstr(index)) { hash = qstr_hash(MP_OBJ_QSTR_VALUE(index)); } else { hash = MP_OBJ_SMALL_INT_VALUE(mp_unary_op(MP_UNARY_OP_HASH, index)); @@ -240,7 +240,7 @@ mp_map_elem_t *PLACE_IN_ITCM(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_m } avail_slot->key = index; avail_slot->value = MP_OBJ_NULL; - if (!MP_OBJ_IS_QSTR(index)) { + if (!mp_obj_is_qstr(index)) { map->all_keys_are_qstrs = 0; } return avail_slot; @@ -280,7 +280,7 @@ mp_map_elem_t *PLACE_IN_ITCM(mp_map_lookup)(mp_map_t * map, mp_obj_t index, mp_m map->used++; avail_slot->key = index; avail_slot->value = MP_OBJ_NULL; - if (!MP_OBJ_IS_QSTR(index)) { + if (!mp_obj_is_qstr(index)) { map->all_keys_are_qstrs = 0; } return avail_slot; @@ -397,7 +397,7 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t looku mp_obj_t mp_set_remove_first(mp_set_t *set) { for (size_t pos = 0; pos < set->alloc; pos++) { - if (MP_SET_SLOT_IS_FILLED(set, pos)) { + if (mp_set_slot_is_filled(set, pos)) { mp_obj_t elem = set->table[pos]; // delete element set->used--; diff --git a/py/misc.h b/py/misc.h index cb7192a56f..1d107f6d96 100644 --- a/py/misc.h +++ b/py/misc.h @@ -49,8 +49,8 @@ typedef unsigned int uint; #endif // Classical double-indirection stringification of preprocessor macro's value -#define _MP_STRINGIFY(x) #x -#define MP_STRINGIFY(x) _MP_STRINGIFY(x) +#define MP_STRINGIFY_HELPER(x) #x +#define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) // Static assertion macro #define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)])) diff --git a/py/mkenv.mk b/py/mkenv.mk index 7e99f59c10..80f9b4eac1 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -44,6 +44,7 @@ BUILD ?= build ECHO = @echo +CAT = cat CD = cd CP = cp FIND = find @@ -55,6 +56,7 @@ PYTHON3 ?= python3 RM = rm RSYNC = rsync SED = sed +TOUCH = touch # Linux has 'nproc', macOS has 'sysctl -n hw.logicalcpu', this is cross-platform NPROC = $(PYTHON3) -c 'import multiprocessing as mp; print(mp.cpu_count())' diff --git a/py/mkrules.mk b/py/mkrules.mk index 2721d293e0..d05f28bf40 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -79,7 +79,7 @@ $(OBJ): | $(HEADER_BUILD)/qstrdefs.enum.h $(HEADER_BUILD)/mpversion.h $(HEADER_BUILD)/qstr.split: $(SRC_QSTR) $(SRC_QSTR_PREPROCESSOR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h $(PY_SRC)/genlast.py $(STEPECHO) "GEN $@" $(Q)$(PYTHON3) $(PY_SRC)/genlast.py $(HEADER_BUILD)/qstr $(if $(filter $?,$(QSTR_GLOBAL_DEPENDENCIES)),$^,$(if $?,$?,$^)) -- $(SRC_QSTR_PREPROCESSOR) -- $(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) - $(Q)touch $@ + $(Q)$(TOUCH) $@ $(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split $(PY_SRC)/makeqstrdefs.py $(STEPECHO) "GEN $@" @@ -197,7 +197,7 @@ print-cfg: print-def: @$(ECHO) "The following defines are built into the $(CC) compiler" - touch __empty__.c + $(TOUCH) __empty__.c @$(CC) -E -Wp,-dM __empty__.c @$(RM) -f __empty__.c diff --git a/py/modarray.c b/py/modarray.c index a47684bf97..daae34662b 100644 --- a/py/modarray.c +++ b/py/modarray.c @@ -40,4 +40,6 @@ const mp_obj_module_t mp_module_array = { .globals = (mp_obj_dict_t *)&mp_module_array_globals, }; +MP_REGISTER_MODULE(MP_QSTR_array, mp_module_array, MICROPY_PY_ARRAY); + #endif diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 49d88f728e..3b962e678e 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -181,7 +181,7 @@ STATIC mp_obj_t mp_builtin_dir(size_t n_args, const mp_obj_t *args) { // Make a list of names in the local namespace mp_obj_dict_t *dict = mp_locals_get(); for (size_t i = 0; i < dict->map.alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { + if (mp_map_slot_is_filled(&dict->map, i)) { mp_obj_list_append(dir, dict->map.table[i].key); } } @@ -319,6 +319,22 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_min_obj, 1, mp_builtin_min); #endif +#if MICROPY_PY_BUILTINS_NEXT2 +STATIC mp_obj_t mp_builtin_next(size_t n_args, const mp_obj_t *args) { + if (n_args == 1) { + mp_obj_t ret = mp_iternext_allow_raise(args[0]); + if (ret == MP_OBJ_STOP_ITERATION) { + nlr_raise(mp_obj_new_exception(&mp_type_StopIteration)); + } else { + return ret; + } + } else { + mp_obj_t ret = mp_iternext(args[0]); + return ret == MP_OBJ_STOP_ITERATION ? args[1] : ret; + } +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_next_obj, 1, 2, mp_builtin_next); +#else STATIC mp_obj_t mp_builtin_next(mp_obj_t o) { mp_obj_t ret = mp_iternext_allow_raise(o); if (ret == MP_OBJ_STOP_ITERATION) { @@ -328,6 +344,7 @@ STATIC mp_obj_t mp_builtin_next(mp_obj_t o) { } } MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next); +#endif STATIC mp_obj_t mp_builtin_oct(mp_obj_t o_in) { #if MICROPY_PY_BUILTINS_STR_OP_MODULO @@ -343,7 +360,7 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) { size_t len; const byte *str = (const byte *)mp_obj_str_get_data(o_in, &len); #if MICROPY_PY_BUILTINS_STR_UNICODE - if (MP_OBJ_IS_STR(o_in)) { + if (mp_obj_is_str(o_in)) { len = utf8_charlen(str, len); if (len == 1) { return mp_obj_new_int(utf8_get_char(str)); @@ -462,7 +479,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr); STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) { mp_obj_t o_in = args[0]; - if (MP_OBJ_IS_INT(o_in)) { + if (mp_obj_is_int(o_in)) { if (n_args <= 1) { return o_in; } diff --git a/py/modio.c b/py/modio.c index e88a9b04f3..9585ed021a 100644 --- a/py/modio.c +++ b/py/modio.c @@ -148,6 +148,7 @@ STATIC mp_uint_t bufwriter_write(mp_obj_t self_in, const void *buf, mp_uint_t si buf = (byte *)buf + rem; size -= rem; mp_uint_t out_sz = mp_stream_write_exactly(self->stream, self->buf, self->alloc, errcode); + (void)out_sz; if (*errcode != 0) { return MP_STREAM_ERROR; } @@ -166,6 +167,7 @@ STATIC mp_obj_t bufwriter_flush(mp_obj_t self_in) { if (self->len != 0) { int err; mp_uint_t out_sz = mp_stream_write_exactly(self->stream, self->buf, self->len, &err); + (void)out_sz; // TODO: try to recover from a case of non-blocking stream, e.g. move // remaining chunk to the beginning of buffer. assert(out_sz == self->len); diff --git a/py/modmath.c b/py/modmath.c index 9df345a564..206d6057fd 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -171,7 +171,7 @@ MATH_FUN_1(gamma, tgamma) // lgamma(x): return the natural logarithm of the gamma function of x MATH_FUN_1(lgamma, lgamma) #endif -// TODO: factorial, fsum +// TODO: fsum // Function that takes a variable number of arguments diff --git a/py/modthread.c b/py/modthread.c index 89b4f3fb66..84b12f7fb1 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -244,7 +244,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) th_args->n_kw = map->used; // copy across the keyword arguments for (size_t i = 0, n = pos_args_len; i < map->alloc; ++i) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { th_args->args[n++] = map->table[i].key; th_args->args[n++] = map->table[i].value; } diff --git a/py/moduerrno.c b/py/moduerrno.c index 6ead6a8054..e8a3bb9b97 100644 --- a/py/moduerrno.c +++ b/py/moduerrno.c @@ -142,7 +142,7 @@ const char *mp_errno_to_str(mp_obj_t errno_val) { // For commonly encountered errors, return human readable strings, otherwise try errno name const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len) { - if (!MP_OBJ_IS_SMALL_INT(errno_val)) { + if (!mp_obj_is_small_int(errno_val)) { return NULL; } diff --git a/py/mpconfig.h b/py/mpconfig.h index 6badacaf6c..8172510008 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -358,6 +358,11 @@ #define MICROPY_COMP_CONST_FOLDING (1) #endif +// Whether to enable optimisations for constant literals, eg OrderedDict +#ifndef MICROPY_COMP_CONST_LITERAL +#define MICROPY_COMP_CONST_LITERAL (1) +#endif + // Whether to enable lookup of constants in modules; eg module.CONST #ifndef MICROPY_COMP_MODULE_CONST #define MICROPY_COMP_MODULE_CONST (0) @@ -416,6 +421,11 @@ #define MICROPY_DEBUG_VERBOSE (0) #endif +// Whether to enable debugging versions of MP_OBJ_NULL/STOP_ITERATION/SENTINEL +#ifndef MICROPY_DEBUG_MP_OBJ_SENTINELS +#define MICROPY_DEBUG_MP_OBJ_SENTINELS (0) +#endif + // Whether to enable a simple VM stack overflow check #ifndef MICROPY_DEBUG_VM_STACK_OVERFLOW #define MICROPY_DEBUG_VM_STACK_OVERFLOW (0) @@ -479,6 +489,11 @@ #define MICROPY_READER_VFS (0) #endif +// Whether any readers have been defined +#ifndef MICROPY_HAS_FILE_READER +#define MICROPY_HAS_FILE_READER (MICROPY_READER_POSIX || MICROPY_READER_VFS) +#endif + // Number of VFS mounts to persist across soft-reset. #ifndef MICROPY_FATFS_NUM_PERSISTENT #define MICROPY_FATFS_NUM_PERSISTENT (0) @@ -618,6 +633,11 @@ typedef long long mp_longint_impl_t; #define MICROPY_WARNINGS (0) #endif +// Whether to support warning categories +#ifndef MICROPY_WARNINGS_CATEGORY +#define MICROPY_WARNINGS_CATEGORY (0) +#endif + // This macro is used when printing runtime warnings and errors #ifndef MICROPY_ERROR_PRINTER #define MICROPY_ERROR_PRINTER (&mp_plat_print) @@ -861,6 +881,11 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_MEMORYVIEW (0) #endif +// Whether to support memoryview.itemsize attribute +#ifndef MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE +#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (0) +#endif + // Whether to support set object #ifndef MICROPY_PY_BUILTINS_SET #define MICROPY_PY_BUILTINS_SET (1) @@ -901,16 +926,16 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_RANGE_BINOP (0) #endif +// Support for callling next() with second argument +#ifndef MICROPY_PY_BUILTINS_NEXT2 +#define MICROPY_PY_BUILTINS_NEXT2 (0) +#endif + // Whether to support rounding of integers (incl bignum); eg round(123,-1)=120 #ifndef MICROPY_PY_BUILTINS_ROUND_INT #define MICROPY_PY_BUILTINS_ROUND_INT (0) #endif -// Whether to support timeout exceptions (like socket.timeout) -#ifndef MICROPY_PY_BUILTINS_TIMEOUTERROR -#define MICROPY_PY_BUILTINS_TIMEOUTERROR (0) -#endif - // Whether to support complete set of special methods for user // classes, or only the most used ones. "Inplace" methods are // controlled by MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS below. @@ -1291,6 +1316,11 @@ typedef double mp_float_t; #define MICROPY_PY_UCRYPTOLIB (0) #endif +// Depends on MICROPY_PY_UCRYPTOLIB +#ifndef MICROPY_PY_UCRYPTOLIB_CTR +#define MICROPY_PY_UCRYPTOLIB_CTR (0) +#endif + #ifndef MICROPY_PY_UCRYPTOLIB_CONSTS #define MICROPY_PY_UCRYPTOLIB_CONSTS (0) #endif @@ -1336,8 +1366,8 @@ typedef double mp_float_t; #define MICROPY_PY_USSL_FINALISER (0) #endif -#ifndef MICROPY_PY_WEBSOCKET -#define MICROPY_PY_WEBSOCKET (0) +#ifndef MICROPY_PY_UWEBSOCKET +#define MICROPY_PY_UWEBSOCKET (0) #endif #ifndef MICROPY_PY_FRAMEBUF @@ -1371,17 +1401,17 @@ typedef double mp_float_t; /*****************************************************************************/ /* Hooks for a port to add builtins */ -// Additional builtin function definitions - see builtintables.c:builtin_object_table for format. +// Additional builtin function definitions - see modbuiltins.c:mp_module_builtins_globals_table for format. #ifndef MICROPY_PORT_BUILTINS #define MICROPY_PORT_BUILTINS #endif -// Additional builtin module definitions - see builtintables.c:builtin_module_table for format. +// Additional builtin module definitions - see objmodule.c:mp_builtin_module_table for format. #ifndef MICROPY_PORT_BUILTIN_MODULES #define MICROPY_PORT_BUILTIN_MODULES #endif -// Any module weak links - see builtintables.c:mp_builtin_module_weak_links_table. +// Any module weak links - see objmodule.c:mp_builtin_module_weak_links_table. #ifndef MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS #define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS #endif @@ -1562,4 +1592,15 @@ typedef double mp_float_t; #endif #endif +// Warning categories are by default implemented as strings, though +// hook is left for a port to define them as something else. +#if MICROPY_WARNINGS_CATEGORY +#ifndef MP_WARN_CAT +#define MP_WARN_CAT(x) #x +#endif +#else +#undef MP_WARN_CAT +#define MP_WARN_CAT(x) (NULL) +#endif + #endif // MICROPY_INCLUDED_PY_MPCONFIG_H diff --git a/py/mpprint.c b/py/mpprint.c index 032ce8e97b..1ba44279f7 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -207,7 +207,7 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char // If needed this function could be generalised to handle other values. assert(base == 2 || base == 8 || base == 10 || base == 16); - if (!MP_OBJ_IS_INT(x)) { + if (!mp_obj_is_int(x)) { // This will convert booleans to int, or raise an error for // non-integer types. x = MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(x)); @@ -505,22 +505,28 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { chrs += mp_print_strn(print, str, prec, flags, fill, width); break; } + case 'd': { + mp_int_t val; + if (long_arg) { + val = va_arg(args, long int); + } else { + val = va_arg(args, int); + } + chrs += mp_print_int(print, val, 1, 10, 'a', flags, fill, width); + break; + } case 'u': - chrs += mp_print_int(print, va_arg(args, unsigned int), 0, 10, 'a', flags, fill, width); - break; - case 'd': - chrs += mp_print_int(print, va_arg(args, int), 1, 10, 'a', flags, fill, width); - break; case 'x': case 'X': { - char fmt_c = *fmt - 'X' + 'A'; + int base = 16 - ((*fmt + 1) & 6); // maps char u/x/X to base 10/16/16 + char fmt_c = (*fmt & 0xf0) - 'P' + 'A'; // maps char u/x/X to char a/a/A mp_uint_t val; if (long_arg) { val = va_arg(args, unsigned long int); } else { val = va_arg(args, unsigned int); } - chrs += mp_print_int(print, val, 0, 16, fmt_c, flags, fill, width); + chrs += mp_print_int(print, val, 0, base, fmt_c, flags, fill, width); break; } case 'p': diff --git a/py/mpstate.h b/py/mpstate.h index 0c57563acc..ce26593fdb 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -46,6 +46,7 @@ typedef struct mp_dynamic_compiler_t { uint8_t small_int_bits; // must be <= host small_int_bits bool opt_cache_map_lookup_in_bytecode; bool py_builtins_str_unicode; + uint8_t native_arch; } mp_dynamic_compiler_t; extern mp_dynamic_compiler_t mp_dynamic_compiler; #endif @@ -217,7 +218,8 @@ typedef struct _mp_state_vm_t { #if MICROPY_ENABLE_SCHEDULER volatile int16_t sched_state; - uint16_t sched_sp; + uint8_t sched_len; + uint8_t sched_idx; #endif #if MICROPY_PY_THREAD_GIL diff --git a/py/nativeglue.c b/py/nativeglue.c index 7662aaeaf6..a3841efb1d 100644 --- a/py/nativeglue.c +++ b/py/nativeglue.c @@ -41,13 +41,37 @@ #if MICROPY_EMIT_NATIVE +int mp_native_type_from_qstr(qstr qst) { + switch (qst) { + case MP_QSTR_object: + return MP_NATIVE_TYPE_OBJ; + case MP_QSTR_bool: + return MP_NATIVE_TYPE_BOOL; + case MP_QSTR_int: + return MP_NATIVE_TYPE_INT; + case MP_QSTR_uint: + return MP_NATIVE_TYPE_UINT; + case MP_QSTR_ptr: + return MP_NATIVE_TYPE_PTR; + case MP_QSTR_ptr8: + return MP_NATIVE_TYPE_PTR8; + case MP_QSTR_ptr16: + return MP_NATIVE_TYPE_PTR16; + case MP_QSTR_ptr32: + return MP_NATIVE_TYPE_PTR32; + default: + return -1; + } +} + // convert a MicroPython object to a valid native value based on type -mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) { - DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type); +mp_uint_t mp_native_from_obj(mp_obj_t obj, mp_uint_t type) { + DEBUG_printf("mp_native_from_obj(%p, " UINT_FMT ")\n", obj, type); switch (type & 0xf) { case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj; case MP_NATIVE_TYPE_BOOL: + return mp_obj_is_true(obj); case MP_NATIVE_TYPE_INT: case MP_NATIVE_TYPE_UINT: return mp_obj_get_int_truncated(obj); @@ -68,8 +92,8 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) { #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM // convert a native value to a MicroPython object based on type -mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) { - DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type); +mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) { + DEBUG_printf("mp_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type); switch (type & 0xf) { case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val; @@ -184,8 +208,8 @@ const void *const mp_fun_table[MP_F_NUMBER_OF] = { &mp_const_none_obj, &mp_const_false_obj, &mp_const_true_obj, - mp_convert_obj_to_native, - mp_convert_native_to_obj, + mp_native_from_obj, + mp_native_to_obj, mp_native_swap_globals, mp_load_name, mp_load_global, diff --git a/py/obj.c b/py/obj.c index 6b2dded57e..dd0aa4e93e 100644 --- a/py/obj.c +++ b/py/obj.c @@ -44,9 +44,9 @@ #include "supervisor/shared/translate.h" mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) { - if (MP_OBJ_IS_SMALL_INT(o_in)) { + if (mp_obj_is_small_int(o_in)) { return (mp_obj_type_t *)&mp_type_int; - } else if (MP_OBJ_IS_QSTR(o_in)) { + } else if (mp_obj_is_qstr(o_in)) { return (mp_obj_type_t *)&mp_type_str; #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(o_in)) { @@ -144,7 +144,7 @@ bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) { return 1; } else if (arg == mp_const_none) { return 0; - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { if (MP_OBJ_SMALL_INT_VALUE(arg) == 0) { return 0; } else { @@ -199,7 +199,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { && !mp_obj_is_float(o1) #endif #if MICROPY_PY_BUILTINS_COMPLEX - && !MP_OBJ_IS_TYPE(o1, &mp_type_complex) + && !mp_obj_is_type(o1, &mp_type_complex) #endif ) { return true; @@ -209,8 +209,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { } // fast path for small ints - if (MP_OBJ_IS_SMALL_INT(o1)) { - if (MP_OBJ_IS_SMALL_INT(o2)) { + if (mp_obj_is_small_int(o1)) { + if (mp_obj_is_small_int(o2)) { // both SMALL_INT, and not equal if we get here return false; } else { @@ -223,20 +223,20 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { } // fast path for strings - if (MP_OBJ_IS_STR(o1)) { - if (MP_OBJ_IS_STR(o2)) { + if (mp_obj_is_str(o1)) { + if (mp_obj_is_str(o2)) { // both strings, use special function return mp_obj_str_equal(o1, o2); } else { // a string is never equal to anything else goto str_cmp_err; } - } else if (MP_OBJ_IS_STR(o2)) { + } else if (mp_obj_is_str(o2)) { // o1 is not a string (else caught above), so the objects are not equal str_cmp_err: #if MICROPY_PY_STR_BYTES_CMP_WARN - if (MP_OBJ_IS_TYPE(o1, &mp_type_bytes) || MP_OBJ_IS_TYPE(o2, &mp_type_bytes)) { - mp_warning("Comparison between bytes and str"); + if (mp_obj_is_type(o1, &mp_type_bytes) || mp_obj_is_type(o2, &mp_type_bytes)) { + mp_warning(MP_WARN_CAT(BytesWarning), "Comparison between bytes and str"); } #endif return false; @@ -264,9 +264,9 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { return 0; } else if (arg == mp_const_true) { return 1; - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { return MP_OBJ_SMALL_INT_VALUE(arg); - } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { + } else if (mp_obj_is_type(arg, &mp_type_int)) { return mp_obj_int_get_checked(arg); } else { mp_obj_t res = mp_unary_op(MP_UNARY_OP_INT, (mp_obj_t)arg); @@ -275,7 +275,7 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { } mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg) { - if (MP_OBJ_IS_INT(arg)) { + if (mp_obj_is_int(arg)) { return mp_obj_int_get_truncated(arg); } else { return mp_obj_get_int(arg); @@ -290,9 +290,9 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) { *value = 0; } else if (arg == mp_const_true) { *value = 1; - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { *value = MP_OBJ_SMALL_INT_VALUE(arg); - } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { + } else if (mp_obj_is_type(arg, &mp_type_int)) { *value = mp_obj_int_get_checked(arg); } else { return false; @@ -308,10 +308,10 @@ bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) { val = 0; } else if (arg == mp_const_true) { val = 1; - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { val = MP_OBJ_SMALL_INT_VALUE(arg); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { + } else if (mp_obj_is_type(arg, &mp_type_int)) { val = mp_obj_int_as_float_impl(arg); #endif } else if (mp_obj_is_float(arg)) { @@ -347,18 +347,18 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { } else if (arg == mp_const_true) { *real = 1; *imag = 0; - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { *real = MP_OBJ_SMALL_INT_VALUE(arg); *imag = 0; #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { + } else if (mp_obj_is_type(arg, &mp_type_int)) { *real = mp_obj_int_as_float_impl(arg); *imag = 0; #endif } else if (mp_obj_is_float(arg)) { *real = mp_obj_float_get(arg); *imag = 0; - } else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) { + } else if (mp_obj_is_type(arg, &mp_type_complex)) { mp_obj_complex_get(arg, real, imag); } else { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE @@ -374,9 +374,9 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { // note: returned value in *items may point to the interior of a GC block void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { - if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { + if (mp_obj_is_type(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); - } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { + } else if (mp_obj_is_type(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE @@ -405,7 +405,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { // is_slice determines whether the index is a slice index size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice) { mp_int_t i; - if (MP_OBJ_IS_SMALL_INT(index)) { + if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE @@ -443,7 +443,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool mp_obj_t mp_obj_id(mp_obj_t o_in) { mp_int_t id = (mp_int_t)o_in; - if (!MP_OBJ_IS_OBJ(o_in)) { + if (!mp_obj_is_obj(o_in)) { return mp_obj_new_int(id); } else if (id >= 0) { // Many OSes and CPUs have affinity for putting "user" memories @@ -479,9 +479,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { if ( #if !MICROPY_PY_BUILTINS_STR_UNICODE // It's simple - unicode is slow, non-unicode is fast - MP_OBJ_IS_STR(o_in) || + mp_obj_is_str(o_in) || #endif - MP_OBJ_IS_TYPE(o_in, &mp_type_bytes)) { + mp_obj_is_type(o_in, &mp_type_bytes)) { GET_STR_LEN(o_in, l); return MP_OBJ_NEW_SMALL_INT(l); } else { diff --git a/py/obj.h b/py/obj.h index 4e32ce8b0e..b7d7bdfd7f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -69,14 +69,14 @@ typedef struct _mp_obj_base_t mp_obj_base_t; // For debugging purposes they are all different. For non-debug mode, we alias // as many as we can to MP_OBJ_NULL because it's cheaper to load/compare 0. -#ifdef NDEBUG -#define MP_OBJ_NULL (MP_OBJ_FROM_PTR((void *)0)) -#define MP_OBJ_STOP_ITERATION (MP_OBJ_FROM_PTR((void *)0)) -#define MP_OBJ_SENTINEL (MP_OBJ_FROM_PTR((void *)4)) -#else +#if MICROPY_DEBUG_MP_OBJ_SENTINELS #define MP_OBJ_NULL (MP_OBJ_FROM_PTR((void *)0)) #define MP_OBJ_STOP_ITERATION (MP_OBJ_FROM_PTR((void *)4)) #define MP_OBJ_SENTINEL (MP_OBJ_FROM_PTR((void *)8)) +#else +#define MP_OBJ_NULL (MP_OBJ_FROM_PTR((void *)0)) +#define MP_OBJ_STOP_ITERATION (MP_OBJ_FROM_PTR((void *)0)) +#define MP_OBJ_SENTINEL (MP_OBJ_FROM_PTR((void *)4)) #endif // These macros/inline functions operate on objects and depend on the @@ -85,13 +85,13 @@ typedef struct _mp_obj_base_t mp_obj_base_t; #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A -static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) { +static inline bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1)) -static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { +static inline bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 2; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2) @@ -103,24 +103,24 @@ static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { extern const struct _mp_obj_float_t mp_const_float_e_obj; extern const struct _mp_obj_float_t mp_const_float_pi_obj; -#define mp_obj_is_float(o) MP_OBJ_IS_TYPE((o), &mp_type_float) +#define mp_obj_is_float(o) mp_obj_is_type((o), &mp_type_float) mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { +static inline bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B -static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) { +static inline bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 1; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 2) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 2) | 1)) -static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { +static inline bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 3; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2) @@ -132,18 +132,18 @@ static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { extern const struct _mp_obj_float_t mp_const_float_e_obj; extern const struct _mp_obj_float_t mp_const_float_pi_obj; -#define mp_obj_is_float(o) MP_OBJ_IS_TYPE((o), &mp_type_float) +#define mp_obj_is_float(o) mp_obj_is_type((o), &mp_type_float) mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { +static inline bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C -static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) { +static inline bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) @@ -172,25 +172,25 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { +static inline bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 0xff800007) == 0x00000006; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 0x00000006)) -static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { +static inline bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D -static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) { +static inline bool mp_obj_is_small_int(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0001000000000000; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)((o) << 16)) >> 17) #define MP_OBJ_NEW_SMALL_INT(small_int) (((((uint64_t)(small_int)) & 0x7fffffffffff) << 1) | 0x0001000000000001) -static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { +static inline bool mp_obj_is_qstr(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0002000000000000; } #define MP_OBJ_QSTR_VALUE(o) ((((uint32_t)(o)) >> 1) & 0xffffffff) @@ -224,7 +224,7 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { +static inline bool mp_obj_is_obj(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0000000000000000; } #define MP_OBJ_TO_PTR(o) ((void *)(uintptr_t)(o)) @@ -275,17 +275,6 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; */ #endif -// The macros below are derived from the ones above and are used to -// check for more specific object types. -// Note: these are kept as macros because inline functions sometimes use much -// more code space than the equivalent macros, depending on the compiler. - -#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type == (t))) // this does not work for checking int, str or fun; use below macros for that -#define MP_OBJ_IS_INT(o) (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int)) -#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str)) -#define MP_OBJ_IS_STR_OR_BYTES(o) (MP_OBJ_IS_QSTR(o) || (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) -#define MP_OBJ_IS_FUN(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) - // These macros are used to declare and define constant function objects // You can put "static" in front of the definitions to make them local @@ -433,7 +422,7 @@ typedef enum _mp_map_lookup_kind_t { extern const mp_map_t mp_const_empty_map; -static inline bool MP_MAP_SLOT_IS_FILLED(const mp_map_t *map, size_t pos) { +static inline bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { return (map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL; } @@ -454,7 +443,7 @@ typedef struct _mp_set_t { mp_obj_t *table; } mp_set_t; -static inline bool MP_SET_SLOT_IS_FILLED(const mp_set_t *set, size_t pos) { +static inline bool mp_set_slot_is_filled(const mp_set_t *set, size_t pos) { return (set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL; } @@ -700,6 +689,16 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; // General API for objects +// These macros are derived from more primitive ones and are used to +// check for more specific object types. +// Note: these are kept as macros because inline functions sometimes use much +// more code space than the equivalent macros, depending on the compiler. +#define mp_obj_is_type(o, t) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type == (t))) // this does not work for checking int, str or fun; use below macros for that +#define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_type(o, &mp_type_int)) +#define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_type(o, &mp_type_str)) +#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) +#define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) + mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_const_false; @@ -732,8 +731,8 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const comp mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list ap); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table); mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table); -mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig); -mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig); +mp_obj_t mp_obj_new_fun_viper(size_t n_args, const void *fun_data, mp_uint_t type_sig); +mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine); mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); @@ -762,7 +761,7 @@ bool mp_obj_is_callable(mp_obj_t o_in); bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); static inline bool mp_obj_is_integer(mp_const_obj_t o) { - return MP_OBJ_IS_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_bool); + return mp_obj_is_int(o) || mp_obj_is_type(o, &mp_type_bool); } // returns true if o is bool, small int or long int mp_int_t mp_obj_get_int(mp_const_obj_t arg); mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg); diff --git a/py/objarray.c b/py/objarray.c index 7864d79867..216b94b298 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -128,8 +128,8 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { if (((MICROPY_PY_BUILTINS_BYTEARRAY && typecode == BYTEARRAY_TYPECODE) || (MICROPY_PY_ARRAY - && (MP_OBJ_IS_TYPE(initializer, &mp_type_bytes) - || (MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(initializer, &mp_type_bytearray))))) + && (mp_obj_is_type(initializer, &mp_type_bytes) + || (MICROPY_PY_BUILTINS_BYTEARRAY && mp_obj_is_type(initializer, &mp_type_bytearray))))) && mp_get_buffer(initializer, &bufinfo, MP_BUFFER_READ)) { // construct array from raw bytes size_t sz = mp_binary_get_size('@', typecode, NULL); @@ -194,7 +194,7 @@ STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, if (n_args == 0) { // no args: construct an empty bytearray return MP_OBJ_FROM_PTR(array_new(BYTEARRAY_TYPECODE, 0)); - } else if (MP_OBJ_IS_INT(args[0])) { + } else if (mp_obj_is_int(args[0])) { // 1 arg, an integer: construct a blank bytearray of that length mp_uint_t len = mp_obj_get_int(args[0]); mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, len); @@ -261,6 +261,19 @@ STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_ } STATIC MP_DEFINE_CONST_FUN_OBJ_2(memoryview_cast_obj, memoryview_cast); #endif + +#if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE +STATIC void memoryview_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + if (dest[0] != MP_OBJ_NULL) { + return; + } + if (attr == MP_QSTR_itemsize) { + mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); + dest[0] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->typecode & TYPECODE_MASK, NULL)); + } +} +#endif + #endif STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { @@ -280,7 +293,7 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs switch (op) { case MP_BINARY_OP_MULTIPLY: case MP_BINARY_OP_INPLACE_MULTIPLY: { - if (!MP_OBJ_IS_INT(rhs_in)) { + if (!mp_obj_is_int(rhs_in)) { return MP_OBJ_NULL; // op not supported } mp_uint_t repeat = mp_obj_get_int(rhs_in); @@ -346,7 +359,7 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs mp_buffer_info_t lhs_bufinfo; mp_buffer_info_t rhs_bufinfo; if (mp_get_buffer(rhs_in, &rhs_bufinfo, MP_BUFFER_READ)) { - if (!MP_OBJ_IS_TYPE(lhs_in, &mp_type_bytearray)) { + if (!mp_obj_is_type(lhs_in, &mp_type_bytearray)) { return mp_const_false; } array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ); @@ -356,7 +369,7 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs #endif // Otherwise, can only look for a scalar numeric value in an array - if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) { + if (mp_obj_is_int(rhs_in) || mp_obj_is_float(rhs_in)) { mp_raise_NotImplementedError(NULL); } @@ -381,8 +394,8 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) { // self is not a memoryview, so we don't need to use (& TYPECODE_MASK) - assert((MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_bytearray)) - || (MICROPY_PY_ARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_array))); + assert((MICROPY_PY_BUILTINS_BYTEARRAY && mp_obj_is_type(self_in, &mp_type_bytearray)) + || (MICROPY_PY_ARRAY && mp_obj_is_type(self_in, &mp_type_array))); mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); if (self->free == 0) { @@ -402,8 +415,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_append_obj, array_append); STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { // self is not a memoryview, so we don't need to use (& TYPECODE_MASK) - assert((MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_bytearray)) - || (MICROPY_PY_ARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_array))); + assert((MICROPY_PY_BUILTINS_BYTEARRAY && mp_obj_is_type(self_in, &mp_type_bytearray)) + || (MICROPY_PY_ARRAY && mp_obj_is_type(self_in, &mp_type_array))); mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); // allow to extend by anything that has the buffer protocol (extension to CPython) @@ -435,7 +448,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_CPYTHON_COMPAT STATIC mp_obj_t buffer_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_bytearray)); + mp_check_self(mp_obj_is_type(args[0], &mp_type_bytearray)); const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); mp_buffer_info_t haystack_bufinfo; @@ -502,9 +515,8 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value return MP_OBJ_NULL; // op not supported } else { mp_obj_array_t *o = MP_OBJ_TO_PTR(self_in); - if (0) { #if MICROPY_PY_BUILTINS_SLICE - } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + if (mp_obj_is_type(index_in, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) { mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); @@ -515,7 +527,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value size_t src_len; void *src_items; size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL); - if (MP_OBJ_IS_OBJ(value) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) { + if (mp_obj_is_obj(value) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) { // value is array, bytearray or memoryview mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { @@ -525,11 +537,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value src_len = src_slice->len; src_items = src_slice->items; #if MICROPY_PY_BUILTINS_MEMORYVIEW - if (MP_OBJ_IS_TYPE(value, &mp_type_memoryview)) { + if (mp_obj_is_type(value, &mp_type_memoryview)) { src_items = (uint8_t *)src_items + (src_slice->memview_offset * item_sz); } #endif - } else if (MP_OBJ_IS_TYPE(value, &mp_type_bytes)) { + } else if (mp_obj_is_type(value, &mp_type_bytes)) { if (item_sz != 1) { goto compat_error; } @@ -585,22 +597,22 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value mp_obj_array_t *res; size_t sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL); assert(sz > 0); - if (0) { - // dummy #if MICROPY_PY_BUILTINS_MEMORYVIEW - } else if (o->base.type == &mp_type_memoryview) { + if (o->base.type == &mp_type_memoryview) { res = m_new_obj(mp_obj_array_t); *res = *o; res->memview_offset += slice.start; res->len = slice.stop - slice.start; + } else #endif - } else { + { res = array_new(o->typecode, slice.stop - slice.start); memcpy(res->items, (uint8_t *)o->items + slice.start * sz, (slice.stop - slice.start) * sz); } return MP_OBJ_FROM_PTR(res); + } else #endif - } else { + { size_t index = mp_get_index(o->base.type, o->len, index_in, false); #if MICROPY_PY_BUILTINS_MEMORYVIEW if (o->base.type == &mp_type_memoryview) { @@ -664,6 +676,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(array_decode_obj, 1, 3, array_decode); STATIC const mp_rom_map_elem_t array_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&array_append_obj) }, { MP_ROM_QSTR(MP_QSTR_extend), MP_ROM_PTR(&array_extend_obj) }, + #if MICROPY_CPYTHON_COMPAT + { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&bytes_decode_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(array_locals_dict, array_locals_dict_table); @@ -735,6 +750,9 @@ const mp_obj_type_t mp_type_memoryview = { .getiter = array_iterator_new, .unary_op = array_unary_op, .binary_op = array_binary_op, + #if MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE + .attr = memoryview_attr, + #endif .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, #if MICROPY_CPYTHON_COMPAT diff --git a/py/objcomplex.c b/py/objcomplex.c index 5e80826c69..5f2c4105a9 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -84,12 +84,12 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, co return mp_obj_new_complex(0, 0); case 1: - if (MP_OBJ_IS_STR(args[0])) { + if (mp_obj_is_str(args[0])) { // a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, true, true, NULL); - } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { + } else if (mp_obj_is_type(args[0], &mp_type_complex)) { // a complex, just return it return args[0]; } else { @@ -100,13 +100,13 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, co case 2: default: { mp_float_t real, imag; - if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { + if (mp_obj_is_type(args[0], &mp_type_complex)) { mp_obj_complex_get(args[0], &real, &imag); } else { real = mp_obj_get_float(args[0]); imag = 0; } - if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) { + if (mp_obj_is_type(args[1], &mp_type_complex)) { mp_float_t real2, imag2; mp_obj_complex_get(args[1], &real2, &imag2); real -= imag2; @@ -174,7 +174,7 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) { } void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_complex)); + assert(mp_obj_is_type(self_in, &mp_type_complex)); mp_obj_complex_t *self = MP_OBJ_TO_PTR(self_in); *real = self->real; *imag = self->imag; diff --git a/py/objdict.c b/py/objdict.c index 4394af9edb..6f494f54f3 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,7 +35,7 @@ #include "supervisor/linker.h" #include "supervisor/shared/translate.h" -#define MP_OBJ_IS_DICT_TYPE(o) (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == dict_make_new) +#define mp_obj_is_dict_type(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == dict_make_new) STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); @@ -46,7 +47,7 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) { mp_map_t *map = &dict->map; for (size_t i = *cur; i < max; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { *cur = i + 1; return &(map->table[i]); } @@ -128,7 +129,7 @@ STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_ } case MP_BINARY_OP_EQUAL: { #if MICROPY_PY_COLLECTIONS_ORDEREDDICT - if (MP_UNLIKELY(MP_OBJ_IS_TYPE(lhs_in, &mp_type_ordereddict) && MP_OBJ_IS_TYPE(rhs_in, &mp_type_ordereddict))) { + if (MP_UNLIKELY(mp_obj_is_type(lhs_in, &mp_type_ordereddict) && mp_obj_is_type(rhs_in, &mp_type_ordereddict))) { // Iterate through both dictionaries simultaneously and compare keys and values. mp_obj_dict_t *rhs = MP_OBJ_TO_PTR(rhs_in); size_t c1 = 0, c2 = 0; @@ -141,7 +142,7 @@ STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_ return e1 == NULL && e2 == NULL ? mp_const_true : mp_const_false; } else #endif - if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_dict)) { + if (mp_obj_is_type(rhs_in, &mp_type_dict)) { mp_obj_dict_t *rhs = MP_OBJ_TO_PTR(rhs_in); if (o->map.used != rhs->map.used) { return mp_const_false; @@ -209,7 +210,7 @@ STATIC void mp_ensure_not_fixed(const mp_obj_dict_t *dict) { } STATIC mp_obj_t dict_clear(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_ensure_not_fixed(self); @@ -220,7 +221,7 @@ STATIC mp_obj_t dict_clear(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_clear_obj, dict_clear); STATIC mp_obj_t dict_copy(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t other_out = mp_obj_new_dict(self->map.alloc); mp_obj_dict_t *other = MP_OBJ_TO_PTR(other_out); @@ -267,7 +268,7 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(dict_fromkeys_obj, MP_ROM_PTR(&dict_fromk #endif STATIC mp_obj_t dict_get_helper(size_t n_args, const mp_obj_t *args, mp_map_lookup_kind_t lookup_kind) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(args[0])); + mp_check_self(mp_obj_is_dict_type(args[0])); mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]); if (lookup_kind != MP_MAP_LOOKUP) { mp_ensure_not_fixed(self); @@ -312,7 +313,7 @@ STATIC mp_obj_t dict_setdefault(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setdefault); STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_ensure_not_fixed(self); size_t cur = 0; @@ -331,7 +332,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem); STATIC mp_obj_t PLACE_IN_ITCM(dict_update)(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(args[0])); + mp_check_self(mp_obj_is_dict_type(args[0])); mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]); mp_ensure_not_fixed(self); @@ -340,7 +341,7 @@ STATIC mp_obj_t PLACE_IN_ITCM(dict_update)(size_t n_args, const mp_obj_t *args, if (n_args == 2) { // given a positional argument - if (MP_OBJ_IS_DICT_TYPE(args[1])) { + if (mp_obj_is_dict_type(args[1])) { // update from other dictionary (make sure other is not self) if (args[1] != args[0]) { size_t cur = 0; @@ -371,7 +372,7 @@ STATIC mp_obj_t PLACE_IN_ITCM(dict_update)(size_t n_args, const mp_obj_t *args, // update the dict with any keyword args for (size_t i = 0; i < kwargs->alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + if (mp_map_slot_is_filled(kwargs, i)) { mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } } @@ -409,7 +410,7 @@ typedef struct _mp_obj_dict_view_t { } mp_obj_dict_view_t; STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &dict_view_it_type)); + mp_check_self(mp_obj_is_type(self_in, &dict_view_it_type)); mp_obj_dict_view_it_t *self = MP_OBJ_TO_PTR(self_in); mp_map_elem_t *next = dict_iter_next(MP_OBJ_TO_PTR(self->dict), &self->cur); @@ -439,7 +440,7 @@ STATIC const mp_obj_type_t dict_view_it_type = { STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) { assert(sizeof(mp_obj_dict_view_it_t) <= sizeof(mp_obj_iter_buf_t)); - mp_check_self(MP_OBJ_IS_TYPE(view_in, &dict_view_type)); + mp_check_self(mp_obj_is_type(view_in, &dict_view_type)); mp_obj_dict_view_t *view = MP_OBJ_TO_PTR(view_in); mp_obj_dict_view_it_t *o = (mp_obj_dict_view_it_t *)iter_buf; o->base.type = &dict_view_it_type; @@ -451,7 +452,7 @@ STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) STATIC void dict_view_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; - mp_check_self(MP_OBJ_IS_TYPE(self_in, &dict_view_type)); + mp_check_self(mp_obj_is_type(self_in, &dict_view_type)); mp_obj_dict_view_t *self = MP_OBJ_TO_PTR(self_in); bool first = true; mp_print_str(print, mp_dict_view_names[self->kind]); @@ -498,7 +499,7 @@ STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_t dict, mp_dict_view_kind_t kind) { } STATIC mp_obj_t dict_view(mp_obj_t self_in, mp_dict_view_kind_t kind) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); return mp_obj_new_dict_view(self_in, kind); } @@ -522,7 +523,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_values_obj, dict_values); STATIC mp_obj_t dict_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { assert(sizeof(mp_obj_dict_view_it_t) <= sizeof(mp_obj_iter_buf_t)); - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); mp_obj_dict_view_it_t *o = (mp_obj_dict_view_it_t *)iter_buf; o->base.type = &dict_view_it_type; o->kind = MP_DICT_VIEW_KEYS; @@ -599,7 +600,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in) { } mp_obj_t PLACE_IN_ITCM(mp_obj_dict_store)(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { - mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); + mp_check_self(mp_obj_is_dict_type(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_ensure_not_fixed(self); mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; diff --git a/py/objenumerate.c b/py/objenumerate.c index 2c2131ad4f..e052ebfe3e 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -78,7 +78,7 @@ const mp_obj_type_t mp_type_enumerate = { }; STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_enumerate)); + assert(mp_obj_is_type(self_in, &mp_type_enumerate)); mp_obj_enumerate_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t next = mp_iternext(self->iter); if (next == MP_OBJ_STOP_ITERATION) { diff --git a/py/objexcept.c b/py/objexcept.c index 2ea1dc7c79..9aa2dde7ff 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -124,7 +125,7 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_print_str(print, ""); return; } - if (MP_OBJ_IS_SMALL_INT(o->args->items[0]) && + if (mp_obj_is_small_int(o->args->items[0]) && mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(o->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError)) && o->args->len <= 2) { // try to provide a nice OSError error message @@ -465,7 +466,7 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com // return true if the given object is an exception type bool mp_obj_is_exception_type(mp_obj_t self_in) { - if (MP_OBJ_IS_TYPE(self_in, &mp_type_type)) { + if (mp_obj_is_type(self_in, &mp_type_type)) { // optimisation when self_in is a builtin exception mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); if (self->make_new == mp_obj_exception_make_new) { diff --git a/py/objfilter.c b/py/objfilter.c index 0e02f4b5ef..7fd9d6124c 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -44,7 +44,7 @@ STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, const } STATIC mp_obj_t filter_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_filter)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_filter)); mp_obj_filter_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t next; while ((next = mp_iternext(self->iter)) != MP_OBJ_STOP_ITERATION) { diff --git a/py/objfloat.c b/py/objfloat.c index 3bdfa0b757..67cb8514ee 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -186,7 +186,7 @@ STATIC mp_obj_t float_unary_op(mp_unary_op_t op, mp_obj_t o_in) { STATIC mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_float_t lhs_val = mp_obj_float_get(lhs_in); #if MICROPY_PY_BUILTINS_COMPLEX - if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) { + if (mp_obj_is_type(rhs_in, &mp_type_complex)) { return mp_obj_complex_binary_op(op, lhs_val, 0, rhs_in); } else #endif diff --git a/py/objfun.c b/py/objfun.c index 5e4792a7dd..c5fb267ad6 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -52,7 +52,7 @@ STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_0)); + assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_0)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num_kw_array(n_args, n_kw, 0, 0, false); return self->fun._0(); @@ -66,7 +66,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = { }; STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_1)); + assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_1)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num_kw_array(n_args, n_kw, 1, 1, false); return self->fun._1(args[0]); @@ -80,7 +80,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = { }; STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_2)); + assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_2)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num_kw_array(n_args, n_kw, 2, 2, false); return self->fun._2(args[0], args[1]); @@ -94,7 +94,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = { }; STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_3)); + assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_3)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num_kw_array(n_args, n_kw, 3, 3, false); return self->fun._3(args[0], args[1], args[2]); @@ -108,7 +108,7 @@ const mp_obj_type_t mp_type_fun_builtin_3 = { }; STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_var)); + assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_var)); mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); // check number of arguments @@ -371,7 +371,7 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byt size_t n_extra_args = 0; mp_obj_tuple_t *def_args = MP_OBJ_TO_PTR(def_args_in); if (def_args_in != MP_OBJ_NULL) { - assert(MP_OBJ_IS_TYPE(def_args_in, &mp_type_tuple)); + assert(mp_obj_is_type(def_args_in, &mp_type_tuple)); n_def_args = def_args->len; n_extra_args = def_args->len; } @@ -427,7 +427,7 @@ mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const typedef struct _mp_obj_fun_asm_t { mp_obj_base_t base; size_t n_args; - void *fun_data; // GC must be able to trace this pointer + const void *fun_data; // GC must be able to trace this pointer mp_uint_t type_sig; } mp_obj_fun_asm_t; @@ -440,7 +440,7 @@ typedef mp_uint_t (*inline_asm_fun_4_t)(mp_uint_t, mp_uint_t, mp_uint_t, mp_uint // convert a MicroPython object to a sensible value for inline asm STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array - if (MP_OBJ_IS_SMALL_INT(obj)) { + if (mp_obj_is_small_int(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; @@ -448,21 +448,21 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { return 0; } else if (obj == mp_const_true) { return 1; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) { + } else if (mp_obj_is_type(obj, &mp_type_int)) { return mp_obj_int_get_truncated(obj); - } else if (MP_OBJ_IS_STR(obj)) { + } else if (mp_obj_is_str(obj)) { // pointer to the string (it's probably constant though!) size_t l; return (mp_uint_t)mp_obj_str_get_data(obj, &l); } else { mp_obj_type_t *type = mp_obj_get_type(obj); - if (0) { #if MICROPY_PY_BUILTINS_FLOAT - } else if (type == &mp_type_float) { + if (type == &mp_type_float) { // convert float to int (could also pass in float registers) return (mp_int_t)mp_obj_float_get(obj); + } else #endif - } else if (type == &mp_type_tuple || type == &mp_type_list) { + if (type == &mp_type_tuple || type == &mp_type_list) { // pointer to start of tuple (could pass length, but then could use len(x) for that) size_t len; mp_obj_t *items; @@ -486,7 +486,7 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_arg_check_num_kw_array(n_args, n_kw, self->n_args, self->n_args, false); - void *fun = MICROPY_MAKE_POINTER_CALLABLE(self->fun_data); + const void *fun = MICROPY_MAKE_POINTER_CALLABLE(self->fun_data); mp_uint_t ret; if (n_args == 0) { @@ -508,7 +508,7 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const ); } - return mp_convert_native_to_obj(ret, self->type_sig); + return mp_native_to_obj(ret, self->type_sig); } STATIC const mp_obj_type_t mp_type_fun_asm = { @@ -518,7 +518,7 @@ STATIC const mp_obj_type_t mp_type_fun_asm = { .unary_op = mp_generic_unary_op, }; -mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig) { +mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig) { mp_obj_fun_asm_t *o = m_new_obj(mp_obj_fun_asm_t); o->base.type = &mp_type_fun_asm; o->n_args = n_args; diff --git a/py/objgenerator.c b/py/objgenerator.c index 5336f7f36a..518944e26b 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014-2017 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -174,7 +174,7 @@ STATIC void gen_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_pri mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) { MP_STACK_CHECK(); - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_gen_instance)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_gen_instance)); mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); if (self->code_state.ip == 0) { // Trying to resume already stopped generator @@ -297,7 +297,6 @@ STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) { return ret; } } - STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send); #if MICROPY_PY_ASYNC_AWAIT @@ -317,7 +316,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(gen_instance_await_obj, gen_instance_await); STATIC mp_obj_t gen_instance_close(mp_obj_t self_in); STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) { - mp_obj_t exc = (n_args == 2) ? args[1] : args[2]; + // The signature of this function is: throw(type[, value[, traceback]]) + // CPython will pass all given arguments through the call chain and process them + // at the point they are used (native generators will handle them differently to + // user-defined generators with a throw() method). To save passing multiple + // values, MicroPython instead does partial processing here to reduce it down to + // one argument and passes that through: + // - if only args[1] is given, or args[2] is given but is None, args[1] is + // passed through (in the standard case it is an exception class or instance) + // - if args[2] is given and not None it is passed through (in the standard + // case it would be an exception instance and args[1] its corresponding class) + // - args[3] is always ignored + + mp_obj_t exc = args[1]; + if (n_args > 2 && args[2] != mp_const_none) { + exc = args[2]; + } mp_obj_t ret = gen_resume_and_raise(args[0], mp_const_none, exc); if (ret == MP_OBJ_STOP_ITERATION) { @@ -326,7 +340,6 @@ STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) { return ret; } } - STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_instance_throw); STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { @@ -348,7 +361,6 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { return mp_const_none; } } - STATIC MP_DEFINE_CONST_FUN_OBJ_1(gen_instance_close_obj, gen_instance_close); STATIC mp_obj_t gen_instance_pend_throw(mp_obj_t self_in, mp_obj_t exc_in) { diff --git a/py/objint.c b/py/objint.c index ac9eb70591..5921db6b31 100644 --- a/py/objint.c +++ b/py/objint.c @@ -51,10 +51,10 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, return MP_OBJ_NEW_SMALL_INT(0); case 1: - if (MP_OBJ_IS_INT(args[0])) { + if (mp_obj_is_int(args[0])) { // already an int (small or long), just return it return args[0]; - } else if (MP_OBJ_IS_STR_OR_BYTES(args[0])) { + } else if (mp_obj_is_str_or_bytes(args[0])) { // a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); @@ -226,11 +226,11 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co // Only have small ints; get the integer value to format. num = MP_OBJ_SMALL_INT_VALUE(self_in); #else - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { // A small int; get the integer value to format. num = MP_OBJ_SMALL_INT_VALUE(self_in); } else { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); // Not a small int. #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG const mp_obj_int_t *self = self_in; @@ -446,7 +446,7 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp // true acts as 0 return mp_binary_op(op, lhs_in, MP_OBJ_NEW_SMALL_INT(1)); } else if (op == MP_BINARY_OP_MULTIPLY) { - if (MP_OBJ_IS_STR_OR_BYTES(rhs_in) || MP_OBJ_IS_TYPE(rhs_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(rhs_in, &mp_type_list)) { + if (mp_obj_is_str_or_bytes(rhs_in) || mp_obj_is_type(rhs_in, &mp_type_tuple) || mp_obj_is_type(rhs_in, &mp_type_list)) { // multiply is commutative for these types, so delegate to them return mp_binary_op(op, rhs_in, lhs_in); } @@ -457,7 +457,7 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp #if MICROPY_CPYTHON_COMPAT STATIC mp_obj_t int_bit_length(mp_obj_t self_in) { #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - if (!MP_OBJ_IS_SMALL_INT(self_in)) { + if (!mp_obj_is_small_int(self_in)) { return mp_obj_int_bit_length_impl(self_in); } else #endif @@ -533,7 +533,7 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t * memset(data, 0, len); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE - if (!MP_OBJ_IS_SMALL_INT(self)) { + if (!mp_obj_is_small_int(self)) { mp_obj_int_buffer_overflow_check(self, len, signed_); mp_obj_int_to_bytes_impl(self, big_endian, len, data); } else diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 63e3464a1a..aa452a4bcf 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -46,7 +46,7 @@ const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX}; #endif mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = self_in; long long val = self->val; return MP_OBJ_NEW_SMALL_INT( @@ -71,7 +71,7 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf } void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = self_in; long long val = self->val; if (big_endian) { @@ -90,7 +90,7 @@ void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byt int mp_obj_int_sign(mp_obj_t self_in) { mp_longint_impl_t val; - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { val = MP_OBJ_SMALL_INT_VALUE(self_in); } else { mp_obj_int_t *self = self_in; @@ -141,16 +141,16 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i long long lhs_val; long long rhs_val; - if (MP_OBJ_IS_SMALL_INT(lhs_in)) { + if (mp_obj_is_small_int(lhs_in)) { lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs_in); } else { - assert(MP_OBJ_IS_TYPE(lhs_in, &mp_type_int)); + assert(mp_obj_is_type(lhs_in, &mp_type_int)); lhs_val = ((mp_obj_int_t *)lhs_in)->val; } - if (MP_OBJ_IS_SMALL_INT(rhs_in)) { + if (mp_obj_is_small_int(rhs_in)) { rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs_in); - } else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_int)) { + } else if (mp_obj_is_type(rhs_in, &mp_type_int)) { rhs_val = ((mp_obj_int_t *)rhs_in)->val; } else { // delegate to generic function to check for extra cases @@ -285,7 +285,7 @@ mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, uns } mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { return MP_OBJ_SMALL_INT_VALUE(self_in); } else { const mp_obj_int_t *self = self_in; @@ -300,7 +300,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = self_in; return self->val; } diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 3d8de47985..80564cf095 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -92,7 +92,7 @@ mp_obj_int_t *mp_obj_int_new_mpz(void) { // This particular routine should only be called for the mpz representation of the int. char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma); @@ -108,7 +108,7 @@ char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, } mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(mpz_num_bits(&self->mpz)); } @@ -120,14 +120,14 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf } void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); memset(buf, 0, len); mpz_as_bytes(&self->mpz, big_endian, len, buf); } int mp_obj_int_sign(mp_obj_t self_in) { - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { mp_int_t val = MP_OBJ_SMALL_INT_VALUE(self_in); if (val < 0) { return -1; @@ -185,25 +185,25 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i mpz_dig_t z_int_dig[MPZ_NUM_DIG_FOR_INT]; // lhs could be a small int (eg small-int + mpz) - if (MP_OBJ_IS_SMALL_INT(lhs_in)) { + if (mp_obj_is_small_int(lhs_in)) { mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(lhs_in)); zlhs = &z_int; } else { - assert(MP_OBJ_IS_TYPE(lhs_in, &mp_type_int)); + assert(mp_obj_is_type(lhs_in, &mp_type_int)); zlhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(lhs_in))->mpz; } // if rhs is small int, then lhs was not (otherwise mp_binary_op handles it) - if (MP_OBJ_IS_SMALL_INT(rhs_in)) { + if (mp_obj_is_small_int(rhs_in)) { mpz_init_fixed_from_int(&z_int, z_int_dig, MPZ_NUM_DIG_FOR_INT, MP_OBJ_SMALL_INT_VALUE(rhs_in)); zrhs = &z_int; - } else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_int)) { + } else if (mp_obj_is_type(rhs_in, &mp_type_int)) { zrhs = &((mp_obj_int_t *)MP_OBJ_TO_PTR(rhs_in))->mpz; #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(rhs_in)) { return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in); #if MICROPY_PY_BUILTINS_COMPLEX - } else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) { + } else if (mp_obj_is_type(rhs_in, &mp_type_complex)) { return mp_obj_complex_binary_op(op, mpz_as_float(zlhs), 0, rhs_in); #endif #endif @@ -212,18 +212,18 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in); } - if (0) { #if MICROPY_PY_BUILTINS_FLOAT - } else if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) { + if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) { if (mpz_is_zero(zrhs)) { goto zero_division_error; } mp_float_t flhs = mpz_as_float(zlhs); mp_float_t frhs = mpz_as_float(zrhs); return mp_obj_new_float(flhs / frhs); + } else #endif - } else if (op >= MP_BINARY_OP_INPLACE_OR && op < MP_BINARY_OP_CONTAINS) { + if (op >= MP_BINARY_OP_INPLACE_OR && op < MP_BINARY_OP_CONTAINS) { mp_obj_int_t *res = mp_obj_int_new_mpz(); switch (op) { @@ -340,7 +340,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i #if MICROPY_PY_BUILTINS_POW3 STATIC mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) { - if (MP_OBJ_IS_SMALL_INT(arg)) { + if (mp_obj_is_small_int(arg)) { mpz_init_from_int(temp, MP_OBJ_SMALL_INT_VALUE(arg)); return temp; } else { @@ -350,7 +350,7 @@ STATIC mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) { } mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) { - if (!MP_OBJ_IS_INT(base) || !MP_OBJ_IS_INT(exponent) || !MP_OBJ_IS_INT(modulus)) { + if (!mp_obj_is_int(base) || !mp_obj_is_int(exponent) || !mp_obj_is_int(modulus)) { mp_raise_TypeError(translate("pow() with 3 arguments requires integers")); } else { mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int @@ -417,7 +417,7 @@ mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, uns } mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { return MP_OBJ_SMALL_INT_VALUE(self_in); } else { const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); @@ -427,7 +427,7 @@ mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { } mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { - if (MP_OBJ_IS_SMALL_INT(self_in)) { + if (mp_obj_is_small_int(self_in)) { return MP_OBJ_SMALL_INT_VALUE(self_in); } else { const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); @@ -443,7 +443,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t mp_obj_int_as_float_impl(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); + assert(mp_obj_is_type(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); return mpz_as_float(&self->mpz); } diff --git a/py/objlist.c b/py/objlist.c index d8b0870e57..8a7a6509b4 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -114,7 +114,7 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = mp_instance_cast_to_native_base(lhs, &mp_type_list); switch (op) { case MP_BINARY_OP_ADD: { - if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { + if (!mp_obj_is_type(rhs, &mp_type_list)) { return MP_OBJ_NULL; // op not supported } mp_obj_list_t *p = MP_OBJ_TO_PTR(rhs); @@ -144,7 +144,7 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: { - if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { + if (!mp_obj_is_type(rhs, &mp_type_list)) { if (op == MP_BINARY_OP_EQUAL) { return mp_const_false; } @@ -166,7 +166,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { mp_raise_NotImplementedError(NULL); @@ -188,7 +188,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } else if (value == MP_OBJ_SENTINEL) { // load #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { return mp_seq_extract_slice(self->len, self->items, &slice); @@ -202,7 +202,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return self->items[index_val]; } else { #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { size_t value_len; mp_obj_t *value_items; mp_obj_get_array(value, &value_len, &value_items); @@ -242,7 +242,7 @@ STATIC mp_obj_t list_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { } mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); if (self->len >= self->alloc) { self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2); @@ -254,8 +254,8 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { } STATIC mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); - if (MP_OBJ_IS_TYPE(arg_in, &mp_type_list)) { + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); + if (mp_obj_is_type(arg_in, &mp_type_list)) { mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); mp_obj_list_t *arg = mp_instance_cast_to_native_base(arg_in, &mp_type_list); @@ -291,7 +291,7 @@ inline mp_obj_t mp_obj_list_pop(mp_obj_list_t *self, size_t index) { } STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list)); + mp_check_self(mp_obj_is_type(args[0], &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(args[0], &mp_type_list); size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); return mp_obj_list_pop(self, index); @@ -343,7 +343,7 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); - mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &mp_type_list)); + mp_check_self(mp_obj_is_type(pos_args[0], &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(pos_args[0], &mp_type_list); if (self->len > 1) { @@ -356,7 +356,7 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ } mp_obj_t mp_obj_list_clear(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); self->len = 0; self->items = m_renew(mp_obj_t, self->items, self->alloc, LIST_MIN_ALLOC); @@ -366,19 +366,19 @@ mp_obj_t mp_obj_list_clear(mp_obj_t self_in) { } STATIC mp_obj_t list_copy(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); return mp_obj_new_list(self->len, self->items); } STATIC mp_obj_t list_count(mp_obj_t self_in, mp_obj_t value) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); return mp_seq_count_obj(self->items, self->len, value); } STATIC mp_obj_t list_index(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list)); + mp_check_self(mp_obj_is_type(args[0], &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(args[0], &mp_type_list); return mp_seq_index_obj(self->items, self->len, n_args, args); } @@ -393,7 +393,7 @@ inline void mp_obj_list_insert(mp_obj_list_t *self, size_t index, mp_obj_t obj) } STATIC mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); // insert has its own strange index logic mp_int_t index = MP_OBJ_SMALL_INT_VALUE(idx); @@ -411,7 +411,7 @@ STATIC mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) { } mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_t args[] = {self_in, value}; args[1] = list_index(2, args); list_pop(2, args); @@ -420,7 +420,7 @@ mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value) { } STATIC mp_obj_t list_reverse(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); mp_int_t len = self->len; diff --git a/py/objmap.c b/py/objmap.c index 5cf975f492..d1844b8ac7 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -49,7 +49,7 @@ STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, const mp_ } STATIC mp_obj_t map_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_map)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_map)); mp_obj_map_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t *nextses = m_new(mp_obj_t, self->n_iters); diff --git a/py/objmodule.c b/py/objmodule.c index efe4650157..ae53faf58e 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -141,13 +142,13 @@ mp_obj_t mp_obj_new_module(qstr module_name) { } mp_obj_dict_t *mp_obj_module_get_globals(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); + assert(mp_obj_is_type(self_in, &mp_type_module)); mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); return self->globals; } void mp_obj_module_set_globals(mp_obj_t self_in, mp_obj_dict_t *globals) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); + assert(mp_obj_is_type(self_in, &mp_type_module)); mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); self->globals = globals; } @@ -259,18 +260,6 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { #if MICROPY_PY_USELECT { MP_ROM_QSTR(MP_QSTR_uselect), MP_ROM_PTR(&mp_module_uselect) }, #endif - #if MICROPY_PY_USSL - { MP_ROM_QSTR(MP_QSTR_ussl), MP_ROM_PTR(&mp_module_ussl) }, - #endif - #if MICROPY_PY_LWIP - { MP_ROM_QSTR(MP_QSTR_lwip), MP_ROM_PTR(&mp_module_lwip) }, - #endif - #if MICROPY_PY_WEBSOCKET - { MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&mp_module_websocket) }, - #endif - #if MICROPY_PY_WEBREPL - { MP_ROM_QSTR(MP_QSTR__webrepl), MP_ROM_PTR(&mp_module_webrepl) }, - #endif #if MICROPY_PY_FRAMEBUF { MP_ROM_QSTR(MP_QSTR_framebuf), MP_ROM_PTR(&mp_module_framebuf) }, #endif diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index d1ca17c502..3a94d58a32 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -185,7 +185,7 @@ STATIC mp_obj_t new_namedtuple_type(mp_obj_t name_in, mp_obj_t fields_in) { size_t n_fields; mp_obj_t *fields; #if MICROPY_CPYTHON_COMPAT - if (MP_OBJ_IS_STR(fields_in)) { + if (mp_obj_is_str(fields_in)) { fields_in = mp_obj_str_split(1, &fields_in); } #endif diff --git a/py/objobject.c b/py/objobject.c index b3a6a171a0..8ad49d5188 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -51,7 +51,7 @@ STATIC mp_obj_t object___init__(mp_obj_t self) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__); STATIC mp_obj_t object___new__(mp_obj_t cls) { - if (!MP_OBJ_IS_TYPE(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t *)MP_OBJ_TO_PTR(cls))) { + if (!mp_obj_is_type(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t *)MP_OBJ_TO_PTR(cls))) { mp_raise_TypeError(translate("__new__ arg must be a user-type")); } // This executes only "__new__" part of instance creation. diff --git a/py/objproperty.c b/py/objproperty.c index f249d79a1d..06ecfc8837 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -96,7 +96,7 @@ const mp_obj_type_t mp_type_property = { }; const mp_obj_t *mp_obj_property_get(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_property)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_property)); mp_obj_property_t *self = MP_OBJ_TO_PTR(self_in); return self->proxy; } diff --git a/py/objrange.c b/py/objrange.c index fcc0ede98b..a3e05ce446 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -145,7 +145,7 @@ STATIC mp_obj_t range_unary_op(mp_unary_op_t op, mp_obj_t self_in) { #if MICROPY_PY_BUILTINS_RANGE_BINOP STATIC mp_obj_t range_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - if (!MP_OBJ_IS_TYPE(rhs_in, &mp_type_range) || op != MP_BINARY_OP_EQUAL) { + if (!mp_obj_is_type(rhs_in, &mp_type_range) || op != MP_BINARY_OP_EQUAL) { return MP_OBJ_NULL; // op not supported } mp_obj_range_t *lhs = MP_OBJ_TO_PTR(lhs_in); @@ -167,7 +167,7 @@ STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t len = range_len(self); #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; mp_seq_get_fast_slice_indexes(len, index, &slice); mp_obj_range_t *o = m_new_obj(mp_obj_range_t); diff --git a/py/objreversed.c b/py/objreversed.c index 63d122b5db..31fea2ec64 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -56,7 +56,7 @@ STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, cons } STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_reversed)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_reversed)); mp_obj_reversed_t *self = MP_OBJ_TO_PTR(self_in); // "raise" stop iteration if we are at the end (the start) of the sequence diff --git a/py/objset.c b/py/objset.c index 6089f91814..f2ead23914 100644 --- a/py/objset.c +++ b/py/objset.c @@ -47,18 +47,16 @@ typedef struct _mp_obj_set_it_t { size_t cur; } mp_obj_set_it_t; -STATIC mp_obj_t set_it_iternext(mp_obj_t self_in); - STATIC bool is_set_or_frozenset(mp_obj_t o) { - return MP_OBJ_IS_TYPE(o, &mp_type_set) + return mp_obj_is_type(o, &mp_type_set) #if MICROPY_PY_BUILTINS_FROZENSET - || MP_OBJ_IS_TYPE(o, &mp_type_frozenset) + || mp_obj_is_type(o, &mp_type_frozenset) #endif ; } // This macro is shorthand for mp_check_self to verify the argument is a set. -#define check_set(o) mp_check_self(MP_OBJ_IS_TYPE(o, &mp_type_set)) +#define check_set(o) mp_check_self(mp_obj_is_type(o, &mp_type_set)) // This macro is shorthand for mp_check_self to verify the argument is a // set or frozenset for methods that operate on both of these types. @@ -68,7 +66,7 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t (void)kind; mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_BUILTINS_FROZENSET - bool is_frozen = MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset); + bool is_frozen = mp_obj_is_type(self_in, &mp_type_frozenset); #endif if (self->set.used == 0) { #if MICROPY_PY_BUILTINS_FROZENSET @@ -87,7 +85,7 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t #endif mp_print_str(print, "{"); for (size_t i = 0; i < self->set.alloc; i++) { - if (MP_SET_SLOT_IS_FILLED(&self->set, i)) { + if (mp_set_slot_is_filled(&self->set, i)) { if (!first) { mp_print_str(print, ", "); } @@ -137,7 +135,7 @@ STATIC mp_obj_t set_it_iternext(mp_obj_t self_in) { mp_set_t *set = &self->set->set; for (size_t i = self->cur; i < max; i++) { - if (MP_SET_SLOT_IS_FILLED(set, i)) { + if (mp_set_slot_is_filled(set, i)) { self->cur = i + 1; return set->table[i]; } @@ -156,7 +154,6 @@ STATIC mp_obj_t set_getiter(mp_obj_t set_in, mp_obj_iter_buf_t *iter_buf) { return MP_OBJ_FROM_PTR(o); } - /******************************************************************************/ /* set methods */ @@ -171,9 +168,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_add_obj, set_add); STATIC mp_obj_t set_clear(mp_obj_t self_in) { check_set(self_in); mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); - mp_set_clear(&self->set); - return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(set_clear_obj, set_clear); @@ -334,6 +329,7 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool } return out; } + STATIC mp_obj_t set_issubset(mp_obj_t self_in, mp_obj_t other_in) { return set_issubset_internal(self_in, other_in, false); } @@ -438,14 +434,14 @@ STATIC mp_obj_t set_unary_op(mp_unary_op_t op, mp_obj_t self_in) { return MP_OBJ_NEW_SMALL_INT(self->set.used); #if MICROPY_PY_BUILTINS_FROZENSET case MP_UNARY_OP_HASH: - if (MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset)) { + if (mp_obj_is_type(self_in, &mp_type_frozenset)) { // start hash with unique value mp_int_t hash = (mp_int_t)(uintptr_t)&mp_type_frozenset; size_t max = self->set.alloc; mp_set_t *set = &self->set; for (size_t i = 0; i < max; i++) { - if (MP_SET_SLOT_IS_FILLED(set, i)) { + if (mp_set_slot_is_filled(set, i)) { hash += MP_OBJ_SMALL_INT_VALUE(mp_unary_op(MP_UNARY_OP_HASH, set->table[i])); } } @@ -461,7 +457,7 @@ STATIC mp_obj_t set_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC mp_obj_t set_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_t args[] = {lhs, rhs}; #if MICROPY_PY_BUILTINS_FROZENSET - bool update = MP_OBJ_IS_TYPE(lhs, &mp_type_set); + bool update = mp_obj_is_type(lhs, &mp_type_set); #else bool update = true; #endif @@ -524,7 +520,6 @@ STATIC mp_obj_t set_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { /******************************************************************************/ /* set constructors & public C API */ - STATIC const mp_rom_map_elem_t set_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&set_add_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&set_clear_obj) }, @@ -545,7 +540,6 @@ STATIC const mp_rom_map_elem_t set_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&set_update_obj) }, { MP_ROM_QSTR(MP_QSTR___contains__), MP_ROM_PTR(&mp_op_contains_obj) }, }; - STATIC MP_DEFINE_CONST_DICT(set_locals_dict, set_locals_dict_table); const mp_obj_type_t mp_type_set = { @@ -596,7 +590,7 @@ mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) { } void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_set)); mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } diff --git a/py/objslice.c b/py/objslice.c index 9bccde76db..a5d21578a1 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -60,7 +60,7 @@ STATIC void slice_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t #if MICROPY_PY_BUILTINS_SLICE_ATTRS STATIC mp_obj_t slice_indices(mp_obj_t self_in, mp_obj_t length_obj) { mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in); - if (!MP_OBJ_IS_SMALL_INT(length_obj)) { + if (!mp_obj_is_small_int(length_obj)) { mp_raise_TypeError(translate("Length must be an int")); } @@ -243,7 +243,7 @@ STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, #endif void mp_obj_slice_get(mp_obj_t self_in, mp_obj_t *start, mp_obj_t *stop, mp_obj_t *step) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_slice)); + assert(mp_obj_is_type(self_in, &mp_type_slice)); mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in); *start = self->start; *stop = self->stop; diff --git a/py/objstr.c b/py/objstr.c index a1c611e381..ad1f2b5043 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -127,7 +127,7 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t } #endif #if !MICROPY_PY_BUILTINS_STR_UNICODE - bool is_bytes = MP_OBJ_IS_TYPE(self_in, &mp_type_bytes); + bool is_bytes = mp_obj_is_type(self_in, &mp_type_bytes); #else bool is_bytes = true; #endif @@ -164,7 +164,7 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, const mp_ default: // 2 or 3 args // TODO: validate 2nd/3rd args - if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) { + if (mp_obj_is_type(args[0], &mp_type_bytes)) { GET_STR_DATA_LEN(args[0], str_data, str_len); GET_STR_HASH(args[0], str_hash); if (str_hash == 0) { @@ -214,7 +214,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, cons return mp_const_empty_bytes; } - if (MP_OBJ_IS_STR(args[0])) { + if (mp_obj_is_str(args[0])) { if (n_args < 2 || n_args > 3) { goto wrong_args; } @@ -229,7 +229,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, cons return MP_OBJ_FROM_PTR(o); } - if (MP_OBJ_IS_SMALL_INT(args[0])) { + if (mp_obj_is_small_int(args[0])) { mp_int_t len = MP_OBJ_SMALL_INT_VALUE(args[0]); if (len < 0) { mp_raise_ValueError(NULL); @@ -315,7 +315,7 @@ const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, // Note: this function is used to check if an object is a str or bytes, which // works because both those types use it as their binary_op method. Revisit -// MP_OBJ_IS_STR_OR_BYTES if this fact changes. +// mp_obj_is_str_or_bytes if this fact changes. mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // check for modulo if (op == MP_BINARY_OP_MODULO) { @@ -323,10 +323,10 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i mp_obj_t *args = &rhs_in; size_t n_args = 1; mp_obj_t dict = MP_OBJ_NULL; - if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_tuple)) { + if (mp_obj_is_type(rhs_in, &mp_type_tuple)) { // TODO: Support tuple subclasses? mp_obj_tuple_get(rhs_in, &n_args, &args); - } else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_dict)) { + } else if (mp_obj_is_type(rhs_in, &mp_type_dict)) { dict = rhs_in; } return str_modulo_format(lhs_in, n_args, args, dict); @@ -451,7 +451,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) { mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); @@ -472,7 +472,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(self_in)); + mp_check_self(mp_obj_is_str_or_bytes(self_in)); const mp_obj_type_t *self_type = mp_obj_get_type(self_in); // get separation string @@ -482,7 +482,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { size_t seq_len; mp_obj_t *seq_items; - if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) { + if (!mp_obj_is_type(arg, &mp_type_list) && !mp_obj_is_type(arg, &mp_type_tuple)) { // arg is not a list nor a tuple, try to convert it to a list // TODO: Try to optimize? arg = mp_type_list.make_new(&mp_type_list, 1, &arg, NULL); @@ -718,7 +718,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit); STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); + mp_check_self(mp_obj_is_str_or_bytes(args[0])); // check argument type if (mp_obj_get_type(args[1]) != self_type) { @@ -816,7 +816,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith); enum { LSTRIP, RSTRIP, STRIP }; STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); + mp_check_self(mp_obj_is_str_or_bytes(args[0])); const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); const byte *chars_to_del; @@ -942,7 +942,7 @@ STATIC bool istype(char ch) { } STATIC bool arg_looks_integer(mp_obj_t arg) { - return MP_OBJ_IS_TYPE(arg, &mp_type_bool) || MP_OBJ_IS_INT(arg); + return mp_obj_is_type(arg, &mp_type_bool) || mp_obj_is_int(arg); } STATIC bool arg_looks_numeric(mp_obj_t arg) { @@ -1419,7 +1419,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); + mp_check_self(mp_obj_is_str_or_bytes(args[0])); GET_STR_DATA_LEN(args[0], str, len); int arg_i = 0; @@ -1430,11 +1430,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(str_format_obj, 1, mp_obj_str_format); #if MICROPY_PY_BUILTINS_STR_OP_MODULO STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(pattern)); + mp_check_self(mp_obj_is_str_or_bytes(pattern)); GET_STR_DATA_LEN(pattern, str, len); const byte *start_str = str; - bool is_bytes = MP_OBJ_IS_TYPE(pattern, &mp_type_bytes); + bool is_bytes = mp_obj_is_type(pattern, &mp_type_bytes); size_t arg_i = 0; vstr_t vstr; mp_print_t print; @@ -1544,7 +1544,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ } switch (*str) { case 'c': - if (MP_OBJ_IS_STR(arg)) { + if (mp_obj_is_str(arg)) { size_t slen; const char *s = mp_obj_str_get_data(arg, &slen); if (slen != 1) { @@ -1589,7 +1589,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ mp_print_t arg_print; vstr_init_print(&arg_vstr, 16, &arg_print); mp_print_kind_t print_kind = (*str == 'r' ? PRINT_REPR : PRINT_STR); - if (print_kind == PRINT_STR && is_bytes && MP_OBJ_IS_TYPE(arg, &mp_type_bytes)) { + if (print_kind == PRINT_STR && is_bytes && mp_obj_is_type(arg, &mp_type_bytes)) { // If we have something like b"%s" % b"1", bytes arg should be // printed undecorated. print_kind = PRINT_RAW; @@ -1634,7 +1634,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ // The implementation is optimized, returning the original string if there's // nothing to replace. STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); + mp_check_self(mp_obj_is_str_or_bytes(args[0])); mp_int_t max_rep = -1; if (n_args == 4) { @@ -1742,7 +1742,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace); #if MICROPY_PY_BUILTINS_STR_COUNT STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); + mp_check_self(mp_obj_is_str_or_bytes(args[0])); // check argument type if (mp_obj_get_type(args[1]) != self_type) { @@ -1784,7 +1784,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count); #if MICROPY_PY_BUILTINS_STR_PARTITION STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { - mp_check_self(MP_OBJ_IS_STR_OR_BYTES(self_in)); + mp_check_self(mp_obj_is_str_or_bytes(self_in)); mp_obj_type_t *self_type = mp_obj_get_type(self_in); if (self_type != mp_obj_get_type(arg)) { bad_implicit_conversion(arg); @@ -2142,7 +2142,7 @@ mp_obj_t mp_obj_new_bytes_of_zeros(size_t len) { bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { - if (MP_OBJ_IS_QSTR(s1) && MP_OBJ_IS_QSTR(s2)) { + if (mp_obj_is_qstr(s1) && mp_obj_is_qstr(s2)) { return s1 == s2; } else { GET_STR_HASH(s1, h1); @@ -2173,9 +2173,9 @@ STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in) { // use this if you will anyway convert the string to a qstr // will be more efficient for the case where it's already a qstr qstr mp_obj_str_get_qstr(mp_obj_t self_in) { - if (MP_OBJ_IS_QSTR(self_in)) { + if (mp_obj_is_qstr(self_in)) { return MP_OBJ_QSTR_VALUE(self_in); - } else if (MP_OBJ_IS_TYPE(self_in, &mp_type_str)) { + } else if (mp_obj_is_type(self_in, &mp_type_str)) { mp_obj_str_t *self = MP_OBJ_TO_PTR(self_in); return qstr_from_strn((char *)self->data, self->len); } else { @@ -2186,7 +2186,7 @@ qstr mp_obj_str_get_qstr(mp_obj_t self_in) { // only use this function if you need the str data to be zero terminated // at the moment all strings are zero terminated to help with C ASCIIZ compatibility const char *mp_obj_str_get_str(mp_obj_t self_in) { - if (MP_OBJ_IS_STR_OR_BYTES(self_in)) { + if (mp_obj_is_str_or_bytes(self_in)) { GET_STR_DATA_LEN(self_in, s, l); (void)l; // len unused return (const char *)s; @@ -2196,7 +2196,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in) { } const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len) { - if (MP_OBJ_IS_STR_OR_BYTES(self_in)) { + if (mp_obj_is_str_or_bytes(self_in)) { GET_STR_DATA_LEN(self_in, s, l); *len = l; return (const char *)s; @@ -2207,7 +2207,7 @@ const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len) { #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len) { - if (MP_OBJ_IS_QSTR(self_in)) { + if (mp_obj_is_qstr(self_in)) { return qstr_data(MP_OBJ_QSTR_VALUE(self_in), len); } else { *len = ((mp_obj_str_t *)self_in)->len; diff --git a/py/objstr.h b/py/objstr.h index e1698ca592..3672fe5d8a 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -41,12 +41,12 @@ typedef struct _mp_obj_str_t { // use this macro to extract the string hash // warning: the hash can be 0, meaning invalid, and must then be explicitly computed from the data #define GET_STR_HASH(str_obj_in, str_hash) \ - mp_uint_t str_hash; if (MP_OBJ_IS_QSTR(str_obj_in)) \ + mp_uint_t str_hash; if (mp_obj_is_qstr(str_obj_in)) \ { str_hash = qstr_hash(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_hash = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->hash; } // use this macro to extract the string length #define GET_STR_LEN(str_obj_in, str_len) \ - size_t str_len; if (MP_OBJ_IS_QSTR(str_obj_in)) \ + size_t str_len; if (mp_obj_is_qstr(str_obj_in)) \ { str_len = qstr_len(MP_OBJ_QSTR_VALUE(str_obj_in)); } else { str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; } // use this macro to extract the string data and length @@ -56,7 +56,7 @@ const byte *mp_obj_str_get_data_no_check(mp_obj_t self_in, size_t *len); size_t str_len; const byte *str_data = mp_obj_str_get_data_no_check(str_obj_in, &str_len); #else #define GET_STR_DATA_LEN(str_obj_in, str_data, str_len) \ - const byte *str_data; size_t str_len; if (MP_OBJ_IS_QSTR(str_obj_in)) \ + const byte *str_data; size_t str_len; if (mp_obj_is_qstr(str_obj_in)) \ { str_data = qstr_data(MP_OBJ_QSTR_VALUE(str_obj_in), &str_len); } \ else { str_len = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t *)MP_OBJ_TO_PTR(str_obj_in))->data; } #endif @@ -107,5 +107,6 @@ MP_DECLARE_CONST_FUN_OBJ_1(str_isalpha_obj); MP_DECLARE_CONST_FUN_OBJ_1(str_isdigit_obj); MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj); MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(bytes_decode_obj); #endif // MICROPY_INCLUDED_PY_OBJSTR_H diff --git a/py/objstringio.c b/py/objstringio.c index 793ec84f31..3d2ff14828 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -198,7 +198,7 @@ STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, c if (n_args > 0) { mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); - if (MP_OBJ_IS_STR_OR_BYTES(args[0])) { + if (mp_obj_is_str_or_bytes(args[0])) { o->vstr = m_new_obj(vstr_t); vstr_init_fixed_buf(o->vstr, bufinfo.len, bufinfo.buf); o->vstr->len = bufinfo.len; diff --git a/py/objstrunicode.c b/py/objstrunicode.c index d77bbeebcd..898339569e 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -148,7 +148,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s // Copied from mp_get_index; I don't want bounds checking, just give me // the integer as-is. (I can't bounds-check without scanning the whole // string; an out-of-bounds index will be caught in the loops below.) - if (MP_OBJ_IS_SMALL_INT(index)) { + if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { mp_raise_TypeError_varg(translate("string indices must be integers, not %q"), mp_obj_get_type_qstr(index)); @@ -203,7 +203,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_obj_t ostart, ostop, ostep; mp_obj_slice_get(index, &ostart, &ostop, &ostep); if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) { diff --git a/py/objtuple.c b/py/objtuple.c index fea4728230..8d1c22be83 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -73,7 +74,7 @@ STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg case 1: default: { // 1 argument, an iterable from which we make a new tuple - if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) { + if (mp_obj_is_type(args[0], &mp_type_tuple)) { return args[0]; } @@ -191,7 +192,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } #if MICROPY_PY_BUILTINS_SLICE - if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { + if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); @@ -209,14 +210,14 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } STATIC mp_obj_t tuple_count(mp_obj_t self_in, mp_obj_t value) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_tuple)); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); return mp_seq_count_obj(self->items, self->len, value); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(tuple_count_obj, tuple_count); STATIC mp_obj_t tuple_index(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)); + mp_check_self(mp_obj_is_type(args[0], &mp_type_tuple)); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(args[0]); return mp_seq_index_obj(self->items, self->len, n_args, args); } @@ -268,7 +269,7 @@ void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) { } void mp_obj_tuple_del(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); + assert(mp_obj_is_type(self_in, &mp_type_tuple)); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); m_del_var(mp_obj_tuple_t, mp_obj_t, self->len, self); } diff --git a/py/objtype.c b/py/objtype.c index 1f9bc386ad..42c616b75e 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013-2018 Damien P. George - * Copyright (c) 2014-2016 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -76,7 +76,7 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t const mp_obj_t *item = parent_tuple->items; const mp_obj_t *top = item + parent_tuple->len; for (; item < top; ++item) { - assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + assert(mp_obj_is_type(*item, &mp_type_type)); const mp_obj_type_t *bt = (const mp_obj_type_t *)MP_OBJ_TO_PTR(*item); count += instance_count_native_bases(bt, last_native_base); } @@ -182,7 +182,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t // do a lookup, not a (base) type in which we found the class method. const mp_obj_type_t *org_type = (const mp_obj_type_t *)lookup->obj; mp_convert_member_lookup(MP_OBJ_NULL, org_type, elem->value, lookup->dest); - } else if (MP_OBJ_IS_TYPE(elem->value, &mp_type_property)) { + } else if (mp_obj_is_type(elem->value, &mp_type_property)) { lookup->dest[0] = elem->value; return; } else { @@ -223,7 +223,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t const mp_obj_t *item = parent_tuple->items; const mp_obj_t *top = item + parent_tuple->len - 1; for (; item < top; ++item) { - assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + assert(mp_obj_is_type(*item, &mp_type_type)); mp_obj_type_t *bt = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item); if (bt == &mp_type_object) { // Not a "real" type @@ -236,7 +236,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t } // search last base (simple tail recursion elimination) - assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + assert(mp_obj_is_type(*item, &mp_type_type)); type = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item); #endif } else { @@ -455,7 +455,7 @@ STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) { break; case MP_UNARY_OP_INT: // Must return int - if (!MP_OBJ_IS_INT(val)) { + if (!mp_obj_is_int(val)) { mp_raise_TypeError(NULL); } break; @@ -619,7 +619,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des mp_map_t *map = &self->members; mp_obj_t attr_dict = mp_obj_new_dict(map->used); for (size_t i = 0; i < map->alloc; ++i) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { mp_obj_dict_store(attr_dict, map->table[i].key, map->table[i].value); } } @@ -644,7 +644,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des } #if MICROPY_PY_BUILTINS_PROPERTY - if (MP_OBJ_IS_TYPE(member, &mp_type_property)) { + if (mp_obj_is_type(member, &mp_type_property)) { // object member is a property; delegate the load to the property // Note: This is an optimisation for code size and execution time. // The proper way to do it is have the functionality just below @@ -724,7 +724,7 @@ STATIC bool mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val if (member[0] != MP_OBJ_NULL) { #if MICROPY_PY_BUILTINS_PROPERTY - if (MP_OBJ_IS_TYPE(member[0], &mp_type_property)) { + if (mp_obj_is_type(member[0], &mp_type_property)) { // attribute exists and is a property; delegate the store/delete // Note: This is an optimisation for code size and execution time. // The proper way to do it is have the functionality just below in @@ -962,7 +962,7 @@ STATIC bool check_for_special_accessors(mp_obj_t key, mp_obj_t value) { } #endif #if MICROPY_PY_BUILTINS_PROPERTY - if (MP_OBJ_IS_TYPE(value, &mp_type_property)) { + if (mp_obj_is_type(value, &mp_type_property)) { return true; } #endif @@ -986,7 +986,7 @@ STATIC bool map_has_special_accessors(const mp_map_t *map) { return false; } for (size_t i = 0; i < map->alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { const mp_map_elem_t *elem = &map->table[i]; if (check_for_special_accessors(elem->key, elem->value)) { return true; @@ -1046,7 +1046,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp } STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type)); + assert(mp_obj_is_type(self_in, &mp_type_type)); mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] == MP_OBJ_NULL) { @@ -1116,10 +1116,10 @@ const mp_obj_type_t mp_type_type = { mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) { // Verify input objects have expected type - if (!MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)) { + if (!mp_obj_is_type(bases_tuple, &mp_type_tuple)) { mp_raise_TypeError(NULL); } - if (!MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)) { + if (!mp_obj_is_type(locals_dict, &mp_type_dict)) { mp_raise_TypeError(NULL); } @@ -1131,7 +1131,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_t *bases_items; mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); for (size_t i = 0; i < bases_len; i++) { - if (!MP_OBJ_IS_TYPE(bases_items[i], &mp_type_type)) { + if (!mp_obj_is_type(bases_items[i], &mp_type_type)) { mp_raise_TypeError(translate("type is not an acceptable base type")); } mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); @@ -1209,7 +1209,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); if (elem != NULL) { // __new__ slot exists; check if it is a function - if (MP_OBJ_IS_FUN(elem->value)) { + if (mp_obj_is_fun(elem->value)) { // __new__ is a function, wrap it in a staticmethod decorator elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, &elem->value, NULL); } @@ -1242,7 +1242,7 @@ STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, cons // 0 arguments are turned into 2 in the compiler // 1 argument is not yet implemented mp_arg_check_num(n_args, kw_args, 2, 2, false); - if (!MP_OBJ_IS_TYPE(args[0], &mp_type_type)) { + if (!mp_obj_is_type(args[0], &mp_type_type)) { mp_raise_TypeError(translate("first argument to super() must be type")); } mp_obj_super_t *o = m_new_obj(mp_obj_super_t); @@ -1256,10 +1256,10 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { return; } - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_super)); + assert(mp_obj_is_type(self_in, &mp_type_super)); mp_obj_super_t *self = MP_OBJ_TO_PTR(self_in); - assert(MP_OBJ_IS_TYPE(self->type, &mp_type_type)); + assert(mp_obj_is_type(self->type, &mp_type_type)); mp_obj_type_t *type = MP_OBJ_TO_PTR(self->type); @@ -1284,7 +1284,7 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { size_t len = parent_tuple->len; const mp_obj_t *items = parent_tuple->items; for (size_t i = 0; i < len; i++) { - assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); + assert(mp_obj_is_type(items[i], &mp_type_type)); if (MP_OBJ_TO_PTR(items[i]) == &mp_type_object) { // The "object" type will be searched at the end of this function, // and we don't want to lookup native methods in object. @@ -1310,7 +1310,7 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { // changes to mp_obj_instance_load_attr may require changes // here... #if MICROPY_PY_BUILTINS_PROPERTY - if (MP_OBJ_IS_TYPE(member, &mp_type_property)) { + if (mp_obj_is_type(member, &mp_type_property)) { const mp_obj_t *proxy = mp_obj_property_get(member); if (proxy[0] == mp_const_none) { mp_raise_AttributeError(translate("unreadable attribute")); @@ -1366,7 +1366,7 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) { // not equivalent classes, keep searching base classes // object should always be a type object, but just return false if it's not - if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) { + if (!mp_obj_is_type(object, &mp_type_type)) { return false; } @@ -1402,10 +1402,10 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) { STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { size_t len; mp_obj_t *items; - if (MP_OBJ_IS_TYPE(classinfo, &mp_type_type)) { + if (mp_obj_is_type(classinfo, &mp_type_type)) { len = 1; items = &classinfo; - } else if (MP_OBJ_IS_TYPE(classinfo, &mp_type_tuple)) { + } else if (mp_obj_is_type(classinfo, &mp_type_tuple)) { mp_obj_tuple_get(classinfo, &len, &items); } else { mp_raise_TypeError(translate("issubclass() arg 2 must be a class or a tuple of classes")); @@ -1421,7 +1421,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { } STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) { - if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) { + if (!mp_obj_is_type(object, &mp_type_type)) { mp_raise_TypeError(translate("issubclass() arg 1 must be a class")); } return mp_obj_is_subclass(object, classinfo); diff --git a/py/objzip.c b/py/objzip.c index 885e464418..c7aa88eb7c 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -49,7 +49,7 @@ STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, const mp_ } STATIC mp_obj_t zip_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_zip)); + mp_check_self(mp_obj_is_type(self_in, &mp_type_zip)); mp_obj_zip_t *self = MP_OBJ_TO_PTR(self_in); if (self->n_iters == 0) { return MP_OBJ_STOP_ITERATION; diff --git a/py/parse.c b/py/parse.c index c8a975e0d2..b829a3a386 100644 --- a/py/parse.c +++ b/py/parse.c @@ -344,7 +344,7 @@ bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) { #else *o = (mp_obj_t)pns->nodes[0]; #endif - return MP_OBJ_IS_INT(*o); + return mp_obj_is_int(*o); } else { return false; } @@ -493,7 +493,7 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { mp_map_elem_t *elem; if (rule_id == RULE_atom && (elem = mp_map_lookup(&parser->consts, MP_OBJ_NEW_QSTR(id), MP_MAP_LOOKUP)) != NULL) { - if (MP_OBJ_IS_SMALL_INT(elem->value)) { + if (mp_obj_is_small_int(elem->value)) { pn = mp_parse_node_new_small_int_checked(parser, elem->value); } else { pn = make_node_const_object(parser, lex->tok_line, elem->value); @@ -507,7 +507,7 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { #endif } else if (lex->tok_kind == MP_TOKEN_INTEGER) { mp_obj_t o = mp_parse_num_integer(lex->vstr.buf, lex->vstr.len, 0, lex); - if (MP_OBJ_IS_SMALL_INT(o)) { + if (mp_obj_is_small_int(o)) { pn = mp_parse_node_new_small_int_checked(parser, o); } else { pn = make_node_const_object(parser, lex->tok_line, o); @@ -784,7 +784,7 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { } mp_obj_t dest[2]; mp_load_method_maybe(elem->value, q_attr, dest); - if (!(dest[0] != MP_OBJ_NULL && MP_OBJ_IS_INT(dest[0]) && dest[1] == MP_OBJ_NULL)) { + if (!(dest[0] != MP_OBJ_NULL && mp_obj_is_int(dest[0]) && dest[1] == MP_OBJ_NULL)) { return false; } arg0 = dest[0]; @@ -799,7 +799,7 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { for (size_t i = num_args; i > 0; i--) { pop_result(parser); } - if (MP_OBJ_IS_SMALL_INT(arg0)) { + if (mp_obj_is_small_int(arg0)) { push_result_node(parser, mp_parse_node_new_small_int_checked(parser, arg0)); } else { // TODO reuse memory for parse node struct? diff --git a/py/persistentcode.c b/py/persistentcode.c index 4e352ce7a4..13447e931f 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -40,10 +40,17 @@ #include "py/smallint.h" -// The current version of .mpy files -#define MPY_VERSION (3) +#define QSTR_LAST_STATIC MP_QSTR_zip -// The feature flags byte encodes the compile-time config options that +// Macros to encode/decode flags to/from the feature byte +#define MPY_FEATURE_ENCODE_FLAGS(flags) (flags) +#define MPY_FEATURE_DECODE_FLAGS(feat) ((feat) & 3) + +// Macros to encode/decode native architecture to/from the feature byte +#define MPY_FEATURE_ENCODE_ARCH(arch) ((arch) << 2) +#define MPY_FEATURE_DECODE_ARCH(feat) ((feat) >> 2) + +// The feature flag bits encode the compile-time config options that // affect the generate bytecode. #define MPY_FEATURE_FLAGS ( \ ((MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) << 0) \ @@ -55,6 +62,27 @@ | ((MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC) << 1) \ ) +// Define the host architecture +#if MICROPY_EMIT_X86 +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_X86) +#elif MICROPY_EMIT_X64 +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_X64) +#elif MICROPY_EMIT_THUMB +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7M) +#elif MICROPY_EMIT_ARM +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV6) +#elif MICROPY_EMIT_XTENSA +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_XTENSA) +#else +#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_NONE) +#endif + +#if MICROPY_DYNAMIC_COMPILER +#define MPY_FEATURE_ARCH_DYNAMIC mp_dynamic_compiler.native_arch +#else +#define MPY_FEATURE_ARCH_DYNAMIC MPY_FEATURE_ARCH +#endif + #if MICROPY_PERSISTENT_CODE_LOAD || (MICROPY_PERSISTENT_CODE_SAVE && !MICROPY_DYNAMIC_COMPILER) // The bytecode will depend on the number of bits in a small-int, and // this function computes that (could make it a fixed constant, but it @@ -70,6 +98,57 @@ STATIC int mp_small_int_bits(void) { } #endif +#define QSTR_WINDOW_SIZE (32) + +typedef struct _qstr_window_t { + uint16_t idx; // indexes the head of the window + uint16_t window[QSTR_WINDOW_SIZE]; +} qstr_window_t; + +// Push a qstr to the head of the window, and the tail qstr is overwritten +STATIC void qstr_window_push(qstr_window_t *qw, qstr qst) { + qw->idx = (qw->idx + 1) % QSTR_WINDOW_SIZE; + qw->window[qw->idx] = qst; +} + +// Pull an existing qstr from within the window to the head of the window +STATIC qstr qstr_window_pull(qstr_window_t *qw, size_t idx) { + qstr qst = qw->window[idx]; + if (idx > qw->idx) { + memmove(&qw->window[idx], &qw->window[idx + 1], (QSTR_WINDOW_SIZE - idx - 1) * sizeof(uint16_t)); + qw->window[QSTR_WINDOW_SIZE - 1] = qw->window[0]; + idx = 0; + } + memmove(&qw->window[idx], &qw->window[idx + 1], (qw->idx - idx) * sizeof(uint16_t)); + qw->window[qw->idx] = qst; + return qst; +} + +#if MICROPY_PERSISTENT_CODE_LOAD + +// Access a qstr at the given index, relative to the head of the window (0=head) +STATIC qstr qstr_window_access(qstr_window_t *qw, size_t idx) { + return qstr_window_pull(qw, (qw->idx + QSTR_WINDOW_SIZE - idx) % QSTR_WINDOW_SIZE); +} + +#endif + +#if MICROPY_PERSISTENT_CODE_SAVE + +// Insert a qstr at the head of the window, either by pulling an existing one or pushing a new one +STATIC size_t qstr_window_insert(qstr_window_t *qw, qstr qst) { + for (size_t idx = 0; idx < QSTR_WINDOW_SIZE; ++idx) { + if (qw->window[idx] == qst) { + qstr_window_pull(qw, idx); + return (qw->idx + QSTR_WINDOW_SIZE - idx) % QSTR_WINDOW_SIZE; + } + } + qstr_window_push(qw, qst); + return QSTR_WINDOW_SIZE; +} + +#endif + typedef struct _bytecode_prelude_t { uint n_state; uint n_exc_stack; @@ -80,6 +159,8 @@ typedef struct _bytecode_prelude_t { uint code_info_size; } bytecode_prelude_t; +#if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_EMIT_NATIVE + // ip will point to start of opcodes // ip2 will point to simple_name, source_file qstrs STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_t *prelude) { @@ -96,40 +177,69 @@ STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_ } } +#endif + #endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_LOAD #include "py/parsenum.h" -STATIC void raise_corrupt_mpy(void) { - mp_raise_RuntimeError(translate("Corrupt .mpy file")); +#if MICROPY_EMIT_NATIVE + +#if MICROPY_EMIT_THUMB +STATIC void asm_thumb_rewrite_mov(uint8_t *pc, uint16_t val) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + // high part + *(uint16_t *)pc = (*(uint16_t *)pc & 0xfbf0) | (val >> 1 & 0x0400) | (val >> 12); + // low part + *(uint16_t *)(pc + 2) = (*(uint16_t *)(pc + 2) & 0x0f00) | (val << 4 & 0x7000) | (val & 0x00ff); +#pragma GCC diagnostic pop +} +#endif + +STATIC void arch_link_qstr(uint8_t *pc, bool is_obj, qstr qst) { + mp_uint_t val = qst; + if (is_obj) { + val = (mp_uint_t)MP_OBJ_NEW_QSTR(qst); + } + #if MICROPY_EMIT_X86 || MICROPY_EMIT_X64 || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA + pc[0] = val & 0xff; + pc[1] = (val >> 8) & 0xff; + pc[2] = (val >> 16) & 0xff; + pc[3] = (val >> 24) & 0xff; + #elif MICROPY_EMIT_THUMB + if (is_obj) { + // qstr object, movw and movt + asm_thumb_rewrite_mov(pc, val); // movw + asm_thumb_rewrite_mov(pc + 4, val >> 16); // movt + } else { + // qstr number, movw instruction + asm_thumb_rewrite_mov(pc, val); // movw + } + #endif } +#endif + STATIC int read_byte(mp_reader_t *reader) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); - } - return b; + return reader->readbyte(reader->data); } STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) { while (len-- > 0) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); - } - *buf++ = b; + *buf++ = reader->readbyte(reader->data); } } -STATIC size_t read_uint(mp_reader_t *reader) { +STATIC size_t read_uint(mp_reader_t *reader, byte **out) { size_t unum = 0; for (;;) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); + byte b = reader->readbyte(reader->data); + if (out != NULL) { + **out = b; + ++*out; } unum = (unum << 7) | (b & 0x7f); if ((b & 0x80) == 0) { @@ -139,11 +249,22 @@ STATIC size_t read_uint(mp_reader_t *reader) { return unum; } -STATIC qstr load_qstr(mp_reader_t *reader) { - size_t len = read_uint(reader); - char str[len]; +STATIC qstr load_qstr(mp_reader_t *reader, qstr_window_t *qw) { + size_t len = read_uint(reader, NULL); + if (len == 0) { + // static qstr + return read_byte(reader); + } + if (len & 1) { + // qstr in window + return qstr_window_access(qw, len >> 1); + } + len >>= 1; + char *str = m_new(char, len); read_bytes(reader, (byte *)str, len); qstr qst = qstr_from_strn(str, len); + m_del(char, str, len); + qstr_window_push(qw, qst); return qst; } @@ -152,7 +273,7 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { if (obj_type == 'e') { return MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj); } else { - size_t len = read_uint(reader); + size_t len = read_uint(reader, NULL); vstr_t vstr; vstr_init_len(&vstr, len); read_bytes(reader, (byte *)vstr.buf, len); @@ -160,74 +281,202 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { return mp_obj_new_str_from_vstr(obj_type == 's' ? &mp_type_str : &mp_type_bytes, &vstr); } else if (obj_type == 'i') { return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); - } else if (obj_type == 'f' || obj_type == 'c') { + } else { + assert(obj_type == 'f' || obj_type == 'c'); return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == 'c', false, NULL); } } - raise_corrupt_mpy(); - return MP_OBJ_FROM_PTR(&mp_const_none_obj); } -STATIC void load_bytecode_qstrs(mp_reader_t *reader, byte *ip, byte *ip_top) { +STATIC void load_prelude(mp_reader_t *reader, byte **ip, byte **ip2, bytecode_prelude_t *prelude) { + prelude->n_state = read_uint(reader, ip); + prelude->n_exc_stack = read_uint(reader, ip); + read_bytes(reader, *ip, 4); + prelude->scope_flags = *(*ip)++; + prelude->n_pos_args = *(*ip)++; + prelude->n_kwonly_args = *(*ip)++; + prelude->n_def_pos_args = *(*ip)++; + *ip2 = *ip; + prelude->code_info_size = read_uint(reader, ip2); + read_bytes(reader, *ip2, prelude->code_info_size - (*ip2 - *ip)); + *ip += prelude->code_info_size; + while ((*(*ip)++ = read_byte(reader)) != 255) { + } +} + +STATIC void load_bytecode(mp_reader_t *reader, qstr_window_t *qw, byte *ip, byte *ip_top) { while (ip < ip_top) { + *ip = read_byte(reader); size_t sz; - uint f = mp_opcode_format(ip, &sz); + uint f = mp_opcode_format(ip, &sz, false); + ++ip; + --sz; if (f == MP_OPCODE_QSTR) { - qstr qst = load_qstr(reader); - ip[1] = qst; - ip[2] = qst >> 8; + qstr qst = load_qstr(reader, qw); + *ip++ = qst; + *ip++ = qst >> 8; + sz -= 2; + } else if (f == MP_OPCODE_VAR_UINT) { + while ((*ip++ = read_byte(reader)) & 0x80) { + } } + read_bytes(reader, ip, sz); ip += sz; } } -STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader) { - // load bytecode - size_t bc_len = read_uint(reader); - byte *bytecode = m_new(byte, bc_len); - read_bytes(reader, bytecode, bc_len); +STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { + // Load function kind and data length + size_t kind_len = read_uint(reader, NULL); + int kind = (kind_len & 3) + MP_CODE_BYTECODE; + size_t fun_data_len = kind_len >> 2; - // extract prelude - const byte *ip = bytecode; - const byte *ip2; - bytecode_prelude_t prelude; - extract_prelude(&ip, &ip2, &prelude); - - // load qstrs and link global qstr ids into bytecode - qstr simple_name = load_qstr(reader); - qstr source_file = load_qstr(reader); - ((byte *)ip2)[0] = simple_name; - ((byte *)ip2)[1] = simple_name >> 8; - ((byte *)ip2)[2] = source_file; - ((byte *)ip2)[3] = source_file >> 8; - load_bytecode_qstrs(reader, (byte *)ip, bytecode + bc_len); - - // load constant table - size_t n_obj = read_uint(reader); - size_t n_raw_code = read_uint(reader); - mp_uint_t *const_table = m_new(mp_uint_t, prelude.n_pos_args + prelude.n_kwonly_args + n_obj + n_raw_code); - mp_uint_t *ct = const_table; - for (size_t i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { - *ct++ = (mp_uint_t)MP_OBJ_NEW_QSTR(load_qstr(reader)); + #if !MICROPY_EMIT_NATIVE + if (kind != MP_CODE_BYTECODE) { + mp_raise_ValueError(translate("incompatible .mpy file")); } - for (size_t i = 0; i < n_obj; ++i) { - *ct++ = (mp_uint_t)load_obj(reader); - } - for (size_t i = 0; i < n_raw_code; ++i) { - *ct++ = (mp_uint_t)(uintptr_t)load_raw_code(reader); + #endif + + uint8_t *fun_data = NULL; + byte *ip2; + bytecode_prelude_t prelude = {0}; + #if MICROPY_EMIT_NATIVE + size_t prelude_offset; + mp_uint_t type_sig = 0; + size_t n_qstr_link = 0; + #endif + + if (kind == MP_CODE_BYTECODE) { + // Allocate memory for the bytecode + fun_data = m_new(uint8_t, fun_data_len); + + // Load prelude + byte *ip = fun_data; + load_prelude(reader, &ip, &ip2, &prelude); + + // Load bytecode + load_bytecode(reader, qw, ip, fun_data + fun_data_len); + + #if MICROPY_EMIT_NATIVE + } else { + // Allocate memory for native data and load it + size_t fun_alloc; + MP_PLAT_ALLOC_EXEC(fun_data_len, (void **)&fun_data, &fun_alloc); + read_bytes(reader, fun_data, fun_data_len); + + if (kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER) { + // Parse qstr link table and link native code + n_qstr_link = read_uint(reader, NULL); + for (size_t i = 0; i < n_qstr_link; ++i) { + size_t off = read_uint(reader, NULL); + qstr qst = load_qstr(reader, qw); + uint8_t *dest = fun_data + (off >> 2); + if ((off & 3) == 0) { + // Generic 16-bit link + dest[0] = qst & 0xff; + dest[1] = (qst >> 8) & 0xff; + } else { + // Architecture-specific link + arch_link_qstr(dest, (off & 3) == 2, qst); + } + } + } + + if (kind == MP_CODE_NATIVE_PY) { + // Extract prelude for later use + prelude_offset = read_uint(reader, NULL); + const byte *ip = fun_data + prelude_offset; + extract_prelude(&ip, (const byte **)&ip2, &prelude); + } else { + // Load basic scope info for viper and asm + prelude.scope_flags = read_uint(reader, NULL); + prelude.n_pos_args = 0; + prelude.n_kwonly_args = 0; + if (kind == MP_CODE_NATIVE_ASM) { + prelude.n_pos_args = read_uint(reader, NULL); + type_sig = read_uint(reader, NULL); + } + } + #endif } - // create raw_code and return it + if (kind == MP_CODE_BYTECODE || kind == MP_CODE_NATIVE_PY) { + // Load qstrs in prelude + qstr simple_name = load_qstr(reader, qw); + qstr source_file = load_qstr(reader, qw); + ip2[0] = simple_name; + ip2[1] = simple_name >> 8; + ip2[2] = source_file; + ip2[3] = source_file >> 8; + } + + mp_uint_t *const_table = NULL; + if (kind != MP_CODE_NATIVE_ASM) { + // Load constant table for bytecode, native and viper + + // Number of entries in constant table + size_t n_obj = read_uint(reader, NULL); + size_t n_raw_code = read_uint(reader, NULL); + + // Allocate constant table + size_t n_alloc = prelude.n_pos_args + prelude.n_kwonly_args + n_obj + n_raw_code; + if (kind != MP_CODE_BYTECODE) { + ++n_alloc; // additional entry for mp_fun_table + } + const_table = m_new(mp_uint_t, n_alloc); + mp_uint_t *ct = const_table; + + // Load function argument names (initial entries in const_table) + // (viper has n_pos_args=n_kwonly_args=0 so doesn't load any qstrs here) + for (size_t i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { + *ct++ = (mp_uint_t)MP_OBJ_NEW_QSTR(load_qstr(reader, qw)); + } + + #if MICROPY_EMIT_NATIVE + if (kind != MP_CODE_BYTECODE) { + // Populate mp_fun_table entry + *ct++ = (mp_uint_t)(uintptr_t)mp_fun_table; + } + #endif + + // Load constant objects and raw code children + for (size_t i = 0; i < n_obj; ++i) { + *ct++ = (mp_uint_t)load_obj(reader); + } + for (size_t i = 0; i < n_raw_code; ++i) { + *ct++ = (mp_uint_t)(uintptr_t)load_raw_code(reader, qw); + } + } + + // Create raw_code and return it mp_raw_code_t *rc = mp_emit_glue_new_raw_code(); - mp_emit_glue_assign_bytecode(rc, bytecode, - #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS - bc_len, + if (kind == MP_CODE_BYTECODE) { + mp_emit_glue_assign_bytecode(rc, fun_data, + #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS + fun_data_len, + #endif + const_table, + #if MICROPY_PERSISTENT_CODE_SAVE + n_obj, n_raw_code, + #endif + prelude.scope_flags); + + #if MICROPY_EMIT_NATIVE + } else { + #if defined(MP_PLAT_COMMIT_EXEC) + fun_data = MP_PLAT_COMMIT_EXEC(fun_data, fun_data_len); #endif - const_table, - #if MICROPY_PERSISTENT_CODE_SAVE - n_obj, n_raw_code, - #endif - prelude.scope_flags); + + mp_emit_glue_assign_native(rc, kind, + fun_data, fun_data_len, const_table, + #if MICROPY_PERSISTENT_CODE_SAVE + prelude_offset, + n_obj, n_raw_code, + n_qstr_link, NULL, + #endif + prelude.n_pos_args, prelude.scope_flags, type_sig); + #endif + } return rc; } @@ -236,11 +485,18 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { read_bytes(reader, header, sizeof(header)); if (header[0] != 'M' || header[1] != MPY_VERSION - || header[2] != MPY_FEATURE_FLAGS - || header[3] > mp_small_int_bits()) { + || MPY_FEATURE_DECODE_FLAGS(header[2]) != MPY_FEATURE_FLAGS + || header[3] > mp_small_int_bits() + || read_uint(reader, NULL) > QSTR_WINDOW_SIZE) { mp_raise_MpyError(translate("Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.")); } - mp_raw_code_t *rc = load_raw_code(reader); + if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE + && MPY_FEATURE_DECODE_ARCH(header[2]) != MPY_FEATURE_ARCH) { + mp_raise_ValueError(translate("incompatible native .mpy architecture")); + } + qstr_window_t qw; + qw.idx = 0; + mp_raw_code_t *rc = load_raw_code(reader, &qw); reader->close(reader->data); return rc; } @@ -251,12 +507,16 @@ mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) { return mp_raw_code_load(&reader); } +#if MICROPY_HAS_FILE_READER + mp_raw_code_t *mp_raw_code_load_file(const char *filename) { mp_reader_t reader; mp_reader_new_file(&reader, filename); return mp_raw_code_load(&reader); } +#endif // MICROPY_HAS_FILE_READER + #endif // MICROPY_PERSISTENT_CODE_LOAD #if MICROPY_PERSISTENT_CODE_SAVE @@ -279,22 +539,34 @@ STATIC void mp_print_uint(mp_print_t *print, size_t n) { print->print_strn(print->data, (char *)p, buf + sizeof(buf) - p); } -STATIC void save_qstr(mp_print_t *print, qstr qst) { +STATIC void save_qstr(mp_print_t *print, qstr_window_t *qw, qstr qst) { + if (qst <= QSTR_LAST_STATIC) { + // encode static qstr + byte buf[2] = {0, qst & 0xff}; + mp_print_bytes(print, buf, 2); + return; + } + size_t idx = qstr_window_insert(qw, qst); + if (idx < QSTR_WINDOW_SIZE) { + // qstr found in window, encode index to it + mp_print_uint(print, idx << 1 | 1); + return; + } size_t len; const byte *str = qstr_data(qst, &len); - mp_print_uint(print, len); + mp_print_uint(print, len << 1); mp_print_bytes(print, str, len); } STATIC void save_obj(mp_print_t *print, mp_obj_t o) { - if (MP_OBJ_IS_STR_OR_BYTES(o)) { + if (mp_obj_is_str_or_bytes(o)) { byte obj_type; - if (MP_OBJ_IS_STR(o)) { + if (mp_obj_is_str(o)) { obj_type = 's'; } else { obj_type = 'b'; } - mp_uint_t len; + size_t len; const char *str = mp_obj_str_get_data(o, &len); mp_print_bytes(print, &obj_type, 1); mp_print_uint(print, len); @@ -306,10 +578,10 @@ STATIC void save_obj(mp_print_t *print, mp_obj_t o) { // we save numbers using a simplistic text representation // TODO could be improved byte obj_type; - if (MP_OBJ_IS_TYPE(o, &mp_type_int)) { + if (mp_obj_is_type(o, &mp_type_int)) { obj_type = 'i'; #if MICROPY_PY_BUILTINS_COMPLEX - } else if (MP_OBJ_IS_TYPE(o, &mp_type_complex)) { + } else if (mp_obj_is_type(o, &mp_type_complex)) { obj_type = 'c'; #endif } else { @@ -327,52 +599,127 @@ STATIC void save_obj(mp_print_t *print, mp_obj_t o) { } } -STATIC void save_bytecode_qstrs(mp_print_t *print, const byte *ip, const byte *ip_top) { +STATIC void save_bytecode(mp_print_t *print, qstr_window_t *qw, const byte *ip, const byte *ip_top) { while (ip < ip_top) { size_t sz; - uint f = mp_opcode_format(ip, &sz); + uint f = mp_opcode_format(ip, &sz, true); if (f == MP_OPCODE_QSTR) { + mp_print_bytes(print, ip, 1); qstr qst = ip[1] | (ip[2] << 8); - save_qstr(print, qst); + save_qstr(print, qw, qst); + ip += 3; + sz -= 3; } + mp_print_bytes(print, ip, sz); ip += sz; } } -STATIC void save_raw_code(mp_print_t *print, mp_raw_code_t *rc) { - if (rc->kind != MP_CODE_BYTECODE) { - mp_raise_ValueError(translate("can only save bytecode")); +STATIC void save_raw_code(mp_print_t *print, mp_raw_code_t *rc, qstr_window_t *qstr_window) { + // Save function kind and data length + mp_print_uint(print, (rc->fun_data_len << 2) | (rc->kind - MP_CODE_BYTECODE)); + + const byte *ip2; + bytecode_prelude_t prelude; + + if (rc->kind == MP_CODE_BYTECODE) { + // Save prelude + const byte *ip = rc->fun_data; + extract_prelude(&ip, &ip2, &prelude); + size_t prelude_len = ip - (const byte *)rc->fun_data; + const byte *ip_top = (const byte *)rc->fun_data + rc->fun_data_len; + mp_print_bytes(print, rc->fun_data, prelude_len); + + // Save bytecode + save_bytecode(print, qstr_window, ip, ip_top); + } else { + // Save native code + mp_print_bytes(print, rc->fun_data, rc->fun_data_len); + + if (rc->kind == MP_CODE_NATIVE_PY || rc->kind == MP_CODE_NATIVE_VIPER) { + // Save qstr link table for native code + mp_print_uint(print, rc->n_qstr); + for (size_t i = 0; i < rc->n_qstr; ++i) { + mp_print_uint(print, rc->qstr_link[i].off); + save_qstr(print, qstr_window, rc->qstr_link[i].qst); + } + } + + if (rc->kind == MP_CODE_NATIVE_PY) { + // Save prelude size, and extract prelude for later use + mp_print_uint(print, rc->prelude_offset); + const byte *ip = (const byte *)rc->fun_data + rc->prelude_offset; + extract_prelude(&ip, &ip2, &prelude); + } else { + // Save basic scope info for viper and asm + mp_print_uint(print, rc->scope_flags); + prelude.n_pos_args = 0; + prelude.n_kwonly_args = 0; + if (rc->kind == MP_CODE_NATIVE_ASM) { + mp_print_uint(print, rc->n_pos_args); + mp_print_uint(print, rc->type_sig); + } + } } - // save bytecode - mp_print_uint(print, rc->data.u_byte.bc_len); - mp_print_bytes(print, rc->data.u_byte.bytecode, rc->data.u_byte.bc_len); + if (rc->kind == MP_CODE_BYTECODE || rc->kind == MP_CODE_NATIVE_PY) { + // Save qstrs in prelude + save_qstr(print, qstr_window, ip2[0] | (ip2[1] << 8)); // simple_name + save_qstr(print, qstr_window, ip2[2] | (ip2[3] << 8)); // source_file + } - // extract prelude - const byte *ip = rc->data.u_byte.bytecode; + if (rc->kind != MP_CODE_NATIVE_ASM) { + // Save constant table for bytecode, native and viper + + // Number of entries in constant table + mp_print_uint(print, rc->n_obj); + mp_print_uint(print, rc->n_raw_code); + + const mp_uint_t *const_table = rc->const_table; + + // Save function argument names (initial entries in const_table) + // (viper has n_pos_args=n_kwonly_args=0 so doesn't save any qstrs here) + for (size_t i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { + mp_obj_t o = (mp_obj_t)*const_table++; + save_qstr(print, qstr_window, MP_OBJ_QSTR_VALUE(o)); + } + + if (rc->kind != MP_CODE_BYTECODE) { + // Skip saving mp_fun_table entry + ++const_table; + } + + // Save constant objects and raw code children + for (size_t i = 0; i < rc->n_obj; ++i) { + save_obj(print, (mp_obj_t)*const_table++); + } + for (size_t i = 0; i < rc->n_raw_code; ++i) { + save_raw_code(print, (mp_raw_code_t *)(uintptr_t)*const_table++, qstr_window); + } + } +} + +STATIC bool mp_raw_code_has_native(mp_raw_code_t *rc) { + if (rc->kind != MP_CODE_BYTECODE) { + return true; + } + + const byte *ip = rc->fun_data; const byte *ip2; bytecode_prelude_t prelude; extract_prelude(&ip, &ip2, &prelude); - // save qstrs - save_qstr(print, ip2[0] | (ip2[1] << 8)); // simple_name - save_qstr(print, ip2[2] | (ip2[3] << 8)); // source_file - save_bytecode_qstrs(print, ip, rc->data.u_byte.bytecode + rc->data.u_byte.bc_len); + const mp_uint_t *const_table = rc->const_table + + prelude.n_pos_args + prelude.n_kwonly_args + + rc->n_obj; - // save constant table - mp_print_uint(print, rc->data.u_byte.n_obj); - mp_print_uint(print, rc->data.u_byte.n_raw_code); - const mp_uint_t *const_table = rc->data.u_byte.const_table; - for (uint i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { - mp_obj_t o = (mp_obj_t)*const_table++; - save_qstr(print, MP_OBJ_QSTR_VALUE(o)); - } - for (uint i = 0; i < rc->data.u_byte.n_obj; ++i) { - save_obj(print, (mp_obj_t)*const_table++); - } - for (uint i = 0; i < rc->data.u_byte.n_raw_code; ++i) { - save_raw_code(print, (mp_raw_code_t *)(uintptr_t)*const_table++); + for (size_t i = 0; i < rc->n_raw_code; ++i) { + if (mp_raw_code_has_native((mp_raw_code_t *)(uintptr_t)*const_table++)) { + return true; + } } + + return false; } void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) { @@ -381,16 +728,27 @@ void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) { // byte version // byte feature flags // byte number of bits in a small int - byte header[4] = {'M', MPY_VERSION, MPY_FEATURE_FLAGS_DYNAMIC, - #if MICROPY_DYNAMIC_COMPILER - mp_dynamic_compiler.small_int_bits, - #else - mp_small_int_bits(), - #endif + // uint size of qstr window + byte header[4] = { + 'M', + MPY_VERSION, + MPY_FEATURE_ENCODE_FLAGS(MPY_FEATURE_FLAGS_DYNAMIC), + #if MICROPY_DYNAMIC_COMPILER + mp_dynamic_compiler.small_int_bits, + #else + mp_small_int_bits(), + #endif }; + if (mp_raw_code_has_native(rc)) { + header[2] |= MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC); + } mp_print_bytes(print, header, sizeof(header)); + mp_print_uint(print, QSTR_WINDOW_SIZE); - save_raw_code(print, rc); + qstr_window_t qw; + qw.idx = 0; + memset(qw.window, 0, sizeof(qw.window)); + save_raw_code(print, rc, &qw); } // here we define mp_raw_code_save_file depending on the port diff --git a/py/persistentcode.h b/py/persistentcode.h index cbb300e4b3..8ecaea1140 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -30,6 +30,22 @@ #include "py/reader.h" #include "py/emitglue.h" +// The current version of .mpy files +#define MPY_VERSION 4 + +enum { + MP_NATIVE_ARCH_NONE = 0, + MP_NATIVE_ARCH_X86, + MP_NATIVE_ARCH_X64, + MP_NATIVE_ARCH_ARMV6, + MP_NATIVE_ARCH_ARMV6M, + MP_NATIVE_ARCH_ARMV7M, + MP_NATIVE_ARCH_ARMV7EM, + MP_NATIVE_ARCH_ARMV7EMSP, + MP_NATIVE_ARCH_ARMV7EMDP, + MP_NATIVE_ARCH_XTENSA, +}; + mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader); mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len); mp_raw_code_t *mp_raw_code_load_file(const char *filename); diff --git a/py/py.mk b/py/py.mk index f61bad1faf..73c093bd64 100644 --- a/py/py.mk +++ b/py/py.mk @@ -37,19 +37,19 @@ LDFLAGS_MOD += -L$(TOP)/lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto endif endif -#ifeq ($(MICROPY_PY_LWIP),1) -#CFLAGS_MOD += -DMICROPY_PY_LWIP=1 -I../lib/lwip/src/include -I../lib/lwip/src/include/ipv4 -I../extmod/lwip-include -#endif - ifeq ($(MICROPY_PY_LWIP),1) +# A port should add an include path where lwipopts.h can be found (eg extmod/lwip-include) LWIP_DIR = lib/lwip/src -INC += -I$(TOP)/lib/lwip/src/include -I$(TOP)/lib/lwip/src/include/ipv4 -I$(TOP)/extmod/lwip-include +INC += -I$(TOP)/$(LWIP_DIR)/include CFLAGS_MOD += -DMICROPY_PY_LWIP=1 +$(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS_MOD += -Wno-address SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c SRC_MOD += $(addprefix $(LWIP_DIR)/,\ core/def.c \ core/dns.c \ + core/inet_chksum.c \ core/init.c \ + core/ip.c \ core/mem.c \ core/memp.c \ core/netif.c \ @@ -60,16 +60,26 @@ SRC_MOD += $(addprefix $(LWIP_DIR)/,\ core/tcp.c \ core/tcp_in.c \ core/tcp_out.c \ - core/timers.c \ + core/timeouts.c \ core/udp.c \ core/ipv4/autoip.c \ + core/ipv4/dhcp.c \ + core/ipv4/etharp.c \ core/ipv4/icmp.c \ core/ipv4/igmp.c \ - core/ipv4/inet.c \ - core/ipv4/inet_chksum.c \ - core/ipv4/ip_addr.c \ - core/ipv4/ip.c \ - core/ipv4/ip_frag.c \ + core/ipv4/ip4_addr.c \ + core/ipv4/ip4.c \ + core/ipv4/ip4_frag.c \ + core/ipv6/dhcp6.c \ + core/ipv6/ethip6.c \ + core/ipv6/icmp6.c \ + core/ipv6/inet6.c \ + core/ipv6/ip6_addr.c \ + core/ipv6/ip6.c \ + core/ipv6/ip6_frag.c \ + core/ipv6/mld6.c \ + core/ipv6/nd6.c \ + netif/ethernet.c \ ) ifeq ($(MICROPY_PY_LWIP_SLIP),1) CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1 @@ -299,7 +309,7 @@ endif # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% SRC_QSTR_EMITNATIVE = py/emitn% -SRC_QSTR = $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) +SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR = $(addprefix $(TOP)/, $(filter $(SRC_QSTR_EMITNATIVE),$(PY_CORE_O_BASENAME:.o=.c))) diff --git a/py/runtime.c b/py/runtime.c index 72eb2fa4c5..35c6f79319 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -70,7 +71,8 @@ void mp_init(void) { MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; #if MICROPY_ENABLE_SCHEDULER MP_STATE_VM(sched_state) = MP_SCHED_IDLE; - MP_STATE_VM(sched_sp) = 0; + MP_STATE_VM(sched_idx) = 0; + MP_STATE_VM(sched_len) = 0; #endif #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF @@ -232,7 +234,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { if (op == MP_UNARY_OP_NOT) { // "not x" is the negative of whether "x" is true per Python semantics return mp_obj_new_bool(mp_obj_is_true(arg) == 0); - } else if (MP_OBJ_IS_SMALL_INT(arg)) { + } else if (mp_obj_is_small_int(arg)) { mp_int_t val = MP_OBJ_SMALL_INT_VALUE(arg); switch (op) { case MP_UNARY_OP_BOOL: @@ -262,7 +264,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { assert(op == MP_UNARY_OP_INVERT); return MP_OBJ_NEW_SMALL_INT(~val); } - } else if (op == MP_UNARY_OP_HASH && MP_OBJ_IS_STR_OR_BYTES(arg)) { + } else if (op == MP_UNARY_OP_HASH && mp_obj_is_str_or_bytes(arg)) { // fast path for hashing str/bytes GET_STR_HASH(arg, h); if (h == 0) { @@ -340,7 +342,7 @@ mp_obj_t PLACE_IN_ITCM(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t r } else { return mp_const_false; } - } else if (MP_OBJ_IS_TYPE(rhs, &mp_type_tuple)) { + } else if (mp_obj_is_type(rhs, &mp_type_tuple)) { mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(rhs); for (size_t i = 0; i < tuple->len; i++) { rhs = tuple->items[i]; @@ -356,9 +358,9 @@ mp_obj_t PLACE_IN_ITCM(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t r goto unsupported_op; } - if (MP_OBJ_IS_SMALL_INT(lhs)) { + if (mp_obj_is_small_int(lhs)) { mp_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs); - if (MP_OBJ_IS_SMALL_INT(rhs)) { + if (mp_obj_is_small_int(rhs)) { mp_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); // This is a binary operation: lhs_val op rhs_val // We need to be careful to handle overflow; see CERT INT32-C @@ -477,8 +479,7 @@ mp_obj_t PLACE_IN_ITCM(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t r case MP_BINARY_OP_INPLACE_POWER: if (rhs_val < 0) { #if MICROPY_PY_BUILTINS_FLOAT - lhs = mp_obj_new_float(lhs_val); - goto generic_binary_op; + return mp_obj_float_binary_op(op, lhs_val, rhs); #else mp_raise_ValueError(translate("negative power with no float support")); #endif @@ -547,7 +548,7 @@ mp_obj_t PLACE_IN_ITCM(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t r return res; } #if MICROPY_PY_BUILTINS_COMPLEX - } else if (MP_OBJ_IS_TYPE(rhs, &mp_type_complex)) { + } else if (mp_obj_is_type(rhs, &mp_type_complex)) { mp_obj_t res = mp_obj_complex_binary_op(op, lhs_val, 0, rhs); if (res == MP_OBJ_NULL) { goto unsupported_op; @@ -693,7 +694,7 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ // Try to get a hint for the size of the kw_dict uint kw_dict_len = 0; - if (kw_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) { + if (kw_dict != MP_OBJ_NULL && mp_obj_is_type(kw_dict, &mp_type_dict)) { kw_dict_len = mp_obj_dict_len(kw_dict); } @@ -715,7 +716,7 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); args2_len += n_args; - } else if (MP_OBJ_IS_TYPE(pos_seq, &mp_type_tuple) || MP_OBJ_IS_TYPE(pos_seq, &mp_type_list)) { + } else if (mp_obj_is_type(pos_seq, &mp_type_tuple) || mp_obj_is_type(pos_seq, &mp_type_list)) { // optimise the case of a tuple and list // get the items @@ -776,15 +777,15 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ // Note that it can be arbitrary iterator. if (kw_dict == MP_OBJ_NULL) { // pass - } else if (MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) { + } else if (mp_obj_is_type(kw_dict, &mp_type_dict)) { // dictionary mp_map_t *map = mp_obj_dict_get_map(kw_dict); assert(args2_len + 2 * map->used <= args2_alloc); // should have enough, since kw_dict_len is in this case hinted correctly above for (size_t i = 0; i < map->alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { // the key must be a qstr, so intern it if it's a string mp_obj_t key = map->table[i].key; - if (!MP_OBJ_IS_QSTR(key)) { + if (!mp_obj_is_qstr(key)) { key = mp_obj_str_intern_checked(key); } args2[args2_len++] = key; @@ -814,7 +815,7 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ } // the key must be a qstr, so intern it if it's a string - if (!MP_OBJ_IS_QSTR(key)) { + if (!mp_obj_is_qstr(key)) { key = mp_obj_str_intern_checked(key); } @@ -849,7 +850,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob // unpacked items are stored in reverse order into the array pointed to by items void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { size_t seq_len; - if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { + if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) { mp_obj_t *seq_items; mp_obj_get_array(seq_in, &seq_len, &seq_items); if (seq_len < num) { @@ -899,9 +900,13 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { size_t num_right = (num_in >> 8) & 0xff; DEBUG_OP_printf("unpack ex " UINT_FMT " " UINT_FMT "\n", num_left, num_right); size_t seq_len; - if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { + if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) { + // Make the seq variable volatile so the compiler keeps a reference to it, + // since if it's a tuple then seq_items points to the interior of the GC cell + // and mp_obj_new_list may trigger a GC which doesn't trace this and reclaims seq. + volatile mp_obj_t seq = seq_in; mp_obj_t *seq_items; - mp_obj_get_array(seq_in, &seq_len, &seq_items); + mp_obj_get_array(seq, &seq_len, &seq_items); if (seq_len < num_left + num_right) { goto too_short; } @@ -912,6 +917,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { for (size_t i = 0; i < num_left; i++) { items[num_right + 1 + i] = seq_items[num_left - 1 - i]; } + seq = MP_OBJ_NULL; } else { // Generic iterable; this gets a bit messy: we unpack known left length to the // items destination array, then the rest to a dynamically created list. Once the @@ -1013,10 +1019,10 @@ STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun) // Conversion means dealing with static/class methods, callables, and values. // see http://docs.python.org/3/howto/descriptor.html void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest) { - if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) { + if (mp_obj_is_type(member, &mp_type_staticmethod)) { // return just the function dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun; - } else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) { + } else if (mp_obj_is_type(member, &mp_type_classmethod)) { // return a bound method, with self being the type of this object // this type should be the type of the original instance, not the base // type (which is what is passed in the 'type' argument to this function) @@ -1025,11 +1031,11 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t } dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun; dest[1] = MP_OBJ_FROM_PTR(type); - } else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) { + } else if (mp_obj_is_type(member, &mp_type_type)) { // Don't try to bind types (even though they're callable) dest[0] = member; - } else if (MP_OBJ_IS_FUN(member) - || (MP_OBJ_IS_OBJ(member) + } else if (mp_obj_is_fun(member) + || (mp_obj_is_obj(member) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_closure || ((mp_obj_base_t *)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_generator))) { // only functions, closures and generators objects can be bound to self @@ -1053,7 +1059,7 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t } #if MICROPY_PY_BUILTINS_PROPERTY // If self is MP_OBJ_NULL, we looking at the class itself, not an instance. - } else if (MP_OBJ_IS_TYPE(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) { + } else if (mp_obj_is_type(member, &mp_type_property) && mp_obj_is_native_type(type) && self != MP_OBJ_NULL) { // object member is a property; delegate the load to the property // Note: This is an optimisation for code size and execution time. // The proper way to do it is have the functionality just below @@ -1086,14 +1092,13 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) { mp_obj_type_t *type = mp_obj_get_type(obj); // look for built-in names - if (0) { #if MICROPY_CPYTHON_COMPAT - } else if (attr == MP_QSTR___class__) { + if (attr == MP_QSTR___class__) { // a.__class__ is equivalent to type(a) dest[0] = MP_OBJ_FROM_PTR(type); + } else #endif - - } else if (attr == MP_QSTR___next__ && type->iternext != NULL) { + if (attr == MP_QSTR___next__ && type->iternext != NULL) { dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj); dest[1] = obj; @@ -1124,7 +1129,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { mp_raise_AttributeError(translate("no such attribute")); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED // following CPython, we give a more detailed error message for type objects - if (MP_OBJ_IS_TYPE(base, &mp_type_type)) { + if (mp_obj_is_type(base, &mp_type_type)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, translate("type object '%q' has no attribute '%q'"), ((mp_obj_type_t *)MP_OBJ_TO_PTR(base))->name, attr)); @@ -1175,7 +1180,7 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { mp_map_t *locals_map = &type->locals_dict->map; mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); // If base is MP_OBJ_NULL, we looking at the class itself, not an instance. - if (elem != NULL && MP_OBJ_IS_TYPE(elem->value, &mp_type_property) && base != MP_OBJ_NULL) { + if (elem != NULL && mp_obj_is_type(elem->value, &mp_type_property) && base != MP_OBJ_NULL) { // attribute exists and is a property; delegate the store/delete // Note: This is an optimisation for code size and execution time. // The proper way to do it is have the functionality just below in @@ -1464,7 +1469,7 @@ void mp_import_all(mp_obj_t module) { // TODO: Support __all__ mp_map_t *map = &mp_obj_module_get_globals(module)->map; for (size_t i = 0; i < map->alloc; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { // Entry in module global scope may be generated programmatically // (and thus be not a qstr for longer names). Avoid turning it in // qstr if it has '_' and was used exactly to save memory. diff --git a/py/runtime.h b/py/runtime.h index c30252a946..9c35cf6392 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -73,7 +73,7 @@ void mp_handle_pending_tail(mp_uint_t atomic_state); void mp_sched_lock(void); void mp_sched_unlock(void); static inline unsigned int mp_sched_num_pending(void) { - return MP_STATE_VM(sched_sp); + return MP_STATE_VM(sched_len); } bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); #endif @@ -197,8 +197,9 @@ NORETURN void mp_raise_recursion_depth(void); #endif // helper functions for native/viper code -mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type); -mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type); +int mp_native_type_from_qstr(qstr qst); +mp_uint_t mp_native_from_obj(mp_obj_t obj, mp_uint_t type); +mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type); mp_obj_dict_t *mp_native_swap_globals(mp_obj_dict_t *new_globals); mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args); void mp_native_raise(mp_obj_t o); @@ -207,7 +208,9 @@ void mp_native_raise(mp_obj_t o); #define mp_sys_argv (MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_sys_argv_obj))) #if MICROPY_WARNINGS -void mp_warning(const char *msg, ...); +#ifndef mp_warning +void mp_warning(const char *category, const char *msg, ...); +#endif #else #define mp_warning(...) #endif diff --git a/py/scheduler.c b/py/scheduler.c index fea7e0153d..75fa2e5fdd 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -30,6 +30,19 @@ #if MICROPY_ENABLE_SCHEDULER +#define IDX_MASK(i) ((i) & (MICROPY_SCHEDULER_DEPTH - 1)) + +static inline bool mp_sched_full(void) { + MP_STATIC_ASSERT(MICROPY_SCHEDULER_DEPTH <= 255); // MICROPY_SCHEDULER_DEPTH must fit in 8 bits + MP_STATIC_ASSERT((IDX_MASK(MICROPY_SCHEDULER_DEPTH) == 0)); // MICROPY_SCHEDULER_DEPTH must be a power of 2 + + return mp_sched_num_pending() == MICROPY_SCHEDULER_DEPTH; +} + +static inline bool mp_sched_empty(void) { + return mp_sched_num_pending() == 0; +} + // A variant of this is inlined in the VM at the pending exception check void mp_handle_pending(void) { if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) { @@ -51,8 +64,10 @@ void mp_handle_pending(void) { // or by the VM's inlined version of that function. void mp_handle_pending_tail(mp_uint_t atomic_state) { MP_STATE_VM(sched_state) = MP_SCHED_LOCKED; - if (MP_STATE_VM(sched_sp) > 0) { - mp_sched_item_t item = MP_STATE_VM(sched_stack)[--MP_STATE_VM(sched_sp)]; + if (!mp_sched_empty()) { + mp_sched_item_t item = MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_idx)]; + MP_STATE_VM(sched_idx) = IDX_MASK(MP_STATE_VM(sched_idx) + 1); + --MP_STATE_VM(sched_len); MICROPY_END_ATOMIC_SECTION(atomic_state); mp_call_function_1_protected(item.func, item.arg); } else { @@ -87,13 +102,13 @@ void mp_sched_unlock(void) { bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg) { mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); bool ret; - if (MP_STATE_VM(sched_sp) < MICROPY_SCHEDULER_DEPTH) { + if (!mp_sched_full()) { if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } - MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].func = function; - MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].arg = arg; - ++MP_STATE_VM(sched_sp); + uint8_t iput = IDX_MASK(MP_STATE_VM(sched_idx) + MP_STATE_VM(sched_len)++); + MP_STATE_VM(sched_stack)[iput].func = function; + MP_STATE_VM(sched_stack)[iput].arg = arg; ret = true; } else { // schedule stack is full diff --git a/py/showbc.c b/py/showbc.c index a94b2b3a57..b8ba9b706f 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -401,14 +401,9 @@ const byte *mp_bytecode_print_str(const byte *ip) { printf("FOR_ITER " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); break; - case MP_BC_POP_BLOCK: - // pops block and restores the stack - printf("POP_BLOCK"); - break; - - case MP_BC_POP_EXCEPT: - // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate - printf("POP_EXCEPT"); + case MP_BC_POP_EXCEPT_JUMP: + DECODE_ULABEL; // these labels are always forward + printf("POP_EXCEPT_JUMP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); break; case MP_BC_BUILD_TUPLE: diff --git a/py/stream.c b/py/stream.c index 35cbc4e211..0b01c3d8c5 100644 --- a/py/stream.c +++ b/py/stream.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -257,7 +257,7 @@ void mp_stream_write_adaptor(void *self, const char *buf, size_t len) { STATIC mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); - if (!mp_get_stream(args[0])->is_text && MP_OBJ_IS_STR(args[1])) { + if (!mp_get_stream(args[0])->is_text && mp_obj_is_str(args[1])) { mp_raise_ValueError(translate("string not supported; use bytes or bytearray")); } size_t max_len = (size_t)-1; diff --git a/py/stream.h b/py/stream.h index 3aa0245be1..adfa190b13 100644 --- a/py/stream.h +++ b/py/stream.h @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/vm.c b/py/vm.c index 615a550304..17ac860e6e 100644 --- a/py/vm.c +++ b/py/vm.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014-2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -102,13 +102,11 @@ DECODE_ULABEL; /* except labels are always forward */ \ ++exc_sp; \ exc_sp->handler = ip + ulab; \ - exc_sp->val_sp = MP_TAGPTR_MAKE(sp, ((with_or_finally) << 1) | currently_in_except_block); \ + exc_sp->val_sp = MP_TAGPTR_MAKE(sp, ((with_or_finally) << 1)); \ exc_sp->prev_exc = NULL; \ - currently_in_except_block = 0; /* in a try block now */ \ } while (0) #define POP_EXC_BLOCK() \ - currently_in_except_block = MP_TAGPTR_TAG0(exc_sp->val_sp); /* restore previous state */ \ exc_sp--; /* pop back to previous exception handler */ \ CLEAR_SYS_EXC_INFO() /* just clear sys.exc_info(), not compliant, but it shouldn't be used in 1st place */ @@ -129,26 +127,16 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st #endif #if MICROPY_OPT_COMPUTED_GOTO #include "py/vmentrytable.h" - #if MICROPY_OPT_COMPUTED_GOTO_SAVE_SPACE - #define ONE_TRUE_DISPATCH() one_true_dispatch : do { \ - TRACE(ip); \ - MARK_EXC_IP_GLOBAL(); \ - goto *(void *)((char *) && entry_MP_BC_LOAD_CONST_FALSE + entry_table[*ip++]); \ -} while (0) - #define DISPATCH() do { goto one_true_dispatch; } while (0) - #else #define DISPATCH() do { \ TRACE(ip); \ MARK_EXC_IP_GLOBAL(); \ goto *entry_table[*ip++]; \ } while (0) - #define ONE_TRUE_DISPATCH() DISPATCH() - #endif #define DISPATCH_WITH_PEND_EXC_CHECK() goto pending_exception_check #define ENTRY(op) entry_##op #define ENTRY_DEFAULT entry_default #else - #define DISPATCH() break + #define DISPATCH() goto dispatch_loop #define DISPATCH_WITH_PEND_EXC_CHECK() goto pending_exception_check #define ENTRY(op) case op #define ENTRY_DEFAULT default @@ -174,7 +162,6 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st } // variables that are visible to the exception handler (declared volatile) - volatile bool currently_in_except_block = MP_TAGPTR_TAG0(code_state->exc_sp); // 0 or 1, to detect nested exceptions mp_exc_stack_t *volatile exc_sp = MP_TAGPTR_PTR(code_state->exc_sp); // stack grows up, exc_sp points to top of stack #if MICROPY_PY_THREAD_GIL && MICROPY_PY_THREAD_GIL_VM_DIVISOR @@ -210,7 +197,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st for (;;) { dispatch_loop: #if MICROPY_OPT_COMPUTED_GOTO - ONE_TRUE_DISPATCH(); + DISPATCH(); #else TRACE(ip); MARK_EXC_IP_GLOBAL(); @@ -617,7 +604,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st sp -= 2; mp_call_method_n_kw(3, 0, sp); SET_TOP(mp_const_none); - } else if (MP_OBJ_IS_SMALL_INT(TOP())) { + } else if (mp_obj_is_small_int(TOP())) { // Getting here there are two distinct cases: // - unwind return, stack: (..., __exit__, ctx_mgr, ret_val, SMALL_INT(-1)) // - unwind jump, stack: (..., __exit__, ctx_mgr, dest_ip, SMALL_INT(num_exc)) @@ -646,8 +633,6 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st // replacing it with None, which signals END_FINALLY to just // execute the finally handler normally. SET_TOP(mp_const_none); - assert(exc_sp >= exc_stack); - POP_EXC_BLOCK(); } else { // We need to re-raise the exception. We pop __exit__ handler // by copying the exception instance down to the new top-of-stack. @@ -667,7 +652,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st while ((unum & 0x7f) > 0) { unum -= 1; assert(exc_sp >= exc_stack); - if (MP_TAGPTR_TAG1(exc_sp->val_sp)) { + if (MP_TAGPTR_TAG1(exc_sp->val_sp) && exc_sp->handler > ip) { // Getting here the stack looks like: // (..., X, dest_ip) // where X is pointed to by exc_sp->val_sp and in the case @@ -693,7 +678,6 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st DISPATCH_WITH_PEND_EXC_CHECK(); } - // matched against: POP_BLOCK or POP_EXCEPT (anything else?) ENTRY(MP_BC_SETUP_EXCEPT) : ENTRY(MP_BC_SETUP_FINALLY) : { MARK_EXC_IP_SELECTIVE(); @@ -711,8 +695,10 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st // if TOS is an integer, finishes coroutine and returns control to caller // if TOS is an exception, reraises the exception if (TOP() == mp_const_none) { + assert(exc_sp >= exc_stack); + POP_EXC_BLOCK(); sp--; - } else if (MP_OBJ_IS_SMALL_INT(TOP())) { + } else if (mp_obj_is_small_int(TOP())) { // We finished "finally" coroutine and now dispatch back // to our caller, based on TOS value mp_int_t cause = MP_OBJ_SMALL_INT_VALUE(POP()); @@ -774,19 +760,13 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st DISPATCH_WITH_PEND_EXC_CHECK(); } - // matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH - ENTRY(MP_BC_POP_BLOCK) : - // we are exiting an exception handler, so pop the last one of the exception-stack + ENTRY(MP_BC_POP_EXCEPT_JUMP) : { assert(exc_sp >= exc_stack); - POP_EXC_BLOCK(); - DISPATCH(); - - // matched against: SETUP_EXCEPT - ENTRY(MP_BC_POP_EXCEPT) : - assert(exc_sp >= exc_stack); - assert(currently_in_except_block); - POP_EXC_BLOCK(); - DISPATCH(); + POP_EXC_BLOCK(); + DECODE_ULABEL; + ip += ulab; + DISPATCH_WITH_PEND_EXC_CHECK(); + } ENTRY(MP_BC_BUILD_TUPLE) : { MARK_EXC_IP_SELECTIVE(); @@ -919,7 +899,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; code_state->sp = sp; - code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); + code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, 0); mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1); #if !MICROPY_ENABLE_PYSTACK if (new_state == NULL) { @@ -955,7 +935,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; code_state->sp = sp; - code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); + code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, 0); mp_call_args_t out_args; mp_call_prepare_args_n_kw_var(false, unum, sp, &out_args); @@ -998,7 +978,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; code_state->sp = sp; - code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); + code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, 0); size_t n_args = unum & 0xff; size_t n_kw = (unum >> 8) & 0xff; @@ -1038,7 +1018,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; code_state->sp = sp; - code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); + code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, 0); mp_call_args_t out_args; mp_call_prepare_args_n_kw_var(true, unum, sp, &out_args); @@ -1076,7 +1056,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st unwind_return: // Search for and execute finally handlers that aren't already active while (exc_sp >= exc_stack) { - if (!currently_in_except_block && MP_TAGPTR_TAG1(exc_sp->val_sp)) { + if (MP_TAGPTR_TAG1(exc_sp->val_sp) && exc_sp->handler > ip) { // Found a finally handler that isn't active. // Getting here the stack looks like: // (..., X, [iter0, iter1, ...,] ret_val) @@ -1129,7 +1109,7 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st mp_uint_t unum = *ip; mp_obj_t obj; if (unum == 2) { - mp_warning("exception chaining not supported"); + mp_warning(NULL, "exception chaining not supported"); // ignore (pop) "from" argument sp--; } @@ -1158,12 +1138,12 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st nlr_pop(); code_state->ip = ip; code_state->sp = sp; - code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); + code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, 0); return MP_VM_RETURN_YIELD; ENTRY(MP_BC_YIELD_FROM) : { MARK_EXC_IP_SELECTIVE(); -// #define EXC_MATCH(exc, type) MP_OBJ_IS_TYPE(exc, type) +// #define EXC_MATCH(exc, type) mp_obj_is_type(exc, type) #define EXC_MATCH(exc, type) mp_obj_exception_match(exc, type) #define GENERATOR_EXIT_IF_NEEDED(t) if (t != MP_OBJ_NULL && EXC_MATCH(t, MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) { mp_obj_t raise_t = mp_make_raise_obj(t); RAISE(raise_t); \ } @@ -1433,7 +1413,8 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st mp_obj_exception_add_traceback(MP_OBJ_FROM_PTR(nlr.ret_val), source_file, source_line, block_name); } - while (currently_in_except_block) { + while (exc_sp >= exc_stack && exc_sp->handler <= code_state->ip) { + // nested exception assert(exc_sp >= exc_stack); @@ -1446,9 +1427,6 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st } if (exc_sp >= exc_stack) { - // set flag to indicate that we are now handling an exception - currently_in_except_block = 1; - // catch exception and pass to byte code code_state->ip = exc_sp->handler; mp_obj_t *sp = MP_TAGPTR_PTR(exc_sp->val_sp); @@ -1474,7 +1452,6 @@ mp_vm_return_kind_t PLACE_IN_ITCM(mp_execute_bytecode)(mp_code_state_t * code_st fastn = &code_state->state[n_state - 1]; exc_stack = (mp_exc_stack_t *)(code_state->state + n_state); // variables that are visible to the exception handler (declared volatile) - currently_in_except_block = MP_TAGPTR_TAG0(code_state->exc_sp); // 0 or 1, to detect nested exceptions exc_sp = MP_TAGPTR_PTR(code_state->exc_sp); // stack grows up, exc_sp points to top of stack goto unwind_loop; diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 0f6c5e96d3..ce88d3a789 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -86,8 +86,7 @@ static entry_table_type const PLACE_IN_DTCM_DATA(entry_table[256]) = { [MP_BC_GET_ITER] = COMPUTE_ENTRY(&& entry_MP_BC_GET_ITER), [MP_BC_GET_ITER_STACK] = COMPUTE_ENTRY(&& entry_MP_BC_GET_ITER_STACK), [MP_BC_FOR_ITER] = COMPUTE_ENTRY(&& entry_MP_BC_FOR_ITER), - [MP_BC_POP_BLOCK] = COMPUTE_ENTRY(&& entry_MP_BC_POP_BLOCK), - [MP_BC_POP_EXCEPT] = COMPUTE_ENTRY(&& entry_MP_BC_POP_EXCEPT), + [MP_BC_POP_EXCEPT_JUMP] = COMPUTE_ENTRY(&& entry_MP_BC_POP_EXCEPT_JUMP), [MP_BC_BUILD_TUPLE] = COMPUTE_ENTRY(&& entry_MP_BC_BUILD_TUPLE), [MP_BC_BUILD_LIST] = COMPUTE_ENTRY(&& entry_MP_BC_BUILD_LIST), [MP_BC_BUILD_MAP] = COMPUTE_ENTRY(&& entry_MP_BC_BUILD_MAP), diff --git a/py/vstr.c b/py/vstr.c index 2b78fc5c83..acc957e778 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/warning.c b/py/warning.c index d516eabddf..71a3ac59ab 100644 --- a/py/warning.c +++ b/py/warning.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * SPDX-FileCopyrightText: Copyright (c) 2015-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,10 +33,15 @@ #if MICROPY_WARNINGS -void mp_warning(const char *msg, ...) { +void mp_warning(const char *category, const char *msg, ...) { + if (category == NULL) { + category = "Warning"; + } + mp_print_str(MICROPY_ERROR_PRINTER, category); + mp_print_str(MICROPY_ERROR_PRINTER, ": "); + va_list args; va_start(args, msg); - mp_print_str(MICROPY_ERROR_PRINTER, "Warning: "); mp_vprintf(MICROPY_ERROR_PRINTER, msg, args); mp_print_str(MICROPY_ERROR_PRINTER, "\n"); va_end(args); @@ -43,7 +49,7 @@ void mp_warning(const char *msg, ...) { void mp_emitter_warning(pass_kind_t pass, const char *msg) { if (pass == MP_PASS_CODE_SIZE) { - mp_warning(msg, NULL); + mp_warning(NULL, msg); } } diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index 5cacfa0691..c2f367e21f 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -96,14 +96,14 @@ STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); busio_uart_obj_t *uart = args[ARG_uart].u_obj; - if (!MP_OBJ_IS_TYPE(uart, &busio_uart_type)) { + if (!mp_obj_is_type(uart, &busio_uart_type)) { mp_raise_ValueError(translate("Expected a UART")); } digitalio_digitalinout_obj_t *rts = args[ARG_rts].u_obj; digitalio_digitalinout_obj_t *cts = args[ARG_cts].u_obj; - if (!MP_OBJ_IS_TYPE(rts, &digitalio_digitalinout_type) || - !MP_OBJ_IS_TYPE(cts, &digitalio_digitalinout_type)) { + if (!mp_obj_is_type(rts, &digitalio_digitalinout_type) || + !mp_obj_is_type(cts, &digitalio_digitalinout_type)) { mp_raise_ValueError(translate("Expected a DigitalInOut")); } @@ -431,7 +431,7 @@ STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) { + if (!mp_obj_is_type(args[ARG_address].u_obj, &bleio_address_type)) { mp_raise_TypeError(translate("Expected an Address")); } diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c index 56e8a013ff..15d5d2bda3 100644 --- a/shared-bindings/_bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -136,7 +136,7 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o switch (op) { // Two Addresses are equal if their address bytes and address_type are equal case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &bleio_address_type)) { + if (mp_obj_is_type(rhs_in, &bleio_address_type)) { bleio_address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in); bleio_address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in); return mp_obj_new_bool( diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index b69b71d0c9..35bb58d270 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -89,12 +89,12 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t service_obj = args[ARG_service].u_obj; - if (!MP_OBJ_IS_TYPE(service_obj, &bleio_service_type)) { + if (!mp_obj_is_type(service_obj, &bleio_service_type)) { mp_raise_TypeError(translate("Expected a Service")); } const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { mp_raise_TypeError(translate("Expected a UUID")); } diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index ddc0c42253..149c060ac2 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -80,7 +80,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size); } - if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + if (!mp_obj_is_type(characteristic, &bleio_characteristic_type)) { mp_raise_TypeError(translate("Expected a Characteristic")); } diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c index 0eee9d7040..d79c9dbf31 100644 --- a/shared-bindings/_bleio/Descriptor.c +++ b/shared-bindings/_bleio/Descriptor.c @@ -85,12 +85,12 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t characteristic_obj = args[ARG_characteristic].u_obj; - if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) { + if (!mp_obj_is_type(characteristic_obj, &bleio_characteristic_type)) { mp_raise_TypeError(translate("Expected a Characteristic")); } const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { mp_raise_TypeError(translate("Expected a UUID")); } diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c index b54a48230b..e9e9a64a7a 100644 --- a/shared-bindings/_bleio/PacketBuffer.c +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -78,7 +78,7 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size); } - if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + if (!mp_obj_is_type(characteristic, &bleio_characteristic_type)) { mp_raise_TypeError(translate("Expected a Characteristic")); } diff --git a/shared-bindings/_bleio/ScanResults.c b/shared-bindings/_bleio/ScanResults.c index 9dca90c38a..7cf77b61aa 100644 --- a/shared-bindings/_bleio/ScanResults.c +++ b/shared-bindings/_bleio/ScanResults.c @@ -37,7 +37,7 @@ //| by a `_bleio.Adapter`: it has no user-visible constructor.""" //| STATIC mp_obj_t scanresults_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &bleio_scanresults_type)); + mp_check_self(mp_obj_is_type(self_in, &bleio_scanresults_type)); bleio_scanresults_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t scan_entry = common_hal_bleio_scanresults_next(self); if (scan_entry != mp_const_none) { diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c index 6657c7e73f..913e70b28a 100644 --- a/shared-bindings/_bleio/Service.c +++ b/shared-bindings/_bleio/Service.c @@ -59,7 +59,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mp_obj_t uuid_obj = args[ARG_uuid].u_obj; - if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) { + if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) { mp_raise_TypeError(translate("Expected a UUID")); } diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c index 2da54c1d5d..d4adbd3d83 100644 --- a/shared-bindings/_bleio/UUID.c +++ b/shared-bindings/_bleio/UUID.c @@ -60,7 +60,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co const mp_obj_t value = pos_args[0]; uint8_t uuid128[16]; - if (MP_OBJ_IS_INT(value)) { + if (mp_obj_is_int(value)) { mp_int_t uuid16 = mp_obj_get_int(value); if (uuid16 < 0 || uuid16 > 0xffff) { mp_raise_ValueError(translate("UUID integer value must be 0-0xffff")); @@ -70,7 +70,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co common_hal_bleio_uuid_construct(self, uuid16, NULL); } else { - if (MP_OBJ_IS_STR(value)) { + if (mp_obj_is_str(value)) { // 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' GET_STR_DATA_LEN(value, chars, len); char hex[32]; @@ -256,7 +256,7 @@ STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_ switch (op) { // Two UUID's are equal if their uuid16 values match or their uuid128 values match. case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &bleio_uuid_type)) { + if (mp_obj_is_type(rhs_in, &bleio_uuid_type)) { if (common_hal_bleio_uuid_get_size(lhs_in) == 16 && common_hal_bleio_uuid_get_size(rhs_in) == 16) { return mp_obj_new_bool(common_hal_bleio_uuid_get_uuid16(lhs_in) == diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c index b9d68abaed..06c9da7b85 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -117,7 +117,7 @@ STATIC mp_obj_dict_t bleio_module_globals; //| mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) { #if CIRCUITPY_BLEIO_HCI - if (adapter_obj != mp_const_none && !MP_OBJ_IS_TYPE(adapter_obj, &bleio_adapter_type)) { + if (adapter_obj != mp_const_none && !mp_obj_is_type(adapter_obj, &bleio_adapter_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), bleio_adapter_type.name); } diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c index b98a124600..2441e3ba5e 100644 --- a/shared-bindings/_pew/PewPew.c +++ b/shared-bindings/_pew/PewPew.c @@ -92,7 +92,7 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, } for (size_t i = 0; i < rows_size; ++i) { - if (!MP_OBJ_IS_TYPE(rows[i], &digitalio_digitalinout_type)) { + if (!mp_obj_is_type(rows[i], &digitalio_digitalinout_type)) { mp_raise_TypeError(translate("Row entry must be digitalio.DigitalInOut")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(rows[i]); @@ -102,7 +102,7 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, } for (size_t i = 0; i < cols_size; ++i) { - if (!MP_OBJ_IS_TYPE(cols[i], &digitalio_digitalinout_type)) { + if (!mp_obj_is_type(cols[i], &digitalio_digitalinout_type)) { mp_raise_TypeError(translate("Column entry must be digitalio.DigitalInOut")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(cols[i]); @@ -111,7 +111,7 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, } } - if (!MP_OBJ_IS_TYPE(args[ARG_buttons].u_obj, + if (!mp_obj_is_type(args[ARG_buttons].u_obj, &digitalio_digitalinout_type)) { mp_raise_TypeError(translate("buttons must be digitalio.DigitalInOut")); } diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index 22923e97d5..2597ca972b 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -120,7 +120,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a } static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t *parsed) { - if (!MP_OBJ_IS_STR(byteorder_obj)) { + if (!mp_obj_is_str(byteorder_obj)) { mp_raise_TypeError(translate("byteorder is not a string")); } @@ -306,7 +306,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp if (0) { #if MICROPY_PY_BUILTINS_SLICE - } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { mp_bound_slice_t slice; size_t length = common_hal__pixelbuf_pixelbuf_get_len(self_in); diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c index 5e87bacab1..4c1b138f36 100644 --- a/shared-bindings/_pixelbuf/__init__.c +++ b/shared-bindings/_pixelbuf/__init__.c @@ -51,7 +51,7 @@ //| STATIC mp_obj_t pixelbuf_colorwheel(mp_obj_t n) { - return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_get_float(n))); + return MP_OBJ_NEW_SMALL_INT(colorwheel(mp_obj_is_small_int(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_get_float(n))); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_colorwheel_obj, pixelbuf_colorwheel); diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 0e3f08da59..2c286ca8de 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -77,7 +77,7 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { mp_obj_t native_display = mp_instance_cast_to_native_base(args[6], &displayio_display_type); - if (!MP_OBJ_IS_TYPE(native_display, &displayio_display_type)) { + if (!mp_obj_is_type(native_display, &displayio_display_type)) { mp_raise_TypeError(translate("argument num/types mismatch")); } displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display); diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index f021e9abc5..89c0177051 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -162,7 +162,7 @@ STATIC void validate_length(aesio_aes_obj_t *self, size_t src_length, //| STATIC mp_obj_t aesio_aes_encrypt_into(mp_obj_t aesio_obj, mp_obj_t src, mp_obj_t dest) { - if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) { + if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); } // Convert parameters into expected types. @@ -192,7 +192,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj, //| STATIC mp_obj_t aesio_aes_decrypt_into(mp_obj_t aesio_obj, mp_obj_t src, mp_obj_t dest) { - if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) { + if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); } // Convert parameters into expected types. @@ -214,7 +214,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_decrypt_into_obj, aesio_aes_decrypt_into); STATIC mp_obj_t aesio_aes_get_mode(mp_obj_t aesio_obj) { - if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) { + if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); } aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj); @@ -223,7 +223,7 @@ STATIC mp_obj_t aesio_aes_get_mode(mp_obj_t aesio_obj) { MP_DEFINE_CONST_FUN_OBJ_1(aesio_aes_get_mode_obj, aesio_aes_get_mode); STATIC mp_obj_t aesio_aes_set_mode(mp_obj_t aesio_obj, mp_obj_t mode_obj) { - if (!MP_OBJ_IS_TYPE(aesio_obj, &aesio_aes_type)) { + if (!mp_obj_is_type(aesio_obj, &aesio_aes_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), aesio_aes_type.name); } aesio_aes_obj_t *self = MP_OBJ_TO_PTR(aesio_obj); diff --git a/shared-bindings/alarm/SleepMemory.c b/shared-bindings/alarm/SleepMemory.c index 9ca0ec0472..18226eb9db 100644 --- a/shared-bindings/alarm/SleepMemory.c +++ b/shared-bindings/alarm/SleepMemory.c @@ -104,7 +104,7 @@ STATIC mp_obj_t alarm_sleep_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, m alarm_sleep_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); if (0) { #if MICROPY_PY_BUILTINS_SLICE - } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(common_hal_alarm_sleep_memory_get_length(self), index_in, &slice)) { mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); @@ -114,10 +114,10 @@ STATIC mp_obj_t alarm_sleep_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, m // Assign size_t src_len = slice.stop - slice.start; uint8_t *src_items; - if (MP_OBJ_IS_TYPE(value, &mp_type_array) || - MP_OBJ_IS_TYPE(value, &mp_type_bytearray) || - MP_OBJ_IS_TYPE(value, &mp_type_memoryview) || - MP_OBJ_IS_TYPE(value, &mp_type_bytes)) { + if (mp_obj_is_type(value, &mp_type_array) || + mp_obj_is_type(value, &mp_type_bytearray) || + mp_obj_is_type(value, &mp_type_memoryview) || + mp_obj_is_type(value, &mp_type_bytes)) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != src_len) { diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 11b96ff240..74ec765ef4 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -72,9 +72,9 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { for (size_t i = 0; i < n_args; i++) { - if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pinalarm_type) || - MP_OBJ_IS_TYPE(objs[i], &alarm_time_timealarm_type) || - MP_OBJ_IS_TYPE(objs[i], &alarm_touch_touchalarm_type)) { + if (mp_obj_is_type(objs[i], &alarm_pin_pinalarm_type) || + mp_obj_is_type(objs[i], &alarm_time_timealarm_type) || + mp_obj_is_type(objs[i], &alarm_touch_touchalarm_type)) { continue; } mp_raise_TypeError_varg(translate("Expected an alarm")); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 5a648e1651..4fc42c3412 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -188,13 +188,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); - if (!MP_OBJ_IS_SMALL_INT(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) { + if (!mp_obj_is_small_int(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) { mp_raise_TypeError(translate("destination_length must be an int >= 0")); } uint32_t length = MP_OBJ_SMALL_INT_VALUE(destination_length); mp_buffer_info_t bufinfo; - if (MP_OBJ_IS_TYPE(destination, &mp_type_fileio)) { + if (mp_obj_is_type(destination, &mp_type_fileio)) { mp_raise_NotImplementedError(translate("Cannot record to a file")); } else if (mp_get_buffer(destination, &bufinfo, MP_BUFFER_WRITE)) { if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) { diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 5cf6deb2ed..5164b25491 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -74,7 +74,7 @@ STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); self->base.type = &audioio_wavefile_type; - if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) { + if (!mp_obj_is_type(args[0], &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } uint8_t *buffer = NULL; diff --git a/shared-bindings/audiomp3/MP3Decoder.c b/shared-bindings/audiomp3/MP3Decoder.c index bdbd14e9e0..28f71f17c7 100644 --- a/shared-bindings/audiomp3/MP3Decoder.c +++ b/shared-bindings/audiomp3/MP3Decoder.c @@ -72,7 +72,7 @@ STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar audiomp3_mp3file_obj_t *self = m_new_obj(audiomp3_mp3file_obj_t); self->base.type = &audiomp3_mp3file_type; - if (!MP_OBJ_IS_TYPE(args[0], &mp_type_fileio)) { + if (!mp_obj_is_type(args[0], &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } uint8_t *buffer = NULL; @@ -137,7 +137,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_file_obj, audiomp3_mp3file_obj_ge STATIC mp_obj_t audiomp3_mp3file_obj_set_file(mp_obj_t self_in, mp_obj_t file) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - if (!MP_OBJ_IS_TYPE(file, &mp_type_fileio)) { + if (!mp_obj_is_type(file, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } common_hal_audiomp3_mp3file_set_file(self, file); diff --git a/shared-bindings/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index 3d352e45c2..2a5195d1a4 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -50,7 +50,7 @@ STATIC void extract_tuple(mp_obj_t xy_tuple, int16_t *x, int16_t *y, int16_t x_d if (xy_tuple == mp_const_none) { *x = x_default; *y = y_default; - } else if (!MP_OBJ_IS_OBJ(xy_tuple)) { + } else if (!mp_obj_is_obj(xy_tuple)) { mp_raise_ValueError(translate("clip point must be (x,y) tuple")); } else { mp_obj_t *items; @@ -401,7 +401,7 @@ STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!MP_OBJ_IS_TYPE(args[ARG_bitmap].u_obj, &displayio_bitmap_type)) { + if (!mp_obj_is_type(args[ARG_bitmap].u_obj, &displayio_bitmap_type)) { mp_raise_TypeError(NULL); } displayio_bitmap_t *bitmap = MP_OBJ_TO_PTR(args[ARG_bitmap].u_obj); @@ -471,12 +471,12 @@ STATIC mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!MP_OBJ_IS_TYPE(args[ARG_bitmap].u_obj, &displayio_bitmap_type)) { + if (!mp_obj_is_type(args[ARG_bitmap].u_obj, &displayio_bitmap_type)) { mp_raise_TypeError(NULL); } displayio_bitmap_t *bitmap = MP_OBJ_TO_PTR(args[ARG_bitmap].u_obj); - if (!MP_OBJ_IS_TYPE(args[ARG_file].u_obj, &mp_type_fileio)) { + if (!mp_obj_is_type(args[ARG_file].u_obj, &mp_type_fileio)) { mp_raise_TypeError(NULL); } pyb_file_obj_t *file = MP_OBJ_TO_PTR(args[ARG_file].u_obj); diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index e64f17b145..9bffdf7656 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -424,7 +424,7 @@ const mp_obj_type_t busio_spi_type = { }; busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj) { - if (!MP_OBJ_IS_TYPE(obj, &busio_spi_type)) { + if (!mp_obj_is_type(obj, &busio_spi_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), busio_spi_type.name); } return MP_OBJ_TO_PTR(obj); diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 0874bed550..ca88a5a74b 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -381,7 +381,7 @@ const mp_obj_type_t digitalio_digitalinout_type = { // Helper for validating digitalio.DigitalInOut arguments digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj) { - if (!MP_OBJ_IS_TYPE(obj, &digitalio_digitalinout_type)) { + if (!mp_obj_is_type(obj, &digitalio_digitalinout_type)) { mp_raise_TypeError(translate("argument num/types mismatch")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj); diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 900428b6e4..058b8db670 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -150,7 +150,7 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + if (mp_obj_is_type(index_obj, &mp_type_slice)) { // TODO(tannewt): Implement subscr after slices support start, stop and step tuples. mp_raise_NotImplementedError(translate("Slices not supported")); return mp_const_none; @@ -158,7 +158,7 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val uint16_t x = 0; uint16_t y = 0; - if (MP_OBJ_IS_SMALL_INT(index_obj)) { + if (mp_obj_is_small_int(index_obj)) { mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); uint16_t width = common_hal_displayio_bitmap_get_width(self); x = i % width; diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 75e210db89..0eed34d574 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -309,7 +309,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { displayio_group_t *self = native_group(self_in); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + if (mp_obj_is_type(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError(translate("Slices not supported")); } else { size_t index = mp_get_index(&displayio_group_type, common_hal_displayio_group_get_len(self), index_obj, false); diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index ae0948b879..d304374664 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -98,7 +98,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_i2cdisplay_reset_obj, displayio_i2cdisplay_o //| STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj); - if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) { + if (!mp_obj_is_small_int(command_obj) || command_int > 255 || command_int < 0) { mp_raise_ValueError(translate("Command must be an int between 0 and 255")); } uint8_t command = command_int; diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index e41f54edfb..71591868d4 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -78,7 +78,7 @@ STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_arg_check_num(n_args, kw_args, 1, 1, false); - if (!MP_OBJ_IS_TYPE(pos_args[0], &mp_type_fileio)) { + if (!mp_obj_is_type(pos_args[0], &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index dc71c0560c..eeb0db4736 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -109,7 +109,7 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val return MP_OBJ_NULL; // op not supported } // Slicing not supported. Use a duplicate Palette to swap multiple colors atomically. - if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + if (mp_obj_is_type(index_in, &mp_type_slice)) { return MP_OBJ_NULL; } displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); @@ -120,8 +120,8 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val } // Convert a tuple or list to a bytearray. - if (MP_OBJ_IS_TYPE(value, &mp_type_tuple) || - MP_OBJ_IS_TYPE(value, &mp_type_list)) { + if (mp_obj_is_type(value, &mp_type_tuple) || + mp_obj_is_type(value, &mp_type_list)) { value = mp_type_bytes.make_new(&mp_type_bytes, 1, &value, NULL); } diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 084628328d..efa64dddf4 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -110,7 +110,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_parallelbus_reset_obj, displayio_parallelbus //| STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj); - if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) { + if (!mp_obj_is_small_int(command_obj) || command_int > 255 || command_int < 0) { mp_raise_ValueError(translate("Command must be an int between 0 and 255")); } uint8_t command = command_int; diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index dee0d7a686..fbacd361af 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -90,12 +90,12 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ displayio_shape_t *bmp = MP_OBJ_TO_PTR(native); bitmap_width = bmp->width; bitmap_height = bmp->height; - } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { + } else if (mp_obj_is_type(bitmap, &displayio_bitmap_type)) { displayio_bitmap_t *bmp = MP_OBJ_TO_PTR(bitmap); native = bitmap; bitmap_width = bmp->width; bitmap_height = bmp->height; - } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_ondiskbitmap_type)) { + } else if (mp_obj_is_type(bitmap, &displayio_ondiskbitmap_type)) { displayio_ondiskbitmap_t *bmp = MP_OBJ_TO_PTR(bitmap); native = bitmap; bitmap_width = bmp->width; @@ -104,8 +104,8 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_bitmap); } mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; - if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type) && - !MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type)) { + if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) && + !mp_obj_is_type(pixel_shader, &displayio_palette_type)) { mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); } uint16_t tile_width = args[ARG_tile_width].u_int; @@ -300,7 +300,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_til STATIC mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { displayio_tilegrid_t *self = native_tilegrid(self_in); - if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); } @@ -343,12 +343,12 @@ STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v displayio_tilegrid_t *self = native_tilegrid(self_in); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + if (mp_obj_is_type(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError(translate("Slices not supported")); } else { uint16_t x = 0; uint16_t y = 0; - if (MP_OBJ_IS_SMALL_INT(index_obj)) { + if (mp_obj_is_small_int(index_obj)) { mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); uint16_t width = common_hal_displayio_tilegrid_get_width(self); x = i % width; diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c index 367f1ccce4..0776839939 100644 --- a/shared-bindings/gamepad/GamePad.c +++ b/shared-bindings/gamepad/GamePad.c @@ -111,7 +111,7 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, } gamepad_obj_t *gamepad_singleton = MP_STATE_VM(gamepad_singleton); if (!gamepad_singleton || - !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepad_type)) { + !mp_obj_is_type(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepad_type)) { gamepad_singleton = m_new_ll_obj(gamepad_obj_t); gamepad_singleton->base.type = &gamepad_type; if (!MP_STATE_VM(gamepad_singleton)) { diff --git a/shared-bindings/gamepadshift/GamePadShift.c b/shared-bindings/gamepadshift/GamePadShift.c index 18f9876b77..17dbb63053 100644 --- a/shared-bindings/gamepadshift/GamePadShift.c +++ b/shared-bindings/gamepadshift/GamePadShift.c @@ -69,7 +69,7 @@ STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args, gamepadshift_obj_t *gamepad_singleton = MP_STATE_VM(gamepad_singleton); if (!gamepad_singleton || - !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), + !mp_obj_is_type(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepadshift_type)) { gamepad_singleton = m_new_ll_obj(gamepadshift_obj_t); gamepad_singleton->base.type = &gamepadshift_type; diff --git a/shared-bindings/gnss/GNSS.c b/shared-bindings/gnss/GNSS.c index a3563b7fd6..2578e9fdca 100644 --- a/shared-bindings/gnss/GNSS.c +++ b/shared-bindings/gnss/GNSS.c @@ -48,14 +48,14 @@ STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, const mp mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); unsigned long selection = 0; - if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &gnss_satellitesystem_type)) { + if (mp_obj_is_type(args[ARG_system].u_obj, &gnss_satellitesystem_type)) { selection |= gnss_satellitesystem_obj_to_type(args[ARG_system].u_obj); - } else if (MP_OBJ_IS_TYPE(args[ARG_system].u_obj, &mp_type_list)) { + } else if (mp_obj_is_type(args[ARG_system].u_obj, &mp_type_list)) { size_t systems_size = 0; mp_obj_t *systems; mp_obj_list_get(args[ARG_system].u_obj, &systems_size, &systems); for (size_t i = 0; i < systems_size; ++i) { - if (!MP_OBJ_IS_TYPE(systems[i], &gnss_satellitesystem_type)) { + if (!mp_obj_is_type(systems[i], &gnss_satellitesystem_type)) { mp_raise_TypeError(translate("System entry must be gnss.SatelliteSystem")); } selection |= gnss_satellitesystem_obj_to_type(systems[i]); diff --git a/shared-bindings/i2cperipheral/I2CPeripheral.c b/shared-bindings/i2cperipheral/I2CPeripheral.c index 9192d61ec5..ac136d7e18 100644 --- a/shared-bindings/i2cperipheral/I2CPeripheral.c +++ b/shared-bindings/i2cperipheral/I2CPeripheral.c @@ -108,7 +108,7 @@ STATIC mp_obj_t i2cperipheral_i2c_peripheral_make_new(const mp_obj_type_t *type, //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj_deinit(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_type)); i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_i2cperipheral_i2c_peripheral_deinit(self); return mp_const_none; @@ -127,7 +127,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(i2cperipheral_i2c_peripheral_deinit_obj, i2cperipheral //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_type)); + mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_type)); i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_i2cperipheral_i2c_peripheral_deinit(self); return mp_const_none; @@ -142,7 +142,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral___exit__ //| :rtype: ~i2cperipheral.I2CPeripheralRequest""" //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_type)); + mp_check_self(mp_obj_is_type(pos_args[0], &i2cperipheral_i2c_peripheral_type)); i2cperipheral_i2c_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); if (common_hal_i2cperipheral_i2c_peripheral_deinited(self)) { raise_deinited_error(); @@ -253,7 +253,7 @@ STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_make_new(const mp_obj_type_ //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); return mp_const_none; @@ -264,7 +264,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request_ //| """The I2C address of the request.""" //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_address(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(self->address); } @@ -274,7 +274,7 @@ MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_address_obj, i2cpe //| """The I2C main controller is reading from this peripheral.""" //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_read(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(self->is_read); } @@ -284,7 +284,7 @@ MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_read_obj, i2cpe //| """Is Repeated Start Condition.""" //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_get_is_restart(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(self->is_restart); } @@ -300,7 +300,7 @@ MP_DEFINE_CONST_PROP_GET(i2cperipheral_i2c_peripheral_request_is_restart_obj, i2 //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(pos_args[0], &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); enum { ARG_n, ARG_ack }; static const mp_arg_t allowed_args[] = { @@ -358,7 +358,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(i2cperipheral_i2c_peripheral_request_read_obj, 1, i2c //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_write(mp_obj_t self_in, mp_obj_t buf_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!self->is_read) { @@ -392,7 +392,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cperipheral_i2c_peripheral_request_write_obj, //| ... //| STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_ack(uint n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(args[0], &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); @@ -406,7 +406,7 @@ STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_ack(uint n_args, const mp_o MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cperipheral_i2c_peripheral_request_ack_obj, 1, 2, i2cperipheral_i2c_peripheral_request_ack); STATIC mp_obj_t i2cperipheral_i2c_peripheral_request_close(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cperipheral_i2c_peripheral_request_type)); + mp_check_self(mp_obj_is_type(self_in, &i2cperipheral_i2c_peripheral_request_type)); i2cperipheral_i2c_peripheral_request_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_i2cperipheral_i2c_peripheral_close(self->peripheral); diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index 62a54560ef..cef4c7c4ce 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -61,7 +61,7 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t if (mp_obj_get_int_maybe(address, (mp_int_t *)&value)) { // We're done. buf = (uint8_t *)value; - } else if (MP_OBJ_IS_STR(address)) { + } else if (mp_obj_is_str(address)) { GET_STR_DATA_LEN(address, str_data, str_len); if (!ipaddress_parse_ipv4address((const char *)str_data, str_len, &value)) { mp_raise_ValueError(translate("Not a valid IP string")); @@ -134,7 +134,7 @@ STATIC mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_ switch (op) { // Two Addresses are equal if their address bytes and address_type are equal case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &ipaddress_ipv4address_type)) { + if (mp_obj_is_type(rhs_in, &ipaddress_ipv4address_type)) { ipaddress_ipv4address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in); ipaddress_ipv4address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in); return mp_obj_new_bool( diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index f768ec0ba6..ee12f5f0d2 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -85,7 +85,7 @@ STATIC mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { uint32_t value; if (mp_obj_get_int_maybe(ip_in, (mp_int_t *)&value)) { // We're done. - } else if (MP_OBJ_IS_STR(ip_in)) { + } else if (mp_obj_is_str(ip_in)) { GET_STR_DATA_LEN(ip_in, str_data, str_len); if (!ipaddress_parse_ipv4address((const char *)str_data, str_len, &value)) { mp_raise_ValueError(translate("Not a valid IP string")); diff --git a/shared-bindings/memorymonitor/AllocationSize.c b/shared-bindings/memorymonitor/AllocationSize.c index ea6a1db3ce..ca4690d4e6 100644 --- a/shared-bindings/memorymonitor/AllocationSize.c +++ b/shared-bindings/memorymonitor/AllocationSize.c @@ -150,7 +150,7 @@ STATIC mp_obj_t memorymonitor_allocationsize_subscr(mp_obj_t self_in, mp_obj_t i } else { memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + if (mp_obj_is_type(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError(translate("Slices not supported")); } else { size_t index = mp_get_index(&memorymonitor_allocationsize_type, common_hal_memorymonitor_allocationsize_get_len(self), index_obj, false); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index 289d890172..deba9bec6b 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -85,7 +85,7 @@ const mp_obj_type_t mcu_pin_type = { }; mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj) { - if (!MP_OBJ_IS_TYPE(obj, &mcu_pin_type)) { + if (!mp_obj_is_type(obj, &mcu_pin_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), mcu_pin_type.name); } return MP_OBJ_TO_PTR(obj); diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c index 0bd1d86e20..c4852f5427 100644 --- a/shared-bindings/msgpack/__init__.c +++ b/shared-bindings/msgpack/__init__.c @@ -31,7 +31,7 @@ #include "shared-module/msgpack/__init__.h" #include "shared-bindings/msgpack/ExtType.h" -#define MP_OBJ_IS_METH(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_bound_method)) +#define MP_OBJ_IS_METH(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_bound_method)) //| """Pack object in msgpack format //| @@ -105,7 +105,7 @@ STATIC mp_obj_t mod_msgpack_pack(size_t n_args, const mp_obj_t *pos_args, mp_map mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t handler = args[ARG_default].u_obj; - if (handler != mp_const_none && !MP_OBJ_IS_FUN(handler) && !MP_OBJ_IS_METH(handler)) { + if (handler != mp_const_none && !mp_obj_is_fun(handler) && !MP_OBJ_IS_METH(handler)) { mp_raise_ValueError(translate("default is not a function")); } @@ -138,7 +138,7 @@ STATIC mp_obj_t mod_msgpack_unpack(size_t n_args, const mp_obj_t *pos_args, mp_m mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t hook = args[ARG_ext_hook].u_obj; - if (hook != mp_const_none && !MP_OBJ_IS_FUN(hook) && !MP_OBJ_IS_METH(hook)) { + if (hook != mp_const_none && !mp_obj_is_fun(hook) && !MP_OBJ_IS_METH(hook)) { mp_raise_ValueError(translate("ext_hook is not a function")); } diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index da4f28a137..a1f01e506f 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -57,7 +57,7 @@ //| :param ~_typing.ReadableBuffer buf: The bytes to clock out. No assumption is made about color order""" //| ... STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { - if (!MP_OBJ_IS_TYPE(digitalinout_obj, &digitalio_digitalinout_type)) { + if (!mp_obj_is_type(digitalinout_obj, &digitalio_digitalinout_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), digitalio_digitalinout_type.name); } // Convert parameters into expected types. diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index 0a2ef3389f..c56e3b5cce 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -98,7 +98,7 @@ STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); if (0) { #if MICROPY_PY_BUILTINS_SLICE - } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(common_hal_nvm_bytearray_get_length(self), index_in, &slice)) { mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); @@ -108,10 +108,10 @@ STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj // Assign size_t src_len = slice.stop - slice.start; uint8_t *src_items; - if (MP_OBJ_IS_TYPE(value, &mp_type_array) || - MP_OBJ_IS_TYPE(value, &mp_type_bytearray) || - MP_OBJ_IS_TYPE(value, &mp_type_memoryview) || - MP_OBJ_IS_TYPE(value, &mp_type_bytes)) { + if (mp_obj_is_type(value, &mp_type_array) || + mp_obj_is_type(value, &mp_type_bytearray) || + mp_obj_is_type(value, &mp_type_memoryview) || + mp_obj_is_type(value, &mp_type_bytes)) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); if (bufinfo.len != src_len) { diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index dd6ca83fbe..c2d3c59de4 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -116,7 +116,7 @@ STATIC void check_for_deinit(ps2io_ps2_obj_t *self) { //| ... //| STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(MP_OBJ_IS_TYPE(args[0], &ps2io_ps2_type)); + mp_check_self(mp_obj_is_type(args[0], &ps2io_ps2_type)); ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_ps2io_ps2_deinit(self); return mp_const_none; diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 18a5d3f3e5..e502c933c7 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -276,7 +276,7 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + if (mp_obj_is_type(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError(translate("Slices not supported")); } else { size_t index = mp_get_index(&pulseio_pulsein_type, common_hal_pulseio_pulsein_get_len(self), index_obj, false); diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 61614889fb..ccea353386 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -70,7 +70,7 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar self->base.type = &pulseio_pulseout_type; mp_obj_t carrier_obj = pos_args[0]; - if (MP_OBJ_IS_TYPE(carrier_obj, &pwmio_pwmout_type)) { + if (mp_obj_is_type(carrier_obj, &pwmio_pwmout_type)) { // Use a PWMOut Carrier mp_arg_check_num(n_args, kw_args, 1, 1, false); common_hal_pulseio_pulseout_construct(self, (pwmio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj), NULL, 0, 0); diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index 7b436a4df1..8e8fe73beb 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -88,7 +88,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(storage_mount_obj, 2, storage_mount); //| ... //| mp_obj_t storage_umount(mp_obj_t mnt_in) { - if (MP_OBJ_IS_STR(mnt_in)) { + if (mp_obj_is_str(mnt_in)) { common_hal_storage_umount_path(mp_obj_str_get_str(mnt_in)); } else { common_hal_storage_umount_object(mnt_in); diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index d5165001fc..90055ff0e4 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -69,7 +69,7 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!MP_OBJ_IS_TYPE(args[ARG_file].u_obj, &mp_type_fileio)) { + if (!mp_obj_is_type(args[ARG_file].u_obj, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } pyb_file_obj_t *file = MP_OBJ_TO_PTR(args[ARG_file].u_obj); diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index b1d3cce653..3432fc9e5c 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -56,12 +56,12 @@ STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t tilegrid = args[ARG_tilegrid].u_obj; - if (!MP_OBJ_IS_TYPE(tilegrid, &displayio_tilegrid_type)) { + if (!mp_obj_is_type(tilegrid, &displayio_tilegrid_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), displayio_tilegrid_type.name); } mp_obj_t font = args[ARG_font].u_obj; - if (!MP_OBJ_IS_TYPE(font, &fontio_builtinfont_type)) { + if (!mp_obj_is_type(font, &fontio_builtinfont_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), fontio_builtinfont_type.name); } terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t); diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 87f766db26..3243fbc2d9 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -164,7 +164,7 @@ void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm) { mp_obj_t *elems; size_t len; - if (!MP_OBJ_IS_TYPE(t, &mp_type_tuple) && !MP_OBJ_IS_TYPE(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { + if (!mp_obj_is_type(t, &mp_type_tuple) && !mp_obj_is_type(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { mp_raise_TypeError(translate("Tuple or struct_time argument required")); } @@ -273,7 +273,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) { mp_obj_t *elem; size_t len; - if (!MP_OBJ_IS_TYPE(t, &mp_type_tuple) && !MP_OBJ_IS_TYPE(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { + if (!mp_obj_is_type(t, &mp_type_tuple) && !mp_obj_is_type(t, MP_OBJ_FROM_PTR(&struct_time_type_obj))) { mp_raise_TypeError(translate("Tuple or struct_time argument required")); } diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 737476c5ef..d6bc6087d1 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -29,7 +29,7 @@ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_ar mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!MP_OBJ_IS_TYPE(args[ARG_points_list].u_obj, &mp_type_list)) { + if (!mp_obj_is_type(args[ARG_points_list].u_obj, &mp_type_list)) { mp_raise_TypeError_varg(translate("%q list must be a list"), MP_QSTR_point); } diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index 7c7f467b09..859d025ada 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -41,8 +41,8 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; - if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type) && - !MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type)) { + if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) && + !mp_obj_is_type(pixel_shader, &displayio_palette_type)) { mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); } @@ -52,15 +52,15 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t mp_obj_t shape = args[ARG_shape].u_obj; vectorio_ishape_t ishape; // Wire up shape functions - if (MP_OBJ_IS_TYPE(shape, &vectorio_polygon_type)) { + if (mp_obj_is_type(shape, &vectorio_polygon_type)) { ishape.shape = shape; ishape.get_area = &common_hal_vectorio_polygon_get_area; ishape.get_pixel = &common_hal_vectorio_polygon_get_pixel; - } else if (MP_OBJ_IS_TYPE(shape, &vectorio_rectangle_type)) { + } else if (mp_obj_is_type(shape, &vectorio_rectangle_type)) { ishape.shape = shape; ishape.get_area = &common_hal_vectorio_rectangle_get_area; ishape.get_pixel = &common_hal_vectorio_rectangle_get_pixel; - } else if (MP_OBJ_IS_TYPE(shape, &vectorio_circle_type)) { + } else if (mp_obj_is_type(shape, &vectorio_circle_type)) { ishape.shape = shape; ishape.get_area = &common_hal_vectorio_circle_get_area; ishape.get_pixel = &common_hal_vectorio_circle_get_pixel; @@ -80,10 +80,10 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t .event = &common_hal_vectorio_vector_shape_set_dirty }; - if (MP_OBJ_IS_TYPE(shape, &vectorio_polygon_type)) { + if (mp_obj_is_type(shape, &vectorio_polygon_type)) { common_hal_vectorio_polygon_set_on_dirty(self->ishape.shape, on_dirty); - } else if (MP_OBJ_IS_TYPE(shape, &vectorio_rectangle_type)) { - } else if (MP_OBJ_IS_TYPE(shape, &vectorio_circle_type)) { + } else if (mp_obj_is_type(shape, &vectorio_rectangle_type)) { + } else if (mp_obj_is_type(shape, &vectorio_circle_type)) { common_hal_vectorio_circle_set_on_dirty(self->ishape.shape, on_dirty); } else { mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_shape); @@ -156,7 +156,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_pixel_shader_obj, vectorio_v STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); - if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); } diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c index 9316faa45b..277679b8df 100644 --- a/shared-bindings/wifi/ScannedNetworks.c +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -37,7 +37,7 @@ //| by a `wifi.Radio`: it has no user-visible constructor.""" //| STATIC mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { - mp_check_self(MP_OBJ_IS_TYPE(self_in, &wifi_scannednetworks_type)); + mp_check_self(mp_obj_is_type(self_in, &wifi_scannednetworks_type)); wifi_scannednetworks_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t network = common_hal_wifi_scannednetworks_next(self); if (network != mp_const_none) { diff --git a/shared-module/_pixelbuf/PixelBuf.c b/shared-module/_pixelbuf/PixelBuf.c index df160b1ffa..10f1b4ec5f 100644 --- a/shared-module/_pixelbuf/PixelBuf.c +++ b/shared-module/_pixelbuf/PixelBuf.c @@ -141,9 +141,9 @@ void common_hal__pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_float_t b } uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) { - if (MP_OBJ_IS_SMALL_INT(obj)) { + if (mp_obj_is_small_int(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); - } else if (MP_OBJ_IS_INT(obj)) { + } else if (mp_obj_is_int(obj)) { return mp_obj_get_int_truncated(obj); } else if (mp_obj_is_float(obj)) { return (uint8_t)mp_obj_get_float(obj); @@ -162,8 +162,8 @@ void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color, uint8_ *w = 0; } - if (MP_OBJ_IS_INT(color) || mp_obj_is_float(color)) { - mp_int_t value = MP_OBJ_IS_INT(color) ? mp_obj_get_int_truncated(color) : mp_obj_get_float(color); + if (mp_obj_is_int(color) || mp_obj_is_float(color)) { + mp_int_t value = mp_obj_is_int(color) ? mp_obj_get_int_truncated(color) : mp_obj_get_float(color); *r = value >> 16 & 0xff; *g = (value >> 8) & 0xff; *b = value & 0xff; diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index a623a10de5..68436ba67f 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -449,20 +449,20 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c // We always want to read bitmap pixels by row first and then transpose into the destination // buffer because most bitmaps are row associated. - if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + if (mp_obj_is_type(self->bitmap, &displayio_bitmap_type)) { input_pixel.pixel = common_hal_displayio_bitmap_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.tile_y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + } else if (mp_obj_is_type(self->bitmap, &displayio_shape_type)) { input_pixel.pixel = common_hal_displayio_shape_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.tile_y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + } else if (mp_obj_is_type(self->bitmap, &displayio_ondiskbitmap_type)) { input_pixel.pixel = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, input_pixel.tile_x, input_pixel.tile_y); } output_pixel.opaque = true; if (self->pixel_shader == mp_const_none) { output_pixel.pixel = input_pixel.pixel; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } if (!output_pixel.opaque) { @@ -512,16 +512,16 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { self->moved = false; self->full_change = false; self->partial_change = false; - if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { displayio_palette_finish_refresh(self->pixel_shader); - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_finish_refresh(self->pixel_shader); } - if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + if (mp_obj_is_type(self->bitmap, &displayio_bitmap_type)) { displayio_bitmap_finish_refresh(self->bitmap); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + } else if (mp_obj_is_type(self->bitmap, &displayio_shape_type)) { displayio_shape_finish_refresh(self->bitmap); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + } else if (mp_obj_is_type(self->bitmap, &displayio_ondiskbitmap_type)) { // OnDiskBitmap changes will trigger a complete reload so no need to // track changes. } @@ -552,7 +552,7 @@ displayio_area_t *displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel } // If we have an in-memory bitmap, then check it for modifications. - if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + if (mp_obj_is_type(self->bitmap, &displayio_bitmap_type)) { displayio_area_t *refresh_area = displayio_bitmap_get_refresh_areas(self->bitmap, tail); if (refresh_area != tail) { // Special case a TileGrid that shows a full bitmap and use its @@ -564,7 +564,7 @@ displayio_area_t *displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel self->full_change = true; } } - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + } else if (mp_obj_is_type(self->bitmap, &displayio_shape_type)) { displayio_area_t *refresh_area = displayio_shape_get_refresh_areas(self->bitmap, tail); if (refresh_area != tail) { displayio_area_copy(refresh_area, &self->dirty_area); @@ -573,9 +573,9 @@ displayio_area_t *displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel } self->full_change = self->full_change || - (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && + (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || - (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && + (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)); if (self->full_change || first_draw) { self->current_area.next = tail; diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index a0b3afa0ee..5b4b20b344 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -61,19 +61,19 @@ void displayio_display_core_construct(displayio_display_core_t *self, // (framebufferdisplay already validated its 'bus' is a buffer-protocol object) if (bus) { - if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { + if (mp_obj_is_type(bus, &displayio_parallelbus_type)) { self->bus_reset = common_hal_displayio_parallelbus_reset; self->bus_free = common_hal_displayio_parallelbus_bus_free; self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; self->send = common_hal_displayio_parallelbus_send; self->end_transaction = common_hal_displayio_parallelbus_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { + } else if (mp_obj_is_type(bus, &displayio_fourwire_type)) { self->bus_reset = common_hal_displayio_fourwire_reset; self->bus_free = common_hal_displayio_fourwire_bus_free; self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; self->send = common_hal_displayio_fourwire_send; self->end_transaction = common_hal_displayio_fourwire_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { + } else if (mp_obj_is_type(bus, &displayio_i2cdisplay_type)) { self->bus_reset = common_hal_displayio_i2cdisplay_reset; self->bus_free = common_hal_displayio_i2cdisplay_bus_free; self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; diff --git a/shared-module/gamepad/__init__.c b/shared-module/gamepad/__init__.c index c707886065..50e3edd9cf 100644 --- a/shared-module/gamepad/__init__.c +++ b/shared-module/gamepad/__init__.c @@ -39,7 +39,7 @@ void gamepad_tick(void) { uint8_t bit = 1; void *singleton = MP_STATE_VM(gamepad_singleton); - if (singleton == NULL || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(singleton), &gamepad_type)) { + if (singleton == NULL || !mp_obj_is_type(MP_OBJ_FROM_PTR(singleton), &gamepad_type)) { return; } diff --git a/shared-module/gamepadshift/__init__.c b/shared-module/gamepadshift/__init__.c index 44cf3be812..eadd3034f6 100644 --- a/shared-module/gamepadshift/__init__.c +++ b/shared-module/gamepadshift/__init__.c @@ -31,7 +31,7 @@ void gamepadshift_tick(void) { void *singleton = MP_STATE_VM(gamepad_singleton); - if (singleton == NULL || !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(singleton), &gamepadshift_type)) { + if (singleton == NULL || !mp_obj_is_type(MP_OBJ_FROM_PTR(singleton), &gamepadshift_type)) { return; } diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c index 61547fde3a..1e865385d7 100644 --- a/shared-module/msgpack/__init__.c +++ b/shared-module/msgpack/__init__.c @@ -174,7 +174,7 @@ STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) { mp_map_t *map = &dict->map; for (size_t i = *cur; i < max; i++) { - if (MP_MAP_SLOT_IS_FILLED(map, i)) { + if (mp_map_slot_is_filled(map, i)) { *cur = i + 1; return &(map->table[i]); } @@ -263,35 +263,35 @@ STATIC void pack_dict(msgpack_stream_t *s, size_t len) { } STATIC void pack(mp_obj_t obj, msgpack_stream_t *s, mp_obj_t default_handler) { - if (MP_OBJ_IS_SMALL_INT(obj)) { + if (mp_obj_is_small_int(obj)) { // int int32_t x = MP_OBJ_SMALL_INT_VALUE(obj); pack_int(s, x); - } else if (MP_OBJ_IS_STR(obj)) { + } else if (mp_obj_is_str(obj)) { // string size_t len; const char *data = mp_obj_str_get_data(obj, &len); pack_str(s, data, len); - } else if (MP_OBJ_IS_TYPE(obj, &mod_msgpack_exttype_type)) { + } else if (mp_obj_is_type(obj, &mod_msgpack_exttype_type)) { mod_msgpack_extype_obj_t *ext = MP_OBJ_TO_PTR(obj); mp_buffer_info_t bufinfo; mp_get_buffer_raise(ext->data, &bufinfo, MP_BUFFER_READ); pack_ext(s, ext->code, bufinfo.buf, bufinfo.len); - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_tuple)) { + } else if (mp_obj_is_type(obj, &mp_type_tuple)) { // tuple mp_obj_tuple_t *self = MP_OBJ_TO_PTR(obj); pack_array(s, self->len); for (size_t i = 0; i < self->len; i++) { pack(self->items[i], s, default_handler); } - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_list)) { + } else if (mp_obj_is_type(obj, &mp_type_list)) { // list (layout differs from tuple) mp_obj_list_t *self = MP_OBJ_TO_PTR(obj); pack_array(s, self->len); for (size_t i = 0; i < self->len; i++) { pack(self->items[i], s, default_handler); } - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_dict)) { + } else if (mp_obj_is_type(obj, &mp_type_dict)) { // dict mp_obj_dict_t *self = MP_OBJ_TO_PTR(obj); pack_dict(s, self->map.used); diff --git a/shared-module/uheap/__init__.c b/shared-module/uheap/__init__.c index fd8e31ec0d..bff571ad8c 100644 --- a/shared-module/uheap/__init__.c +++ b/shared-module/uheap/__init__.c @@ -53,7 +53,7 @@ static void indent(uint8_t levels) { static uint32_t object_size(uint8_t indent_level, mp_obj_t obj); static uint32_t int_size(uint8_t indent_level, mp_obj_t obj) { - if (MP_OBJ_IS_SMALL_INT(obj)) { + if (mp_obj_is_small_int(obj)) { return 0; } if (!VERIFY_PTR(obj)) { @@ -68,7 +68,7 @@ static uint32_t int_size(uint8_t indent_level, mp_obj_t obj) { } static uint32_t string_size(uint8_t indent_level, mp_obj_t obj) { - if (MP_OBJ_IS_QSTR(obj)) { + if (mp_obj_is_qstr(obj)) { qstr qs = MP_OBJ_QSTR_VALUE(obj); const char *s = qstr_str(qs); if (!VERIFY_PTR(s)) { @@ -77,7 +77,7 @@ static uint32_t string_size(uint8_t indent_level, mp_obj_t obj) { indent(indent_level); mp_printf(&mp_plat_print, "%s\n", s); return 0; - } else { // MP_OBJ_IS_TYPE(o, &mp_type_str) + } else { // mp_obj_is_type(o, &mp_type_str) mp_obj_str_t *s = MP_OBJ_TO_PTR(obj); return gc_nbytes(s) + gc_nbytes(s->data); } @@ -120,17 +120,17 @@ static uint32_t dict_size(uint8_t indent_level, mp_obj_dict_t *dict) { static uint32_t function_size(uint8_t indent_level, mp_obj_t obj) { // indent(indent_level); // mp_print_str(&mp_plat_print, "function\n"); - if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_0)) { + if (mp_obj_is_type(obj, &mp_type_fun_builtin_0)) { return 0; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_1)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_builtin_1)) { return 0; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_2)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_builtin_2)) { return 0; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_3)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_builtin_3)) { return 0; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_builtin_var)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_builtin_var)) { return 0; - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_bc)) { mp_obj_fun_bc_t *fn = MP_OBJ_TO_PTR(obj); uint32_t total_size = gc_nbytes(fn) + gc_nbytes(fn->bytecode) + gc_nbytes(fn->const_table); #if MICROPY_DEBUG_PRINTERS @@ -140,15 +140,15 @@ static uint32_t function_size(uint8_t indent_level, mp_obj_t obj) { #endif return total_size; #if MICROPY_EMIT_NATIVE - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_native)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_native)) { return 0; #endif #if MICROPY_EMIT_NATIVE - } else if (MP_OBJ_IS_TYPE(obj, &mp_obj_fun_viper_t)) { + } else if (mp_obj_is_type(obj, &mp_obj_fun_viper_t)) { return 0; #endif #if MICROPY_EMIT_THUMB - } else if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_asm)) { + } else if (mp_obj_is_type(obj, &mp_type_fun_asm)) { return 0; #endif } @@ -250,11 +250,11 @@ static uint32_t object_size(uint8_t indent_level, mp_obj_t obj) { if (obj == NULL) { return 0; } - if (MP_OBJ_IS_INT(obj)) { + if (mp_obj_is_int(obj)) { return int_size(indent_level, MP_OBJ_TO_PTR(obj)); - } else if (MP_OBJ_IS_STR(obj)) { + } else if (mp_obj_is_str(obj)) { return string_size(indent_level, MP_OBJ_TO_PTR(obj)); - } else if (MP_OBJ_IS_FUN(obj)) { + } else if (mp_obj_is_fun(obj)) { return function_size(indent_level, MP_OBJ_TO_PTR(obj)); } if (!VERIFY_PTR(obj)) { @@ -274,7 +274,7 @@ static uint32_t object_size(uint8_t indent_level, mp_obj_t obj) { return array_size(indent_level, MP_OBJ_TO_PTR(obj)); } else if (type == &mp_type_memoryview) { return memoryview_size(indent_level, MP_OBJ_TO_PTR(obj)); - } else if (MP_OBJ_IS_OBJ(obj) && VERIFY_PTR(type)) { + } else if (mp_obj_is_obj(obj) && VERIFY_PTR(type)) { return instance_size(indent_level, MP_OBJ_TO_PTR(obj)); } diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index efc40d0356..f0b6a725c1 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -217,9 +217,9 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ output_pixel.opaque = true; if (self->pixel_shader == mp_const_none) { output_pixel.pixel = input_pixel.pixel; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); } if (!output_pixel.opaque) { @@ -281,9 +281,9 @@ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { self->ephemeral_dirty_area.next = NULL; VECTORIO_SHAPE_DEBUG("%p finish_refresh now:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { displayio_palette_finish_refresh(self->pixel_shader); - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_finish_refresh(self->pixel_shader); } } @@ -292,8 +292,8 @@ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { // Assembles a singly linked list of dirty areas from all components on the display. displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail) { if (self->dirty - || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) - || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) + || (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) + || (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) ) { VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty:%d {(%3d,%3d), (%3d,%3d)}", self, self->dirty, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); common_hal_vectorio_vector_shape_set_dirty(self); diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 874f258217..b8d9d8ae31 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -97,7 +97,7 @@ void filesystem_init(bool create_allowed, bool force_create) { if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { // No filesystem so create a fresh one, or reformat has been requested. - uint8_t working_buf[_MAX_SS]; + uint8_t working_buf[FF_MAX_SS]; res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf)); // Flush the new file system to make sure it's repaired immediately. supervisor_flash_flush(); diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 409bf0ea6c..60e7c9cc24 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -161,11 +161,11 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * // Since by getting here we assume the mount is read-only to // MicroPython let's update the cached FatFs sector if it's the one // we just wrote. - #if _MAX_SS != _MIN_SS + #if FF_MAX_SS != FF_MIN_SS if (vfs->ssize == MSC_FLASH_BLOCK_SIZE) { #else // The compiler can optimize this away. - if (_MAX_SS == FILESYSTEM_BLOCK_SIZE) { + if (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) { #endif if (lba == vfs->fatfs.winsect && lba > 0) { memcpy(vfs->fatfs.win, diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index c206ff96be..c6354205cf 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -7,6 +7,7 @@ SRC_SUPERVISOR = \ supervisor/shared/cpu.c \ supervisor/shared/filesystem.c \ supervisor/shared/flash.c \ + supervisor/shared/memory.c \ supervisor/shared/micropython.c \ supervisor/shared/rgb_led_status.c \ supervisor/shared/safe_mode.c \ diff --git a/tests/basics/async_with.py b/tests/basics/async_with.py index 5af0c5d955..f7774055cf 100644 --- a/tests/basics/async_with.py +++ b/tests/basics/async_with.py @@ -27,3 +27,13 @@ try: o.send(None) except ValueError: print('ValueError') + +# test raising BaseException to make sure it is handled by the async-with +async def h(): + async with AContext(): + raise BaseException +o = h() +try: + o.send(None) +except BaseException: + print('BaseException') diff --git a/tests/basics/async_with.py.exp b/tests/basics/async_with.py.exp index d00b18c969..6bbf84cb4b 100644 --- a/tests/basics/async_with.py.exp +++ b/tests/basics/async_with.py.exp @@ -6,3 +6,6 @@ enter 1 exit error ValueError +enter +exit +BaseException diff --git a/tests/basics/builtin_next_arg2.py b/tests/basics/builtin_next_arg2.py new file mode 100644 index 0000000000..b00155ec54 --- /dev/null +++ b/tests/basics/builtin_next_arg2.py @@ -0,0 +1,34 @@ +# test next(iter, default) + +try: + next(iter([]), 42) +except TypeError: # 2-argument version not supported + print('SKIP') + raise SystemExit + +print(next(iter([]), 42)) +print(next(iter(range(0)), 42)) +print(next((x for x in [0] if x == 1), 43)) + +def gen(): + yield 1 + yield 2 + +g = gen() +print(next(g, 42)) +print(next(g, 43)) +print(next(g, 44)) + +class Gen: + def __init__(self): + self.b = False + + def __next__(self): + if self.b: + raise StopIteration + self.b = True + return self.b + +g = Gen() +print(next(g, 44)) +print(next(g, 45)) diff --git a/tests/basics/bytearray_decode.py b/tests/basics/bytearray_decode.py new file mode 100644 index 0000000000..b5e1cb419b --- /dev/null +++ b/tests/basics/bytearray_decode.py @@ -0,0 +1,6 @@ +try: + print(bytearray(b'').decode()) + print(bytearray(b'abc').decode()) +except AttributeError: + print("SKIP") + raise SystemExit diff --git a/tests/basics/gen_yield_from_throw.py b/tests/basics/gen_yield_from_throw.py index 703158f4d4..804c53dda0 100644 --- a/tests/basics/gen_yield_from_throw.py +++ b/tests/basics/gen_yield_from_throw.py @@ -1,8 +1,8 @@ def gen(): try: yield 1 - except ValueError: - print("got ValueError from upstream!") + except ValueError as e: + print("got ValueError from upstream!", repr(e.args)) yield "str1" raise TypeError @@ -16,3 +16,21 @@ try: print(next(g)) except TypeError: print("got TypeError from downstream!") + +# passing None as second argument to throw +g = gen2() +print(next(g)) +print(g.throw(ValueError, None)) +try: + print(next(g)) +except TypeError: + print("got TypeError from downstream!") + +# passing an exception instance as second argument to throw +g = gen2() +print(next(g)) +print(g.throw(ValueError, ValueError(123))) +try: + print(next(g)) +except TypeError: + print("got TypeError from downstream!") diff --git a/tests/basics/generator_throw.py b/tests/basics/generator_throw.py index 1a390f399d..067ab2b8eb 100644 --- a/tests/basics/generator_throw.py +++ b/tests/basics/generator_throw.py @@ -28,8 +28,8 @@ except StopIteration: def gen(): try: yield 123 - except GeneratorExit: - print('GeneratorExit') + except GeneratorExit as e: + print('GeneratorExit', repr(e.args)) yield 456 # thrown a class @@ -41,3 +41,13 @@ print(g.throw(GeneratorExit)) g = gen() print(next(g)) print(g.throw(GeneratorExit())) + +# thrown an instance with None as second arg +g = gen() +print(next(g)) +print(g.throw(GeneratorExit(), None)) + +# thrown a class and instance +g = gen() +print(next(g)) +print(g.throw(GeneratorExit, GeneratorExit(123))) diff --git a/tests/basics/memoryview1.py b/tests/basics/memoryview1.py index 3e5c86768c..a0ac9e3449 100644 --- a/tests/basics/memoryview1.py +++ b/tests/basics/memoryview1.py @@ -46,3 +46,57 @@ print(list(m)) print(list(m[1:-1])) m[2] = 6 print(a) + +# test slice assignment between memoryviews +b1 = bytearray(b'1234') +b2 = bytearray(b'5678') +b3 = bytearray(b'5678') +m1 = memoryview(b1) +m2 = memoryview(b2) +m3 = memoryview(b3) +m2[1:3] = m1[0:2] +print(b2) +b3[1:3] = m1[0:2] +print(b3) +m1[2:4] = b3[1:3] +print(b1) + +try: + m2[1:3] = b1[0:4] +except ValueError: + print("ValueError") + +try: + m2[1:3] = m1[0:4] +except ValueError: + print("ValueError") + +try: + m2[0:4] = m1[1:3] +except ValueError: + print("ValueError") + +# test memoryview of arrays with items sized larger than 1 +a1 = array.array('i', [0]*5) +m4 = memoryview(a1) +a2 = array.array('i', [3]*5) +m5 = memoryview(a2) +m4[1:3] = m5[1:3] +print(a1) + +try: + m4[1:3] = m2[1:3] +except ValueError: + print("ValueError") + +# invalid assignment on RHS +try: + memoryview(array.array('i'))[0:2] = b'1234' +except ValueError: + print('ValueError') + +# invalid attribute +try: + memoryview(b'a').noexist +except AttributeError: + print('AttributeError') diff --git a/tests/basics/memoryview_itemsize.py b/tests/basics/memoryview_itemsize.py new file mode 100644 index 0000000000..60cb823087 --- /dev/null +++ b/tests/basics/memoryview_itemsize.py @@ -0,0 +1,15 @@ +try: + memoryview(b'a').itemsize + from array import array +except: + print("SKIP") + raise SystemExit + +for code in ['b', 'h', 'i', 'l', 'q', 'f', 'd']: + print(memoryview(array(code)).itemsize) + +# shouldn't be able to store to the itemsize attribute +try: + memoryview(b'a').itemsize = 1 +except AttributeError: + print('AttributeError') diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py index da11c88d3e..8adff04439 100644 --- a/tests/basics/sys1.py +++ b/tests/basics/sys1.py @@ -24,6 +24,11 @@ try: except SystemExit as e: print("SystemExit", e.args) +try: + sys.exit() +except SystemExit as e: + print("SystemExit", e.args) + try: sys.exit(42) except SystemExit as e: diff --git a/tests/basics/try_else.py b/tests/basics/try_else.py new file mode 100644 index 0000000000..677707ecd6 --- /dev/null +++ b/tests/basics/try_else.py @@ -0,0 +1,76 @@ +# test try-else statement + +# base case +try: + print(1) +except: + print(2) +else: + print(3) + +# basic case that should skip else +try: + print(1) + raise Exception +except: + print(2) +else: + print(3) + +# uncaught exception should skip else +try: + try: + print(1) + raise ValueError + except TypeError: + print(2) + else: + print(3) +except: + print('caught') + +# nested within outer try +try: + print(1) + try: + print(2) + raise Exception + except: + print(3) + else: + print(4) +except: + print(5) +else: + print(6) + +# nested within outer except, one else should be skipped +try: + print(1) + raise Exception +except: + print(2) + try: + print(3) + except: + print(4) + else: + print(5) +else: + print(6) + +# nested within outer except, both else should be skipped +try: + print(1) + raise Exception +except: + print(2) + try: + print(3) + raise Exception + except: + print(4) + else: + print(5) +else: + print(6) diff --git a/tests/basics/try_else_finally.py b/tests/basics/try_else_finally.py new file mode 100644 index 0000000000..87d98bbdaf --- /dev/null +++ b/tests/basics/try_else_finally.py @@ -0,0 +1,94 @@ +# test try-else-finally statement + +# base case +try: + print(1) +except: + print(2) +else: + print(3) +finally: + print(4) + +# basic case that should skip else +try: + print(1) + raise Exception +except: + print(2) +else: + print(3) +finally: + print(4) + +# uncaught exception should skip else +try: + try: + print(1) + raise ValueError + except TypeError: + print(2) + else: + print(3) + finally: + print(4) +except: + print('caught') + +# nested within outer try +try: + print(1) + try: + print(2) + raise Exception + except: + print(3) + else: + print(4) + finally: + print(5) +except: + print(6) +else: + print(7) +finally: + print(8) + +# nested within outer except, one else should be skipped +try: + print(1) + raise Exception +except: + print(2) + try: + print(3) + except: + print(4) + else: + print(5) + finally: + print(6) +else: + print(7) +finally: + print(8) + +# nested within outer except, both else should be skipped +try: + print(1) + raise Exception +except: + print(2) + try: + print(3) + raise Exception + except: + print(4) + else: + print(5) + finally: + print(6) +else: + print(7) +finally: + print(8) diff --git a/tests/basics/try_finally_break.py b/tests/basics/try_finally_break.py new file mode 100644 index 0000000000..ae7226637d --- /dev/null +++ b/tests/basics/try_finally_break.py @@ -0,0 +1,99 @@ +# test break within (nested) finally + +# basic case with break in finally +def f(): + for _ in range(2): + print(1) + try: + pass + finally: + print(2) + break + print(3) + print(4) + print(5) +f() + +# where the finally swallows an exception +def f(): + lst = [1, 2, 3] + for x in lst: + print('a', x) + try: + raise Exception + finally: + print(1) + break + print('b', x) +f() + +# basic nested finally with break in inner finally +def f(): + for i in range(2): + print('iter', i) + try: + raise TypeError + finally: + print(1) + try: + raise ValueError + finally: + break +print(f()) + +# similar to above but more nesting +def f(): + for i in range(2): + try: + raise ValueError + finally: + print(1) + try: + raise TypeError + finally: + print(2) + try: + pass + finally: + break +print(f()) + +# lots of nesting +def f(): + for i in range(2): + try: + raise ValueError + finally: + print(1) + try: + raise TypeError + finally: + print(2) + try: + raise Exception + finally: + break +print(f()) + +# basic case combined with try-else +def f(arg): + for _ in range(2): + print(1) + try: + if arg == 1: + raise ValueError + elif arg == 2: + raise TypeError + except ValueError: + print(2) + else: + print(3) + finally: + print(4) + break + print(5) + print(6) + print(7) +f(0) # no exception, else should execute +f(1) # exception caught, else should be skipped +f(2) # exception not caught, finally swallows exception, else should be skipped diff --git a/tests/basics/try_return.py b/tests/basics/try_return.py index 492c18d95c..a24290c4fb 100644 --- a/tests/basics/try_return.py +++ b/tests/basics/try_return.py @@ -1,5 +1,14 @@ # test use of return with try-except +def f(): + try: + print(1) + return + except: + print(2) + print(3) +f() + def f(l, i): try: return l[i] diff --git a/tests/cmdline/cmd_showbc.py b/tests/cmdline/cmd_showbc.py index 326f2373f6..8ef5e22f39 100644 --- a/tests/cmdline/cmd_showbc.py +++ b/tests/cmdline/cmd_showbc.py @@ -3,6 +3,7 @@ # fmt: off + def f(): # constants a = None + False + True diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index ac4cedd340..9b7691b7d2 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -7,7 +7,7 @@ arg names: (N_EXC_STACK 0) bc=-1 line=1 ######## - bc=\\d\+ line=164 + bc=\\d\+ line=165 00 MAKE_FUNCTION \.\+ \\d\+ STORE_NAME f \\d\+ MAKE_FUNCTION \.\+ @@ -40,7 +40,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): (INIT_CELL 16) bc=-4 line=1 ######## - bc=\\d\+ line=130 + bc=\\d\+ line=131 00 LOAD_CONST_NONE 01 LOAD_CONST_FALSE 02 BINARY_OP 26 __add__ @@ -257,15 +257,12 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ JUMP \\d\+ \\d\+ LOAD_FAST 0 \\d\+ POP_JUMP_IF_TRUE \\d\+ -\\d\+ POP_BLOCK -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ POP_TOP \\d\+ LOAD_DEREF 14 \\d\+ POP_TOP -\\d\+ POP_EXCEPT -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ END_FINALLY -\\d\+ POP_BLOCK \\d\+ LOAD_CONST_NONE \\d\+ LOAD_FAST 1 \\d\+ POP_TOP @@ -273,11 +270,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ JUMP \\d\+ \\d\+ SETUP_EXCEPT \\d\+ \\d\+ UNWIND_JUMP \\d\+ 1 -\\d\+ POP_BLOCK -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ POP_TOP -\\d\+ POP_EXCEPT -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ END_FINALLY \\d\+ LOAD_FAST 0 \\d\+ POP_JUMP_IF_TRUE \\d\+ @@ -286,7 +281,6 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ POP_TOP \\d\+ LOAD_DEREF 14 \\d\+ POP_TOP -\\d\+ POP_BLOCK \\d\+ LOAD_CONST_NONE \\d\+ WITH_CLEANUP \\d\+ END_FINALLY @@ -326,7 +320,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): (N_EXC_STACK 0) bc=-1 line=1 ######## - bc=\\d\+ line=137 + bc=\\d\+ line=138 00 LOAD_CONST_SMALL_INT 1 01 DUP_TOP 02 STORE_FAST 0 @@ -382,7 +376,7 @@ arg names: a (N_EXC_STACK 0) (INIT_CELL 0) ######## - bc=\\d\+ line=144 + bc=\\d\+ line=145 00 LOAD_CONST_SMALL_INT 2 01 BUILD_TUPLE 1 03 LOAD_NULL @@ -399,9 +393,9 @@ arg names: (N_STATE 2) (N_EXC_STACK 0) bc=-1 line=1 - bc=0 line=150 - bc=3 line=151 - bc=6 line=152 + bc=0 line=151 + bc=3 line=152 + bc=6 line=153 00 LOAD_CONST_NONE 01 YIELD_VALUE 02 POP_TOP @@ -423,7 +417,7 @@ arg names: (N_STATE 1) (N_EXC_STACK 0) bc=-1 line=1 - bc=13 line=157 + bc=13 line=158 00 LOAD_NAME __name__ (cache=0) 04 STORE_NAME __module__ 07 LOAD_CONST_STRING 'Class' @@ -438,7 +432,7 @@ arg names: self (N_STATE 4) (N_EXC_STACK 0) bc=-1 line=1 - bc=0 line=165 + bc=0 line=166 00 LOAD_GLOBAL super (cache=0) \\d\+ LOAD_GLOBAL __class__ (cache=0) \\d\+ LOAD_FAST 0 @@ -518,7 +512,7 @@ arg names: * (N_EXC_STACK 0) bc=-\\d\+ line=1 ######## - bc=\\d\+ line=117 + bc=\\d\+ line=118 00 LOAD_DEREF 0 02 LOAD_CONST_SMALL_INT 1 03 BINARY_OP 26 __add__ @@ -537,7 +531,7 @@ arg names: * b (N_EXC_STACK 0) bc=-\\d\+ line=1 ######## - bc=\\d\+ line=145 + bc=\\d\+ line=146 00 LOAD_FAST 1 01 LOAD_DEREF 0 03 BINARY_OP 26 __add__ diff --git a/tests/cmdline/repl_autocomplete.py b/tests/cmdline/repl_autocomplete.py index 43c49cdc25..27cad428f7 100644 --- a/tests/cmdline/repl_autocomplete.py +++ b/tests/cmdline/repl_autocomplete.py @@ -6,7 +6,4 @@ x = '123' 1, x.isdi () i = str i.lowe ('ABC') -x = 5 -x.  -x._ None.  diff --git a/tests/cmdline/repl_autocomplete.py.exp b/tests/cmdline/repl_autocomplete.py.exp index 0dabc90144..75002985e3 100644 --- a/tests/cmdline/repl_autocomplete.py.exp +++ b/tests/cmdline/repl_autocomplete.py.exp @@ -10,11 +10,5 @@ Use \.\+ >>> i = str >>> i.lower('ABC') 'abc' ->>> x = 5 ->>> x. -bit_length from_bytes to_bytes ->>> x. ->>> x.__class__ - >>> None. >>> diff --git a/tests/extmod/ucryptolib_aes128_ctr.py b/tests/extmod/ucryptolib_aes128_ctr.py new file mode 100644 index 0000000000..538d9606e9 --- /dev/null +++ b/tests/extmod/ucryptolib_aes128_ctr.py @@ -0,0 +1,28 @@ +try: + from ucryptolib import aes +except ImportError: + print("SKIP") + raise SystemExit + + +def _new(k, ctr_initial): + return aes(k, 6, ctr_initial) + + +try: + _new(b"x" * 16, b"x" * 16) +except ValueError as e: + # is CTR support disabled? + if e.args[0] == "mode": + print("SKIP") + raise SystemExit + raise e + +crypto = _new(b"1234" * 4, b"5678" * 4) +enc = crypto.encrypt(b"a") +print(enc) +enc += crypto.encrypt(b"b" * 1000) +print(enc) + +crypto = _new(b"1234" * 4, b"5678" * 4) +print(crypto.decrypt(enc)) diff --git a/tests/extmod/ucryptolib_aes128_ctr.py.exp b/tests/extmod/ucryptolib_aes128_ctr.py.exp new file mode 100644 index 0000000000..92e090fd39 --- /dev/null +++ b/tests/extmod/ucryptolib_aes128_ctr.py.exp @@ -0,0 +1,3 @@ +b'\x06' +b'\x06(F\x08\xc3hB\xfdO\x05;\xf6\x96\xfe\xad\xe0\xca\xe6\xd1\xa2m\t\x91v>|\xee\xe0q\xbc]\x9a`\xfal\x87\xa6e\xfb\x8a\xf4\xb2-\xc4x,\xfc@=,\x90\xf4\xe9h\xf0\xfc\xfb\xe6\x03\xf0d\xb6\xcdObZ\xde\x1b\xe2\x84-%=\xa9\xe4\x05\xab\xd7\x044\xf4$\xd0)\xfd\xd6\xdbL\xdd\xe6\x0cp\xca^p\xaaA\x8b\xb3!\xe3\x13\xfa\x7f#\xfa0\xbd\x0b\x9cX\xec\xed\x1c\xbc\x06\xa4\xa8\x17\xbfg\x98dW\xb9~\x04\xec\xe6lZ\xb0\xab\xd5\xc6v\xe4\x8f\x98G\xff\x9b\x8a\xae\xfd\xe5\xed\x96\x1b\xe2\x99u3\xeb\x9faYr;\xf0g\xf2\x9cq\x8dI\x1cL\xc9\xa8\xb0\xdeD\xd5\x06\x87u=\xcd\x10\x1c\xab\x14\x06n\x99\x13\x89\x9f5\xea\xd2\x08\x9e\xef$?\xb9\xdeQ\x0b\x90CH\xea@V\x94\x1a\xdd\x7f\x1dz\x82\xaay\xea$Lv\x07\x8e\xce\xb8oN\x15\xf8,\x05\x00\xd9H\xf4\xbe\xb8\xee\x0e\xd6Hjh\xc6\x11\xf8:\xfe\xed\xba_\xaf\x8e\'\x0c\x7fZ\xd5\xb7\xbc\xba\xd3+\xf1\x98i\xab\x0c-\xd9\xe6>\x9e\xd0\xe6>\x9f\xebn\xf0\x15\xd9:\xec\xf7aXa\xb2,CAB7\x18g\xcc#\xbc\xb8\xf9\xa7\xf4V\xba\x0baN\x88\xb1\xea\x94\x05\x0cV\x99_\xc4\xe6\xb2\xd1|\x92\x05*@U\xe4\\\x8dR\x98\xdf\xbfS\x97\x12^\tr\x1f\x12\x8f\xdfi\x8e=\xc4I\xfcB\r\x99f\xe3\xe31\xee\xa9\xcd\x91\x1a\x1ei\xfd\xf4\x84\xc6\xda\x9e\xf3\x8aKn\xaa\xf7\x9eS\xcc\xbaXZ\x0cpbk\x18\x1f\x9aAl>y\xad\xcb\xcf\xe1Wm\xe7\xdd\xcc\x10eW\xe4h\x1dY\xb5Zs\xf1\xe7\x16_\xdc:I1R\xd3\xfe\xb1)\t\xddE\xbax\x06R\xdc\x1dSdlu\xd1\x9c\x00\xaf\x87\x8d1\xbf$\x08\xc6/y\xdf\x1f\x97z(\xff\xb9\xcb\xf2,\x91\xd7\xa0W\xfc\xe3\xe2\x905\x17O\xaf\x18\xc7\xb8?\x94^\xf5@\x80\x8d\xaa*p\xbeR0i\x17\x1e\'-\xfa\xd9\xb2\x03\xb8\x1fY\x13\xc1{\x7f\xa9\x86\t\x99\xee\xa2\xba\xab\xc1\xbb\x07a\xa5J\x01\x98\xe8\x8e\xa1\x8aV\xc1)^A\xd9\xe7\xfej`\xb4\xe9\xd3C\xab\xd4\xdb\xb1\x8c\x83\xaa&\xf1\xe2\xfc\xa1Lb\xa8\xbb\xd6\x83\xb7\xd8\xc5\x9e\xb5\xed\x1b\xe6\x91\x90\xe4\xfa\xfdD\xc2\xcb\xb7U\xb3|?(\x86=\xc2\xff\xd3P\xd2\xc5y\x93\x13r\xcd>5\x80\xde\xdaJ\xdd\x8b\xfa\x14\xd1\x85\xa8P\x06(F\xb3?\xefm\x8e\xe5C\xfe\x98\xaf\xed\xd1!(\x1f.\xc6M\xba\x00\xcb\xbfg5\xc8\x9d\x97+\x14\x87\xf5\x9d4\xb4l\xd5\xc5>\x90\xf2\x06\xa2\xc1R\x89\xf0P\xb4\xe5\x97\xdb\x07\xd3\xc6q\x08\xb9\xe7\r\xf9\x13\x8215\xcb\x92\xed\x99\xc7"\x1e\xe3Zsh\x0e\xe7\xae\x10Xs&)\x1d\xe5\xd5\xbc\x95\x8e\xa3\xd6k[k\x9c\xa0%\xd4\x83%\x88}\x90\xf0\xa7\xc7\xa4(\xdaE\xb9~\xae\x05\xbd}\xe2\xd0\xa5Y\xc1aV[\xab\x93S\xa6\xacg\r\x14\xc6\xe2J\xd6\xcck"\xcc\xfb\xb3\x97\x14\x13\x0b\xd1\xf5\xe7)_\x1e\x0b\xbb\x01\xf7\x11u\x85b\xdf\xab\xe3\xbb:\x84zF\x14u\xfe\x89\x90\xbc\xcaF\x15y\xa3\xa4[\xce\xcf-\xae\x18\x97N\xaa\xed\x84A\xfc\x9e\xeb\xb3\xfcH\x8ej\xcc\x9f \x1b\xc1\x1f}\'q.\xc0^\xd99\x1e\x91b-\xf9\xed\xfd\x9a\x7f\xb6\rO\xea\xc8\x94\xea\xf6\xb4\xdb\xf5\xc7\xb3\xef\xf6D\x12>5\xf3\x9d*\xc9\xf8\x9f]\xb01{d\xe7\'\x8f\xc0\xfbKB\x8dd\xb1\x84\x804\xbe\xe2?AT\x14\xdb4eJ\x96\xc5\xb9%\xe5\x1c\xc0L\xae\xd6O\xde\x1fjJIRD\x96\xa2\xdb\xfc\xc6t\xce\xe6\xe8"\x81\xe6\xc7\x7fuz\xb3\x91\'D\xac\xb2\x93O\xee\x14\xaa7yT\xcf\x81p\x0b(\xa1d\xda\xf8\xcb\x01\x98\x07\'\xfe/\xe4\xca\xab\x03uR"zY\xfb\x1f\x02\xc5\x9c\xa0\'\x89\xffO\x88cK\xac\xb1+S0]%E\x1a\xeb\x04\xf7\x0b\xba\xa0\xbb\xbd|\x06@T\xee\xe7\x17\xa1T\xe3"\x07\x07q' +b'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' diff --git a/tests/extmod/ujson_loads_float.py b/tests/extmod/ujson_loads_float.py index e368ca42e7..842718f37d 100644 --- a/tests/extmod/ujson_loads_float.py +++ b/tests/extmod/ujson_loads_float.py @@ -16,4 +16,5 @@ my_print(json.loads("1.2")) my_print(json.loads("1e2")) my_print(json.loads("-2.3")) my_print(json.loads("-2e3")) +my_print(json.loads("-2e+3")) my_print(json.loads("-2e-3")) diff --git a/tests/extmod/ussl_basic.py b/tests/extmod/ussl_basic.py index c8bdc81a48..b4e21c7dce 100644 --- a/tests/extmod/ussl_basic.py +++ b/tests/extmod/ussl_basic.py @@ -20,12 +20,13 @@ ss = ssl.wrap_socket(socket, server_side=1) # print print(repr(ss)[:12]) -# setblocking -try: - ss.setblocking(False) -except NotImplementedError: - print("setblocking: NotImplementedError") -ss.setblocking(True) +# setblocking() propagates call to the underlying stream object, and +# io.BytesIO doesn't have setblocking() (in CPython too). +# try: +# ss.setblocking(False) +# except NotImplementedError: +# print('setblocking: NotImplementedError') +# ss.setblocking(True) # write print(ss.write(b"aaaa")) diff --git a/tests/extmod/ussl_basic.py.exp b/tests/extmod/ussl_basic.py.exp index cb9c51f7a1..5282338319 100644 --- a/tests/extmod/ussl_basic.py.exp +++ b/tests/extmod/ussl_basic.py.exp @@ -1,7 +1,6 @@ ssl_handshake_status: -256 wrap_socket: OSError(5,) <_SSLSocket -setblocking: NotImplementedError 4 b'' read: OSError(-261,) diff --git a/tests/extmod/vfs_fat_ramdisklarge.py b/tests/extmod/vfs_fat_ramdisklarge.py new file mode 100644 index 0000000000..dcebd54288 --- /dev/null +++ b/tests/extmod/vfs_fat_ramdisklarge.py @@ -0,0 +1,70 @@ +# test making a FAT filesystem on a very large block device + +try: + import uos +except ImportError: + print("SKIP") + raise SystemExit + +try: + uos.VfsFat +except AttributeError: + print("SKIP") + raise SystemExit + + +class RAMBDevSparse: + + SEC_SIZE = 512 + + def __init__(self, blocks): + self.blocks = blocks + self.data = {} + + def readblocks(self, n, buf): + # print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf))) + assert len(buf) == self.SEC_SIZE + if n not in self.data: + self.data[n] = bytearray(self.SEC_SIZE) + buf[:] = self.data[n] + + def writeblocks(self, n, buf): + # print("writeblocks(%s, %x)" % (n, id(buf))) + mv = memoryview(buf) + for off in range(0, len(buf), self.SEC_SIZE): + s = n + off // self.SEC_SIZE + if s not in self.data: + self.data[s] = bytearray(self.SEC_SIZE) + self.data[s][:] = mv[off : off + self.SEC_SIZE] + + def ioctl(self, op, arg): + # print("ioctl(%d, %r)" % (op, arg)) + if op == 4: # BP_IOCTL_SEC_COUNT + return self.blocks + if op == 5: # BP_IOCTL_SEC_SIZE + return self.SEC_SIZE + + +try: + bdev = RAMBDevSparse(4 * 1024 * 1024 * 1024 // RAMBDevSparse.SEC_SIZE) + uos.VfsFat.mkfs(bdev) +except MemoryError: + print("SKIP") + raise SystemExit + +vfs = uos.VfsFat(bdev) +uos.mount(vfs, "/ramdisk") + +print("statvfs:", vfs.statvfs("/ramdisk")) + +f = open("/ramdisk/test.txt", "w") +f.write("test file") +f.close() + +print("statvfs:", vfs.statvfs("/ramdisk")) + +f = open("/ramdisk/test.txt") +print(f.read()) +f.close() + +uos.umount(vfs) diff --git a/tests/extmod/vfs_fat_ramdisklarge.py.exp b/tests/extmod/vfs_fat_ramdisklarge.py.exp new file mode 100644 index 0000000000..ea723e2249 --- /dev/null +++ b/tests/extmod/vfs_fat_ramdisklarge.py.exp @@ -0,0 +1,3 @@ +statvfs: (32768, 32768, 131054, 131053, 131053, 0, 0, 0, 0, 255) +statvfs: (32768, 32768, 131054, 131052, 131052, 0, 0, 0, 0, 255) +test file diff --git a/tests/extmod/websocket_basic.py b/tests/extmod/websocket_basic.py deleted file mode 100644 index 8c5cf58257..0000000000 --- a/tests/extmod/websocket_basic.py +++ /dev/null @@ -1,62 +0,0 @@ -try: - import uio - import uerrno - import websocket -except ImportError: - print("SKIP") - raise SystemExit - -# put raw data in the stream and do a websocket read -def ws_read(msg, sz): - ws = websocket.websocket(uio.BytesIO(msg)) - return ws.read(sz) - - -# do a websocket write and then return the raw data from the stream -def ws_write(msg, sz): - s = uio.BytesIO() - ws = websocket.websocket(s) - ws.write(msg) - s.seek(0) - return s.read(sz) - - -# basic frame -print(ws_read(b"\x81\x04ping", 4)) -print(ws_read(b"\x80\x04ping", 4)) # FRAME_CONT -print(ws_write(b"pong", 6)) - -# split frames are not supported -# print(ws_read(b"\x01\x04ping", 4)) - -# extended payloads -print(ws_read(b"\x81~\x00\x80" + b"ping" * 32, 128)) -print(ws_write(b"pong" * 32, 132)) - -# mask (returned data will be 'mask' ^ 'mask') -print(ws_read(b"\x81\x84maskmask", 4)) - -# close control frame -s = uio.BytesIO(b"\x88\x00") # FRAME_CLOSE -ws = websocket.websocket(s) -print(ws.read(1)) -s.seek(2) -print(s.read(4)) - -# misc control frames -print(ws_read(b"\x89\x00\x81\x04ping", 4)) # FRAME_PING -print(ws_read(b"\x8a\x00\x81\x04pong", 4)) # FRAME_PONG - -# close method -ws = websocket.websocket(uio.BytesIO()) -ws.close() - -# ioctl -ws = websocket.websocket(uio.BytesIO()) -print(ws.ioctl(8)) # GET_DATA_OPTS -print(ws.ioctl(9, 2)) # SET_DATA_OPTS -print(ws.ioctl(9)) -try: - ws.ioctl(-1) -except OSError as e: - print("ioctl: EINVAL:", e.args[0] == uerrno.EINVAL) diff --git a/tests/import/mpy_invalid.py b/tests/import/mpy_invalid.py index 188fb16127..3b416fc63c 100644 --- a/tests/import/mpy_invalid.py +++ b/tests/import/mpy_invalid.py @@ -56,6 +56,7 @@ user_files = { "/mod0.mpy": b"", # empty file "/mod1.mpy": b"M", # too short header "/mod2.mpy": b"M\x00\x00\x00", # bad version + "/mod3.mpy": b"M\x00\x00\x00\x7f", # qstr window too large } # create and mount a user filesystem diff --git a/tests/import/mpy_invalid.py.exp b/tests/import/mpy_invalid.py.exp index 197eb4f7b2..e7a7a89422 100644 --- a/tests/import/mpy_invalid.py.exp +++ b/tests/import/mpy_invalid.py.exp @@ -1,3 +1,4 @@ -mod0 RuntimeError Corrupt .mpy file -mod1 RuntimeError Corrupt .mpy file +mod0 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. +mod1 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. mod2 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. +mod3 MpyError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. diff --git a/tests/import/mpy_native.py b/tests/import/mpy_native.py new file mode 100644 index 0000000000..2499e3e206 --- /dev/null +++ b/tests/import/mpy_native.py @@ -0,0 +1,96 @@ +# test importing of .mpy files with native code (x64 only) + +import sys, uio + +try: + uio.IOBase + import uos + + uos.mount +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +if not (sys.platform == "linux" and sys.maxsize > 2 ** 32): + print("SKIP") + raise SystemExit + + +class UserFile(uio.IOBase): + def __init__(self, data): + self.data = data + self.pos = 0 + + def read(self): + return self.data + + def readinto(self, buf): + n = 0 + while n < len(buf) and self.pos < len(self.data): + buf[n] = self.data[self.pos] + n += 1 + self.pos += 1 + return n + + def ioctl(self, req, arg): + return 0 + + +class UserFS: + def __init__(self, files): + self.files = files + + def mount(self, readonly, mksfs): + pass + + def umount(self): + pass + + def stat(self, path): + if path in self.files: + return (32768, 0, 0, 0, 0, 0, 0, 0, 0, 0) + raise OSError + + def open(self, path, mode): + return UserFile(self.files[path]) + + +# these are the test .mpy files +user_files = { + # bad architecture + "/mod0.mpy": b"M\x04\xff\x00\x10", + # test loading of viper and asm + "/mod1.mpy": ( + b"M\x04\x0b\x1f\x20" # header + b"\x38" # n bytes, bytecode + b"\x01\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\xff" # prelude + b"\x11" # LOAD_CONST_NONE + b"\x5b" # RETURN_VALUE + b"\x02m\x02m\x00\x02" # simple_name, source_file, n_obj, n_raw_code + b"\x22" # n bytes, viper code + b"\x00\x00\x00\x00\x00\x00" # dummy machine code + b"\x00\x00" # qstr0 + b"\x01\x0c\x0aprint" # n_qstr, qstr0 + b"\x00\x00\x00" # scope_flags, n_obj, n_raw_code + b"\x23" # n bytes, asm code + b"\x00\x00\x00\x00\x00\x00\x00\x00" # dummy machine code + b"\x00\x00\x00" # scope_flags, n_pos_args, type_sig + ), +} + +# create and mount a user filesystem +uos.mount(UserFS(user_files), "/userfs") +sys.path.append("/userfs") + +# import .mpy files from the user filesystem +for i in range(len(user_files)): + mod = "mod%u" % i + try: + __import__(mod) + print(mod, "OK") + except ValueError as er: + print(mod, "ValueError", er) + +# unmount and undo path addition +uos.umount("/userfs") +sys.path.pop() diff --git a/tests/import/mpy_native.py.exp b/tests/import/mpy_native.py.exp new file mode 100644 index 0000000000..0b8958f5aa --- /dev/null +++ b/tests/import/mpy_native.py.exp @@ -0,0 +1,2 @@ +mod0 ValueError incompatible native .mpy architecture +mod1 OK diff --git a/tests/micropython/heapalloc_fail_bytearray.py b/tests/micropython/heapalloc_fail_bytearray.py new file mode 100644 index 0000000000..1bf7ddd600 --- /dev/null +++ b/tests/micropython/heapalloc_fail_bytearray.py @@ -0,0 +1,93 @@ +# test handling of failed heap allocation with bytearray + +import micropython + + +class GetSlice: + def __getitem__(self, idx): + return idx + + +sl = GetSlice()[:] + +# create bytearray +micropython.heap_lock() +try: + bytearray(4) +except MemoryError: + print("MemoryError: bytearray create") +micropython.heap_unlock() + +# create bytearray from bytes +micropython.heap_lock() +try: + bytearray(b"0123") +except MemoryError: + print("MemoryError: bytearray create from bytes") +micropython.heap_unlock() + +# create bytearray from iterator +r = range(4) +micropython.heap_lock() +try: + bytearray(r) +except MemoryError: + print("MemoryError: bytearray create from iter") +micropython.heap_unlock() + +# bytearray add +b = bytearray(4) +micropython.heap_lock() +try: + b + b"01" +except MemoryError: + print("MemoryError: bytearray.__add__") +micropython.heap_unlock() + +# bytearray iadd +b = bytearray(4) +micropython.heap_lock() +try: + b += b"01234567" +except MemoryError: + print("MemoryError: bytearray.__iadd__") +micropython.heap_unlock() +print(b) + +# bytearray append +b = bytearray(4) +micropython.heap_lock() +try: + for i in range(100): + b.append(1) +except MemoryError: + print("MemoryError: bytearray.append") +micropython.heap_unlock() + +# bytearray extend +b = bytearray(4) +micropython.heap_lock() +try: + b.extend(b"01234567") +except MemoryError: + print("MemoryError: bytearray.extend") +micropython.heap_unlock() + +# bytearray get with slice +b = bytearray(4) +micropython.heap_lock() +try: + b[sl] +except MemoryError: + print("MemoryError: bytearray subscr get") +micropython.heap_unlock() + +# extend bytearray using slice subscr +b = bytearray(4) +micropython.heap_lock() +try: + b[sl] = b"01234567" +except MemoryError: + print("MemoryError: bytearray subscr grow") +micropython.heap_unlock() +print(b) diff --git a/tests/micropython/heapalloc_fail_bytearray.py.exp b/tests/micropython/heapalloc_fail_bytearray.py.exp new file mode 100644 index 0000000000..57f6202f5e --- /dev/null +++ b/tests/micropython/heapalloc_fail_bytearray.py.exp @@ -0,0 +1,11 @@ +MemoryError: bytearray create +MemoryError: bytearray create from bytes +MemoryError: bytearray create from iter +MemoryError: bytearray.__add__ +MemoryError: bytearray.__iadd__ +bytearray(b'\x00\x00\x00\x00') +MemoryError: bytearray.append +MemoryError: bytearray.extend +MemoryError: bytearray subscr get +MemoryError: bytearray subscr grow +bytearray(b'\x00\x00\x00\x00') diff --git a/tests/micropython/heapalloc_fail_dict.py b/tests/micropython/heapalloc_fail_dict.py new file mode 100644 index 0000000000..ce2d158bd0 --- /dev/null +++ b/tests/micropython/heapalloc_fail_dict.py @@ -0,0 +1,21 @@ +# test handling of failed heap allocation with dict + +import micropython + +# create dict +x = 1 +micropython.heap_lock() +try: + {x: x} +except MemoryError: + print("MemoryError: create dict") +micropython.heap_unlock() + +# create dict view +x = {1: 1} +micropython.heap_lock() +try: + x.items() +except MemoryError: + print("MemoryError: dict.items") +micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_fail_dict.py.exp b/tests/micropython/heapalloc_fail_dict.py.exp new file mode 100644 index 0000000000..70cfc64ba4 --- /dev/null +++ b/tests/micropython/heapalloc_fail_dict.py.exp @@ -0,0 +1,2 @@ +MemoryError: create dict +MemoryError: dict.items diff --git a/tests/micropython/heapalloc_fail_list.py b/tests/micropython/heapalloc_fail_list.py new file mode 100644 index 0000000000..9a2e9a555f --- /dev/null +++ b/tests/micropython/heapalloc_fail_list.py @@ -0,0 +1,39 @@ +# test handling of failed heap allocation with list + +import micropython + + +class GetSlice: + def __getitem__(self, idx): + return idx + + +sl = GetSlice()[:] + +# create slice in VM +l = [1, 2, 3] +micropython.heap_lock() +try: + print(l[0:1]) +except MemoryError: + print("MemoryError: list index") +micropython.heap_unlock() + +# get from list using slice +micropython.heap_lock() +try: + l[sl] +except MemoryError: + print("MemoryError: list get slice") +micropython.heap_unlock() + +# extend list using slice subscr +l = [1, 2] +l2 = [3, 4, 5, 6, 7, 8, 9, 10] +micropython.heap_lock() +try: + l[sl] = l2 +except MemoryError: + print("MemoryError: list extend slice") +micropython.heap_unlock() +print(l) diff --git a/tests/micropython/heapalloc_fail_list.py.exp b/tests/micropython/heapalloc_fail_list.py.exp new file mode 100644 index 0000000000..0e1637476b --- /dev/null +++ b/tests/micropython/heapalloc_fail_list.py.exp @@ -0,0 +1,4 @@ +MemoryError: list index +MemoryError: list get slice +MemoryError: list extend slice +[1, 2] diff --git a/tests/micropython/heapalloc_fail_memoryview.py b/tests/micropython/heapalloc_fail_memoryview.py new file mode 100644 index 0000000000..da2d1abffa --- /dev/null +++ b/tests/micropython/heapalloc_fail_memoryview.py @@ -0,0 +1,28 @@ +# test handling of failed heap allocation with memoryview + +import micropython + + +class GetSlice: + def __getitem__(self, idx): + return idx + + +sl = GetSlice()[:] + +# create memoryview +micropython.heap_lock() +try: + memoryview(b"") +except MemoryError: + print("MemoryError: memoryview create") +micropython.heap_unlock() + +# memoryview get with slice +m = memoryview(b"") +micropython.heap_lock() +try: + m[sl] +except MemoryError: + print("MemoryError: memoryview subscr get") +micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_fail_memoryview.py.exp b/tests/micropython/heapalloc_fail_memoryview.py.exp new file mode 100644 index 0000000000..e41a1e6cb2 --- /dev/null +++ b/tests/micropython/heapalloc_fail_memoryview.py.exp @@ -0,0 +1,2 @@ +MemoryError: memoryview create +MemoryError: memoryview subscr get diff --git a/tests/micropython/heapalloc_fail_set.py b/tests/micropython/heapalloc_fail_set.py new file mode 100644 index 0000000000..8eb887f711 --- /dev/null +++ b/tests/micropython/heapalloc_fail_set.py @@ -0,0 +1,23 @@ +# test handling of failed heap allocation with set + +import micropython + +# create set +x = 1 +micropython.heap_lock() +try: + { + x, + } +except MemoryError: + print("MemoryError: set create") +micropython.heap_unlock() + +# set copy +s = {1, 2} +micropython.heap_lock() +try: + s.copy() +except MemoryError: + print("MemoryError: set copy") +micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_fail_set.py.exp b/tests/micropython/heapalloc_fail_set.py.exp new file mode 100644 index 0000000000..dd749672dc --- /dev/null +++ b/tests/micropython/heapalloc_fail_set.py.exp @@ -0,0 +1,2 @@ +MemoryError: set create +MemoryError: set copy diff --git a/tests/micropython/heapalloc_fail_tuple.py b/tests/micropython/heapalloc_fail_tuple.py new file mode 100644 index 0000000000..de79385e3e --- /dev/null +++ b/tests/micropython/heapalloc_fail_tuple.py @@ -0,0 +1,12 @@ +# test handling of failed heap allocation with tuple + +import micropython + +# create tuple +x = 1 +micropython.heap_lock() +try: + (x,) +except MemoryError: + print("MemoryError: tuple create") +micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_fail_tuple.py.exp b/tests/micropython/heapalloc_fail_tuple.py.exp new file mode 100644 index 0000000000..5bf632d799 --- /dev/null +++ b/tests/micropython/heapalloc_fail_tuple.py.exp @@ -0,0 +1 @@ +MemoryError: tuple create diff --git a/tests/micropython/viper_types.py b/tests/micropython/viper_types.py new file mode 100644 index 0000000000..3af148171e --- /dev/null +++ b/tests/micropython/viper_types.py @@ -0,0 +1,32 @@ +# test various type conversions + +import micropython + +# converting incoming arg to bool +@micropython.viper +def f1(x: bool): + print(x) + + +f1(0) +f1(1) +f1([]) +f1([1]) + +# taking and returning a bool +@micropython.viper +def f2(x: bool) -> bool: + return x + + +print(f2([])) +print(f2([1])) + +# converting to bool within function +@micropython.viper +def f3(x) -> bool: + return bool(x) + + +print(f3([])) +print(f3(-1)) diff --git a/tests/micropython/viper_types.py.exp b/tests/micropython/viper_types.py.exp new file mode 100644 index 0000000000..b7bef156ea --- /dev/null +++ b/tests/micropython/viper_types.py.exp @@ -0,0 +1,8 @@ +False +True +False +True +False +True +False +True diff --git a/tests/run-tests b/tests/run-tests index e00d6930f0..184743b341 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -110,7 +110,16 @@ def run_micropython(pyb, args, test_file, is_special=False): banner = get(True) output_mupy = banner + b''.join(send_get(line) for line in f) send_get(b'\x04') # exit the REPL, so coverage info is saved - p.kill() + # At this point the process might have exited already, but trying to + # kill it 'again' normally doesn't result in exceptions as Python and/or + # the OS seem to try to handle this nicely. When running Linux on WSL + # though, the situation differs and calling Popen.kill after the process + # terminated results in a ProcessLookupError. Just catch that one here + # since we just want the process to be gone and that's the case. + try: + p.kill() + except ProcessLookupError: + pass os.close(emulator) os.close(subterminal) else: @@ -128,7 +137,7 @@ def run_micropython(pyb, args, test_file, is_special=False): # if running via .mpy, first compile the .py file if args.via_mpy: - subprocess.check_output([MPYCROSS, '-mcache-lookup-bc', '-o', 'mpytest.mpy', test_file]) + subprocess.check_output([MPYCROSS, '-mcache-lookup-bc', '-o', 'mpytest.mpy', '-X', 'emit=' + args.emit, test_file]) cmdlist.extend(['-m', 'mpytest']) else: cmdlist.append(test_file) @@ -198,7 +207,7 @@ def run_micropython(pyb, args, test_file, is_special=False): if lines_exp[i][1].match(lines_mupy[i_mupy]): lines_mupy[i_mupy] = lines_exp[i][0] else: - #print("don't match: %r %s" % (lines_exp[i][1], lines_mupy[i_mupy])) # DEBUG + print("don't match: %r %s" % (lines_exp[i][1], lines_mupy[i_mupy])) # DEBUG pass i_mupy += 1 if i_mupy >= len(lines_mupy): diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 06b5d37903..55739d7af8 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -13,6 +13,7 @@ false true 80000000 80000000 abc +% # GC 0 0 @@ -70,10 +71,10 @@ sched(2)=1 sched(3)=1 sched(4)=0 unlocked -3 -2 -1 0 +1 +2 +3 0123456789 b'0123456789' 7300 7300 diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 9572f8f2aa..5c3a6af32d 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -41,7 +41,7 @@ class FreezeError(Exception): class Config: - MPY_VERSION = 3 + MPY_VERSION = 4 MICROPY_LONGINT_IMPL_NONE = 0 MICROPY_LONGINT_IMPL_LONGLONG = 1 MICROPY_LONGINT_IMPL_MPZ = 2 @@ -49,6 +49,50 @@ class Config: config = Config() + +class QStrType: + def __init__(self, str): + self.str = str + self.qstr_esc = qstrutil.qstr_escape(self.str) + self.qstr_id = "MP_QSTR_" + self.qstr_esc + + +# Initialise global list of qstrs with static qstrs +global_qstrs = [None] # MP_QSTR_NULL should never be referenced +for n in qstrutil.static_qstr_list: + global_qstrs.append(QStrType(n)) + + +class QStrWindow: + def __init__(self, size): + self.window = [] + self.size = size + + def push(self, val): + self.window = [val] + self.window[: self.size - 1] + + def access(self, idx): + val = self.window[idx] + self.window = [val] + self.window[:idx] + self.window[idx + 1 :] + return val + + +MP_CODE_BYTECODE = 2 +MP_CODE_NATIVE_PY = 3 +MP_CODE_NATIVE_VIPER = 4 +MP_CODE_NATIVE_ASM = 5 + +MP_NATIVE_ARCH_NONE = 0 +MP_NATIVE_ARCH_X86 = 1 +MP_NATIVE_ARCH_X64 = 2 +MP_NATIVE_ARCH_ARMV6 = 3 +MP_NATIVE_ARCH_ARMV6M = 4 +MP_NATIVE_ARCH_ARMV7M = 5 +MP_NATIVE_ARCH_ARMV7EM = 6 +MP_NATIVE_ARCH_ARMV7EMSP = 7 +MP_NATIVE_ARCH_ARMV7EMDP = 8 +MP_NATIVE_ARCH_XTENSA = 9 + MP_OPCODE_BYTE = 0 MP_OPCODE_QSTR = 1 MP_OPCODE_VAR_UINT = 2 @@ -106,7 +150,7 @@ def make_opcode_format(): OC4(O, O, U, U), # 0x38-0x3b OC4(U, O, B, O), # 0x3c-0x3f OC4(O, B, B, O), # 0x40-0x43 - OC4(B, B, O, B), # 0x44-0x47 + OC4(O, U, O, B), # 0x44-0x47 OC4(U, U, U, U), # 0x48-0x4b OC4(U, U, U, U), # 0x4c-0x4f OC4(V, V, U, V), # 0x50-0x53 @@ -158,7 +202,7 @@ def make_opcode_format(): # this function mirrors that in py/bc.c -def mp_opcode_format(bytecode, ip, opcode_format=make_opcode_format()): +def mp_opcode_format(bytecode, ip, count_var_uint, opcode_format=make_opcode_format()): opcode = bytecode[ip] ip_start = ip f = (opcode_format[opcode >> 2] >> (2 * (opcode & 3))) & 3 @@ -187,9 +231,10 @@ def mp_opcode_format(bytecode, ip, opcode_format=make_opcode_format()): ) ip += 1 if f == MP_OPCODE_VAR_UINT: - while bytecode[ip] & 0x80 != 0: + if count_var_uint: + while bytecode[ip] & 0x80 != 0: + ip += 1 ip += 1 - ip += 1 elif f == MP_OPCODE_OFFSET: ip += 2 ip += extra_byte @@ -207,8 +252,7 @@ def decode_uint(bytecode, ip): return ip, unum -def extract_prelude(bytecode): - ip = 0 +def extract_prelude(bytecode, ip): ip, n_state = decode_uint(bytecode, ip) ip, n_exc_stack = decode_uint(bytecode, ip) scope_flags = bytecode[ip] @@ -241,21 +285,40 @@ def extract_prelude(bytecode): ) -class RawCode: +class MPFunTable: + pass + + +class RawCode(object): # a set of all escaped names, to make sure they are unique escaped_names = set() - def __init__(self, bytecode, qstrs, objs, raw_codes): + # convert code kind number to string + code_kind_str = { + MP_CODE_BYTECODE: "MP_CODE_BYTECODE", + MP_CODE_NATIVE_PY: "MP_CODE_NATIVE_PY", + MP_CODE_NATIVE_VIPER: "MP_CODE_NATIVE_VIPER", + MP_CODE_NATIVE_ASM: "MP_CODE_NATIVE_ASM", + } + + def __init__(self, code_kind, bytecode, prelude_offset, qstrs, objs, raw_codes): # set core variables + self.code_kind = code_kind self.bytecode = bytecode + self.prelude_offset = prelude_offset self.qstrs = qstrs self.objs = objs self.raw_codes = raw_codes - # extract prelude - self.ip, self.ip2, self.prelude = extract_prelude(self.bytecode) - self.simple_name = self._unpack_qstr(self.ip2) - self.source_file = self._unpack_qstr(self.ip2 + 2) + if self.prelude_offset is None: + # no prelude, assign a dummy simple_name + self.prelude_offset = 0 + self.simple_name = global_qstrs[1] + else: + # extract prelude + self.ip, self.ip2, self.prelude = extract_prelude(self.bytecode, self.prelude_offset) + self.simple_name = self._unpack_qstr(self.ip2) + self.source_file = self._unpack_qstr(self.ip2 + 2) def _unpack_qstr(self, ip): qst = self.bytecode[ip] | self.bytecode[ip + 1] << 8 @@ -267,7 +330,7 @@ class RawCode: rc.freeze("") # TODO - def freeze(self, parent_name): + def freeze_children(self, parent_name): self.escaped_name = parent_name + self.simple_name.qstr_esc # make sure the escaped name is unique @@ -277,71 +340,17 @@ class RawCode: i += 1 RawCode.escaped_names.add(self.escaped_name) - sizes = { - "bytecode": 0, - "strings": 0, - "raw_code_overhead": 0, - "const_table_overhead": 0, - "string_overhead": 0, - "number_overhead": 0, - } # emit children first for rc in self.raw_codes: - subsize = rc.freeze(self.escaped_name + "_") - for k in sizes: - sizes[k] += subsize[k] - - # generate bytecode data - print() - print( - "// frozen bytecode for file %s, scope %s%s" - % (self.source_file.str, parent_name, self.simple_name.str) - ) - print("// bytecode size", len(self.bytecode)) - print("STATIC ", end="") - if not config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: - print("const ", end="") - print("byte bytecode_data_%s[%u] = {" % (self.escaped_name, len(self.bytecode))) - sizes["bytecode"] += len(self.bytecode) - print(" ", end="") - for i in range(self.ip2): - print(" 0x%02x," % self.bytecode[i], end="") - print() - print(" // simple name") - print(" ", self.simple_name.qstr_id, "& 0xff,", self.simple_name.qstr_id, ">> 8,") - print(" // source file") - print(" ", self.source_file.qstr_id, "& 0xff,", self.source_file.qstr_id, ">> 8,") - print(" // code info") - print(" ", end="") - for i in range(self.ip2 + 4, self.ip): - print(" 0x%02x," % self.bytecode[i], end="") - print() - print(" // bytecode") - ip = self.ip - while ip < len(self.bytecode): - f, sz = mp_opcode_format(self.bytecode, ip) - opcode = self.bytecode[ip] - if opcode in opcode_names: - opcode = opcode_names[opcode] - else: - opcode = "0x%02x" % opcode - if f == 1: - qst = self._unpack_qstr(ip + 1).qstr_id - extra = "" if sz == 3 else " 0x%02x," % self.bytecode[ip + 3] - print(" {}, {} & 0xff, {} >> 8,{}".format(opcode, qst, qst, extra)) - else: - print( - " {},{}".format( - opcode, "".join(" 0x%02x," % self.bytecode[ip + i] for i in range(1, sz)) - ) - ) - ip += sz - print("};") + rc.freeze(self.escaped_name + "_") + def freeze_constants(self): # generate constant objects for i, obj in enumerate(self.objs): obj_name = "const_obj_%s_%u" % (self.escaped_name, i) - if obj is Ellipsis: + if obj is MPFunTable: + pass + elif obj is Ellipsis: print("#define %s mp_const_ellipsis_obj" % obj_name) elif is_str_type(obj) or is_bytes_type(obj): if is_str_type(obj): @@ -350,19 +359,15 @@ class RawCode: else: obj_type = "mp_type_bytes" print( - 'STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"}; // %s' + 'STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};' % ( obj_name, obj_type, qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH), len(obj), "".join(("\\x%02x" % b) for b in obj), - obj, ) ) - sizes["strings"] += len(obj) - sizes["string_overhead"] += 16 - elif is_int_type(obj): if config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE: # TODO check if we can actually fit this long-int into a small-int @@ -385,10 +390,9 @@ class RawCode: digs = ",".join(("%#x" % d) for d in digs) print( "STATIC const mp_obj_int_t %s = {{&mp_type_int}, " - "{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t[]){%s}}};" - % (obj_name, neg, ndigs, ndigs, bits_per_dig, digs) + "{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t*)(const uint%u_t[]){%s}}};" + % (obj_name, neg, ndigs, ndigs, bits_per_dig, bits_per_dig, digs) ) - sizes["number_overhead"] += 16 elif type(obj) is float: print( "#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B" @@ -397,13 +401,11 @@ class RawCode: "STATIC const mp_obj_float_t %s = {{&mp_type_float}, %.16g};" % (obj_name, obj) ) print("#endif") - sizes["number_overhead"] += 8 elif type(obj) is complex: print( "STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, %.16g, %.16g};" % (obj_name, obj.real, obj.imag) ) - sizes["number_overhead"] += 12 else: raise FreezeError(self, "freezing of object %r is not implemented" % (obj,)) @@ -415,11 +417,11 @@ class RawCode: % (self.escaped_name, const_table_len) ) for qst in self.qstrs: - sizes["const_table_overhead"] += 4 print(" MP_ROM_QSTR(%s)," % global_qstrs[qst].qstr_id) for i in range(len(self.objs)): - sizes["const_table_overhead"] += 4 - if type(self.objs[i]) is float: + if self.objs[i] is MPFunTable: + print(" mp_fun_table,") + elif type(self.objs[i]) is float: print( "#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B" ) @@ -436,54 +438,236 @@ class RawCode: else: print(" MP_ROM_PTR(&const_obj_%s_%u)," % (self.escaped_name, i)) for rc in self.raw_codes: - sizes["const_table_overhead"] += 4 print(" MP_ROM_PTR(&raw_code_%s)," % rc.escaped_name) print("};") + def freeze_module(self, qstr_links=(), type_sig=0): # generate module if self.simple_name.str != "": print("STATIC ", end="") print("const mp_raw_code_t raw_code_%s = {" % self.escaped_name) - print(" .kind = MP_CODE_BYTECODE,") + print(" .kind = %s," % RawCode.code_kind_str[self.code_kind]) print(" .scope_flags = 0x%02x," % self.prelude[2]) print(" .n_pos_args = %u," % self.prelude[3]) - print(" .data.u_byte = {") - print(" .bytecode = bytecode_data_%s," % self.escaped_name) - if const_table_len: - print(" .const_table = (mp_uint_t*)const_table_data_%s," % self.escaped_name) + print(" .fun_data = fun_data_%s," % self.escaped_name) + if len(self.qstrs) + len(self.objs) + len(self.raw_codes): + print(" .const_table = (mp_uint_t*)const_table_data_%s," % self.escaped_name) else: - print(" .const_table = NULL,") - print(" #if MICROPY_PERSISTENT_CODE_SAVE") - print(" .bc_len = %u," % len(self.bytecode)) - print(" .n_obj = %u," % len(self.objs)) - print(" .n_raw_code = %u," % len(self.raw_codes)) - print(" #endif") - print(" },") + print(" .const_table = NULL,") + print(" #if MICROPY_PERSISTENT_CODE_SAVE") + print(" .fun_data_len = %u," % len(self.bytecode)) + print(" .n_obj = %u," % len(self.objs)) + print(" .n_raw_code = %u," % len(self.raw_codes)) + print(" #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM") + print(" .prelude_offset = %u," % self.prelude_offset) + print(" .n_qstr = %u," % len(qstr_links)) + print(" .qstr_link = NULL,") # TODO + print(" #endif") + print(" #endif") + print(" #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM") + print(" .type_sig = %u," % type_sig) + print(" #endif") print("};") - sizes["raw_code_overhead"] += 16 - - return sizes -def read_uint(f): +class RawCodeBytecode(RawCode): + def __init__(self, bytecode, qstrs, objs, raw_codes): + super(RawCodeBytecode, self).__init__( + MP_CODE_BYTECODE, bytecode, 0, qstrs, objs, raw_codes + ) + + def freeze(self, parent_name): + self.freeze_children(parent_name) + + # generate bytecode data + print() + print( + "// frozen bytecode for file %s, scope %s%s" + % (self.source_file.str, parent_name, self.simple_name.str) + ) + print("STATIC ", end="") + if not config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE: + print("const ", end="") + print("byte fun_data_%s[%u] = {" % (self.escaped_name, len(self.bytecode))) + print(" ", end="") + for i in range(self.ip2): + print(" 0x%02x," % self.bytecode[i], end="") + print() + print(" ", self.simple_name.qstr_id, "& 0xff,", self.simple_name.qstr_id, ">> 8,") + print(" ", self.source_file.qstr_id, "& 0xff,", self.source_file.qstr_id, ">> 8,") + print(" ", end="") + for i in range(self.ip2 + 4, self.ip): + print(" 0x%02x," % self.bytecode[i], end="") + print() + ip = self.ip + while ip < len(self.bytecode): + f, sz = mp_opcode_format(self.bytecode, ip, True) + if f == 1: + qst = self._unpack_qstr(ip + 1).qstr_id + extra = "" if sz == 3 else " 0x%02x," % self.bytecode[ip + 3] + print(" ", "0x%02x," % self.bytecode[ip], qst, "& 0xff,", qst, ">> 8,", extra) + else: + print(" ", "".join("0x%02x, " % self.bytecode[ip + i] for i in range(sz))) + ip += sz + print("};") + + self.freeze_constants() + self.freeze_module() + + +class RawCodeNative(RawCode): + def __init__( + self, + code_kind, + fun_data, + prelude_offset, + prelude, + qstr_links, + qstrs, + objs, + raw_codes, + type_sig, + ): + super(RawCodeNative, self).__init__( + code_kind, fun_data, prelude_offset, qstrs, objs, raw_codes + ) + self.prelude = prelude + self.qstr_links = qstr_links + self.type_sig = type_sig + if config.native_arch in (MP_NATIVE_ARCH_X86, MP_NATIVE_ARCH_X64): + self.fun_data_attributes = '__attribute__((section(".text,\\"ax\\",@progbits # ")))' + else: + self.fun_data_attributes = '__attribute__((section(".text,\\"ax\\",%progbits @ ")))' + + def _asm_thumb_rewrite_mov(self, pc, val): + print(" (%u & 0xf0) | (%s >> 12)," % (self.bytecode[pc], val), end="") + print(" (%u & 0xfb) | (%s >> 9 & 0x04)," % (self.bytecode[pc + 1], val), end="") + print(" (%s & 0xff)," % (val,), end="") + print(" (%u & 0x07) | (%s >> 4 & 0x70)," % (self.bytecode[pc + 3], val)) + + def _link_qstr(self, pc, kind, qst): + if kind == 0: + print(" %s & 0xff, %s >> 8," % (qst, qst)) + else: + if kind == 2: + qst = "((uintptr_t)MP_OBJ_NEW_QSTR(%s))" % qst + if config.native_arch in (MP_NATIVE_ARCH_X86, MP_NATIVE_ARCH_X64): + print(" %s & 0xff, %s >> 8, 0, 0," % (qst, qst)) + elif MP_NATIVE_ARCH_ARMV6M <= config.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP: + if is_obj: + self._asm_thumb_rewrite_mov(i, qst) + self._asm_thumb_rewrite_mov(i + 4, "(%s >> 16)" % qst) + else: + self._asm_thumb_rewrite_mov(i, qst) + else: + assert 0 + + def freeze(self, parent_name): + self.freeze_children(parent_name) + + # generate native code data + print() + if self.code_kind == MP_CODE_NATIVE_PY: + print( + "// frozen native code for file %s, scope %s%s" + % (self.source_file.str, parent_name, self.simple_name.str) + ) + elif self.code_kind == MP_CODE_NATIVE_VIPER: + print("// frozen viper code for scope %s" % (parent_name,)) + else: + print("// frozen assembler code for scope %s" % (parent_name,)) + print( + "STATIC const byte fun_data_%s[%u] %s = {" + % (self.escaped_name, len(self.bytecode), self.fun_data_attributes) + ) + + if self.code_kind == MP_CODE_NATIVE_PY: + i_top = self.prelude_offset + else: + i_top = len(self.bytecode) + i = 0 + qi = 0 + while i < i_top: + if qi < len(self.qstr_links) and i == self.qstr_links[qi][0]: + # link qstr + qi_off, qi_kind, qi_val = self.qstr_links[qi] + qst = global_qstrs[qi_val].qstr_id + self._link_qstr(i, qi_kind, qst) + i += 4 + qi += 1 + else: + # copy machine code (max 16 bytes) + i16 = min(i + 16, i_top) + if qi < len(self.qstr_links): + i16 = min(i16, self.qstr_links[qi][0]) + print(" ", end="") + for ii in range(i, i16): + print(" 0x%02x," % self.bytecode[ii], end="") + print() + i = i16 + + if self.code_kind == MP_CODE_NATIVE_PY: + print(" ", end="") + for i in range(self.prelude_offset, self.ip2): + print(" 0x%02x," % self.bytecode[i], end="") + print() + + print(" ", self.simple_name.qstr_id, "& 0xff,", self.simple_name.qstr_id, ">> 8,") + print(" ", self.source_file.qstr_id, "& 0xff,", self.source_file.qstr_id, ">> 8,") + + print(" ", end="") + for i in range(self.ip2 + 4, self.ip): + print(" 0x%02x," % self.bytecode[i], end="") + print() + + print("};") + + self.freeze_constants() + self.freeze_module(self.qstr_links, self.type_sig) + + +class BytecodeBuffer: + def __init__(self, size): + self.buf = bytearray(size) + self.idx = 0 + + def is_full(self): + return self.idx == len(self.buf) + + def append(self, b): + self.buf[self.idx] = b + self.idx += 1 + + +def read_byte(f, out=None): + b = bytes_cons(f.read(1))[0] + if out is not None: + out.append(b) + return b + + +def read_uint(f, out=None): i = 0 while True: - b = bytes_cons(f.read(1))[0] + b = read_byte(f, out) i = (i << 7) | (b & 0x7F) if b & 0x80 == 0: break return i -global_qstrs = [] -qstr_type = namedtuple("qstr", ("str", "qstr_esc", "qstr_id")) - - -def read_qstr(f): +def read_qstr(f, qstr_win): ln = read_uint(f) + if ln == 0: + # static qstr + return bytes_cons(f.read(1))[0] + if ln & 1: + # qstr in table + return qstr_win.access(ln >> 1) + ln >>= 1 data = str_cons(f.read(ln), "utf8") - qstr_esc = qstrutil.qstr_escape(data) - global_qstrs.append(qstr_type(data, qstr_esc, "MP_QSTR_" + qstr_esc)) + global_qstrs.append(QStrType(data)) + qstr_win.push(len(global_qstrs) - 1) return len(global_qstrs) - 1 @@ -507,33 +691,119 @@ def read_obj(f): assert 0 -def read_qstr_and_pack(f, bytecode, ip): - qst = read_qstr(f) - bytecode[ip] = qst & 0xFF - bytecode[ip + 1] = qst >> 8 +def read_prelude(f, bytecode): + n_state = read_uint(f, bytecode) + n_exc_stack = read_uint(f, bytecode) + scope_flags = read_byte(f, bytecode) + n_pos_args = read_byte(f, bytecode) + n_kwonly_args = read_byte(f, bytecode) + n_def_pos_args = read_byte(f, bytecode) + l1 = bytecode.idx + code_info_size = read_uint(f, bytecode) + l2 = bytecode.idx + for _ in range(code_info_size - (l2 - l1)): + read_byte(f, bytecode) + while read_byte(f, bytecode) != 255: + pass + return l2, ( + n_state, + n_exc_stack, + scope_flags, + n_pos_args, + n_kwonly_args, + n_def_pos_args, + code_info_size, + ) -def read_bytecode_qstrs(file, bytecode, ip): - while ip < len(bytecode): - f, sz = mp_opcode_format(bytecode, ip) - if f == 1: - read_qstr_and_pack(file, bytecode, ip + 1) - ip += sz +def read_qstr_and_pack(f, bytecode, qstr_win): + qst = read_qstr(f, qstr_win) + bytecode.append(qst & 0xFF) + bytecode.append(qst >> 8) -def read_raw_code(f): - bc_len = read_uint(f) - bytecode = bytearray(f.read(bc_len)) - ip, ip2, prelude = extract_prelude(bytecode) - read_qstr_and_pack(f, bytecode, ip2) # simple_name - read_qstr_and_pack(f, bytecode, ip2 + 2) # source_file - read_bytecode_qstrs(f, bytecode, ip) - n_obj = read_uint(f) - n_raw_code = read_uint(f) - qstrs = [read_qstr(f) for _ in range(prelude[3] + prelude[4])] - objs = [read_obj(f) for _ in range(n_obj)] - raw_codes = [read_raw_code(f) for _ in range(n_raw_code)] - return RawCode(bytecode, qstrs, objs, raw_codes) +def read_bytecode(file, bytecode, qstr_win): + while not bytecode.is_full(): + op = read_byte(file, bytecode) + f, sz = mp_opcode_format(bytecode.buf, bytecode.idx - 1, False) + sz -= 1 + if f == MP_OPCODE_QSTR: + read_qstr_and_pack(file, bytecode, qstr_win) + sz -= 2 + elif f == MP_OPCODE_VAR_UINT: + while read_byte(file, bytecode) & 0x80: + pass + for _ in range(sz): + read_byte(file, bytecode) + + +def read_raw_code(f, qstr_win): + kind_len = read_uint(f) + kind = (kind_len & 3) + MP_CODE_BYTECODE + fun_data_len = kind_len >> 2 + fun_data = BytecodeBuffer(fun_data_len) + + if kind == MP_CODE_BYTECODE: + name_idx, prelude = read_prelude(f, fun_data) + read_bytecode(f, fun_data, qstr_win) + else: + fun_data.buf[:] = f.read(fun_data_len) + + qstr_links = [] + if kind in (MP_CODE_NATIVE_PY, MP_CODE_NATIVE_VIPER): + # load qstr link table + n_qstr_link = read_uint(f) + for _ in range(n_qstr_link): + off = read_uint(f, qstr_win) + qst = read_qstr(f, qstr_win) + qstr_links.append((off >> 2, off & 3, qst)) + + type_sig = 0 + if kind == MP_CODE_NATIVE_PY: + prelude_offset = read_uint(f) + _, name_idx, prelude = extract_prelude(fun_data.buf, prelude_offset) + else: + prelude_offset = None + scope_flags = read_uint(f) + n_pos_args = 0 + if kind == MP_CODE_NATIVE_ASM: + n_pos_args = read_uint(f) + type_sig = read_uint(f) + prelude = (None, None, scope_flags, n_pos_args, 0) + + if kind in (MP_CODE_BYTECODE, MP_CODE_NATIVE_PY): + fun_data.idx = name_idx # rewind to where qstrs are in prelude + read_qstr_and_pack(f, fun_data, qstr_win) # simple_name + read_qstr_and_pack(f, fun_data, qstr_win) # source_file + + qstrs = [] + objs = [] + raw_codes = [] + if kind != MP_CODE_NATIVE_ASM: + # load constant table + n_obj = read_uint(f) + n_raw_code = read_uint(f) + qstrs = [read_qstr(f, qstr_win) for _ in range(prelude[3] + prelude[4])] + if kind != MP_CODE_BYTECODE: + objs.append(MPFunTable) + objs.extend([read_obj(f) for _ in range(n_obj)]) + raw_codes = [read_raw_code(f, qstr_win) for _ in range(n_raw_code)] + + if kind == MP_CODE_BYTECODE: + return RawCodeBytecode(fun_data.buf, qstrs, objs, raw_codes) + else: + return RawCodeNative( + kind, + fun_data.buf, + prelude_offset, + prelude, + qstr_links, + qstrs, + objs, + raw_codes, + type_sig, + ) + def read_mpy(filename): @@ -543,11 +813,15 @@ def read_mpy(filename): raise Exception("not a valid .mpy file") if header[1] != config.MPY_VERSION: raise Exception("incompatible .mpy version") - feature_flags = header[2] - config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = (feature_flags & 1) != 0 - config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_flags & 2) != 0 + feature_byte = header[2] + qw_size = read_uint(f) + config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE = (feature_byte & 1) != 0 + config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_byte & 2) != 0 + config.native_arch = feature_byte >> 2 config.mp_small_int_bits = header[3] - return read_raw_code(f) + qstr_win = QStrWindow(qw_size) + return read_raw_code(f, qstr_win) + def dump_mpy(raw_codes): @@ -560,7 +834,7 @@ def freeze_mpy(base_qstrs, raw_codes): new = {} for q in global_qstrs: # don't add duplicates - if q.qstr_esc in base_qstrs or q.qstr_esc in new: + if q is None or q.qstr_esc in base_qstrs or q.qstr_esc in new: continue new[q.qstr_esc] = (len(new), q.qstr_esc, q.str) new = sorted(new.values(), key=lambda x: x[0]) @@ -608,13 +882,14 @@ def freeze_mpy(base_qstrs, raw_codes): print("#endif") print() - print("enum {") - for i in range(len(new)): - if i == 0: - print(" MP_QSTR_%s = MP_QSTRnumber_of," % new[i][1]) - else: - print(" MP_QSTR_%s," % new[i][1]) - print("};") + if new: + print("enum {") + for i in range(len(new)): + if i == 0: + print(" MP_QSTR_%s = MP_QSTRnumber_of," % new[i][1]) + else: + print(" MP_QSTR_%s," % new[i][1]) + print("};") print() print("const qstr_attr_t mp_qstr_frozen_const_attr[] = {") @@ -648,9 +923,8 @@ def freeze_mpy(base_qstrs, raw_codes): print(" },") print("};") - sizes = {} for rc in raw_codes: - sizes[rc.source_file.str] = rc.freeze(rc.source_file.str.replace("/", "_")[:-3] + "_") + rc.freeze(rc.source_file.str.replace("/", "_")[:-3] + "_") print() print("const char mp_frozen_mpy_names[] = {") @@ -664,22 +938,8 @@ def freeze_mpy(base_qstrs, raw_codes): print("const mp_raw_code_t *const mp_frozen_mpy_content[] = {") for rc in raw_codes: print(" &raw_code_%s," % rc.escaped_name) - size = sizes[rc.source_file.str] - print(" // Total size:", sum(size.values())) - for k in size: - print(" // {} {}".format(k, size[k])) print("};") - print() - print( - "// Total size:", sum([sum(x.values()) for x in sizes.values()]) + sum(qstr_size.values()) - ) - for k in size: - total = sum([x[k] for x in sizes.values()]) - print("// {} {}".format(k, total)) - for k in qstr_size: - print("// qstr {} {}".format(k, qstr_size[k])) - def main(): import argparse diff --git a/tools/pyboard.py b/tools/pyboard.py index 200f4578a4..908448da75 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -28,6 +28,7 @@ Or: Then: pyb.enter_raw_repl() + pyb.exec('import pyb') pyb.exec('pyb.LED(1).on()') pyb.exit_raw_repl() @@ -267,6 +268,9 @@ class Pyboard: self.serial.close() def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None): + # if data_consumer is used then data is not accumulated and the ending must be 1 byte long + assert data_consumer is None or len(ending) == 1 + data = self.serial.read(min_num_bytes) if data_consumer: data_consumer(data) @@ -276,9 +280,11 @@ class Pyboard: break elif self.serial.inWaiting() > 0: new_data = self.serial.read(1) - data = data + new_data if data_consumer: data_consumer(new_data) + data = new_data + else: + data = data + new_data timeout_count = 0 else: timeout_count += 1 diff --git a/tools/upip.py b/tools/upip.py index a7187e700d..212cd26d0b 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -17,6 +17,7 @@ gc.collect() debug = False +index_urls = ["https://micropython.org/pi", "https://pypi.org/pypi"] install_path = None cleanup_files = [] gzdict_sz = 16 + 15 @@ -60,7 +61,7 @@ def _makedirs(name, mode=0o777): ret = True except OSError as e: if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR: - raise + raise e ret = False return ret @@ -167,11 +168,16 @@ def url_open(url): def get_pkg_metadata(name): - f = url_open("https://pypi.org/pypi/%s/json" % name) - try: - return json.load(f) - finally: - f.close() + for url in index_urls: + try: + f = url_open("%s/%s/json" % (url, name)) + except NotFoundError: + continue + try: + return json.load(f) + finally: + f.close() + raise NotFoundError("Package not found") def fatal(msg, exc=None): @@ -283,6 +289,7 @@ for installation, upip does not support arbitrary code in setup.py. def main(): global debug + global index_urls global install_path install_path = None @@ -316,6 +323,9 @@ def main(): if l[0] == "#": continue to_install.append(l.rstrip()) + elif opt == "-i": + index_urls = [sys.argv[i]] + i += 1 elif opt == "--debug": debug = True else: From 91739de71acc6ebcddd8b15119d32c2772588275 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 26 Apr 2021 18:52:15 -0500 Subject: [PATCH 66/69] Increased max pulse to 65535 us --- ports/raspberrypi/common-hal/pulseio/PulseIn.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 0495cb1b1b..e94e872cf5 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -39,11 +39,11 @@ pulseio_pulsein_obj_t *save_self; #define NO_PIN 0xff -#define MAX_PULSE 32678 +#define MAX_PULSE 65535 #define MIN_PULSE 10 volatile bool last_level; -volatile uint16_t level_count = 0; -volatile uint16_t result = 0; +volatile uint32_t level_count = 0; +volatile uint32_t result = 0; volatile uint16_t buf_index = 0; uint16_t pulsein_program[] = { @@ -140,14 +140,19 @@ void common_hal_pulseio_pulsein_interrupt() { result = level_count; last_level = level; level_count = 1; - // ignore pulses that are too long and too short - if (result < MAX_PULSE && result > MIN_PULSE) { - self->buffer[buf_index] = result; + // Pulses that are londger than MAX_PULSE will return MAX_PULSE + if (result > MAX_PULSE ) { + result = MAX_PULSE; + } + // ignore pulses that are too short + if (result <= MAX_PULSE && result > MIN_PULSE) { + self->buffer[buf_index] = (uint16_t) result; buf_index++; self->len++; } } } + // check for a pulse thats too long (MAX_PULSE us) or maxlen reached, and reset if ((level_count > MAX_PULSE) || (buf_index >= self->maxlen)) { pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, false); From d7faac11b81230df4dabc1c153ceafe772adf1ad Mon Sep 17 00:00:00 2001 From: Melissa LeBlanc-Williams Date: Tue, 27 Apr 2021 09:09:23 -0700 Subject: [PATCH 67/69] Release display on FunHouse for DeepSleep --- ports/esp32s2/boards/adafruit_funhouse/board.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp32s2/boards/adafruit_funhouse/board.c b/ports/esp32s2/boards/adafruit_funhouse/board.c index 810b61dbe0..3ca5c5d64f 100644 --- a/ports/esp32s2/boards/adafruit_funhouse/board.c +++ b/ports/esp32s2/boards/adafruit_funhouse/board.c @@ -120,4 +120,5 @@ void reset_board(void) { } void board_deinit(void) { + common_hal_displayio_release_displays(); } From 4e1d2fa056663d70efe8277bc9ca517ca39fa025 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Tue, 27 Apr 2021 12:52:24 -0400 Subject: [PATCH 68/69] Adding clearer on-board DotStar pin names. --- ports/atmel-samd/boards/gemma_m0/pins.c | 2 ++ ports/atmel-samd/boards/itsybitsy_m0_express/pins.c | 3 +++ ports/atmel-samd/boards/itsybitsy_m4_express/pins.c | 3 +++ ports/atmel-samd/boards/pirkey_m0/pins.c | 2 ++ ports/atmel-samd/boards/pyruler/pins.c | 3 +++ ports/atmel-samd/boards/trellis_m4_express/pins.c | 2 ++ ports/atmel-samd/boards/trinket_m0/pins.c | 3 +++ ports/atmel-samd/boards/trinket_m0_haxpress/pins.c | 3 +++ ports/nrf/boards/itsybitsy_nrf52840_express/pins.c | 2 ++ 9 files changed, 23 insertions(+) diff --git a/ports/atmel-samd/boards/gemma_m0/pins.c b/ports/atmel-samd/boards/gemma_m0/pins.c index 63e2ec54a0..bb6e9bda53 100644 --- a/ports/atmel-samd/boards/gemma_m0/pins.c +++ b/ports/atmel-samd/boards/gemma_m0/pins.c @@ -19,7 +19,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index 1b0e5d09eb..6e8cddfdb9 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -37,7 +37,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA01) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index 8cd2f44f89..b9167671ec 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -34,7 +34,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c index 41d02e3291..74e135827e 100644 --- a/ports/atmel-samd/boards/pirkey_m0/pins.c +++ b/ports/atmel-samd/boards/pirkey_m0/pins.c @@ -4,6 +4,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA28) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA01) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/pyruler/pins.c b/ports/atmel-samd/boards/pyruler/pins.c index 315dbe6303..37538cae5f 100644 --- a/ports/atmel-samd/boards/pyruler/pins.c +++ b/ports/atmel-samd/boards/pyruler/pins.c @@ -42,7 +42,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c index 4a0fa3ca21..6573b5fab3 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/pins.c +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -38,7 +38,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c index 372601e628..a5d7f32287 100644 --- a/ports/atmel-samd/boards/trinket_m0/pins.c +++ b/ports/atmel-samd/boards/trinket_m0/pins.c @@ -26,7 +26,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c index 372601e628..a5d7f32287 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -26,7 +26,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c b/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c index 364fbfd470..ad5fabc509 100644 --- a/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c +++ b/ports/nrf/boards/itsybitsy_nrf52840_express/pins.c @@ -29,7 +29,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_16) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_P0_08) }, { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_DOTSTAR_CLOCK), MP_ROM_PTR(&pin_P1_09) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_15) }, From cbb2ff4ce7aca17aad8c95adb26e2132026e1298 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 27 Apr 2021 20:02:10 +0200 Subject: [PATCH 69/69] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 44 ++++++++++++++++++++----------------- locale/cs.po | 32 ++++++++++----------------- locale/de_DE.po | 47 +++++++++++++++++++++++----------------- locale/el.po | 32 ++++++++++----------------- locale/en_GB.po | 47 +++++++++++++++++++++++----------------- locale/es.po | 47 +++++++++++++++++++++++----------------- locale/fil.po | 41 ++++++++++++++++++----------------- locale/fr.po | 47 +++++++++++++++++++++++----------------- locale/hi.po | 32 ++++++++++----------------- locale/it_IT.po | 41 ++++++++++++++++++----------------- locale/ja.po | 44 ++++++++++++++++++++----------------- locale/ko.po | 38 +++++++++++++++----------------- locale/nl.po | 47 +++++++++++++++++++++++----------------- locale/pl.po | 44 ++++++++++++++++++++----------------- locale/pt_BR.po | 47 +++++++++++++++++++++++----------------- locale/sv.po | 47 +++++++++++++++++++++++----------------- locale/zh_Latn_pinyin.po | 47 +++++++++++++++++++++++----------------- 17 files changed, 384 insertions(+), 340 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 97d3e15d18..9507fb0b22 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -753,14 +753,6 @@ msgid "" msgstr "" "Koneksi telah terputus dan tidak dapat lagi digunakan. Buat koneksi baru." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "File .mpy rusak" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Kode raw rusak" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2623,10 +2615,6 @@ msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3139,6 +3127,14 @@ msgstr "identifier didefinisi ulang sebagai global" msgid "identifier redefined as nonlocal" msgstr "identifier didefinisi ulang sebagai nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3258,6 +3254,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "argumen-argumen tidak valid" @@ -3267,10 +3267,6 @@ msgstr "argumen-argumen tidak valid" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "cert tidak valid" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3301,10 +3297,6 @@ msgstr "" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "key tidak valid" - #: py/compile.c msgid "invalid micropython decorator" msgstr "micropython decorator tidak valid" @@ -4314,6 +4306,18 @@ msgstr "zi harus berjenis float" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Corrupt .mpy file" +#~ msgstr "File .mpy rusak" + +#~ msgid "Corrupt raw code" +#~ msgstr "Kode raw rusak" + +#~ msgid "invalid cert" +#~ msgstr "cert tidak valid" + +#~ msgid "invalid key" +#~ msgstr "key tidak valid" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Fungsi Viper saat ini tidak mendukung lebih dari 4 argumen" diff --git a/locale/cs.po b/locale/cs.po index 79f18261a4..dab2eb901a 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -736,14 +736,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2577,10 +2569,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3093,6 +3081,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3212,6 +3208,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "" @@ -3221,10 +3221,6 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3255,10 +3251,6 @@ msgstr "" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "" - #: py/compile.c msgid "invalid micropython decorator" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 419e42b498..d8d3727bb6 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -751,14 +751,6 @@ msgstr "" "Die Verbindung wurde getrennt und kann nicht mehr verwendet werden. " "Erstellen Sie eine neue Verbindung." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Beschädigte .mpy Datei" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Beschädigter raw code" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Konnte Kamera nicht initialisieren" @@ -2636,10 +2628,6 @@ msgstr "kann nur bis zu 4 Parameter für die Thumb assembly haben" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "kann nur bis zu 4 Parameter für die Xtensa assembly haben" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "kann nur Bytecode speichern" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3166,6 +3154,14 @@ msgstr "Bezeichner als global neu definiert" msgid "identifier redefined as nonlocal" msgstr "Bezeichner als nonlocal definiert" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "unvollständiges Format" @@ -3285,6 +3281,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "Das Intervall muss im Bereich %s-%s sein" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "ungültige argumente" @@ -3294,10 +3294,6 @@ msgstr "ungültige argumente" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "ungültiges cert" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3328,10 +3324,6 @@ msgstr "ungültiger Formatbezeichner" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "ungültiger Schlüssel" - #: py/compile.c msgid "invalid micropython decorator" msgstr "ungültiger micropython decorator" @@ -4357,6 +4349,21 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Beschädigte .mpy Datei" + +#~ msgid "Corrupt raw code" +#~ msgstr "Beschädigter raw code" + +#~ msgid "can only save bytecode" +#~ msgstr "kann nur Bytecode speichern" + +#~ msgid "invalid cert" +#~ msgstr "ungültiges cert" + +#~ msgid "invalid key" +#~ msgstr "ungültiger Schlüssel" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente" diff --git a/locale/el.po b/locale/el.po index 9f3027016c..c2a73c577a 100644 --- a/locale/el.po +++ b/locale/el.po @@ -733,14 +733,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2574,10 +2566,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3090,6 +3078,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3209,6 +3205,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "" @@ -3218,10 +3218,6 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3252,10 +3248,6 @@ msgstr "" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "" - #: py/compile.c msgid "invalid micropython decorator" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index ef1677f66d..2f1b10a1f3 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -748,14 +748,6 @@ msgstr "" "Connection has been disconnected and can no longer be used. Create a new " "connection." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Corrupt .mpy file" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Corrupt raw code" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Could not initialise camera" @@ -2618,10 +2610,6 @@ msgstr "Can only have up to 4 parameters to thumb assembly" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "Can only have up to 4 parameters to xtensa assembly" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "Can only save bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "Can't add special method to already-subclassed class" @@ -3137,6 +3125,14 @@ msgstr "identifier redefined as global" msgid "identifier redefined as nonlocal" msgstr "identifier redefined as nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "incomplete format" @@ -3256,6 +3252,10 @@ msgstr "interp is defined for 1D arrays of equal length" msgid "interval must be in range %s-%s" msgstr "interval must be in range %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "invalid arguments" @@ -3265,10 +3265,6 @@ msgstr "invalid arguments" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "invalid cert" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3299,10 +3295,6 @@ msgstr "invalid format specifier" msgid "invalid hostname" msgstr "invalid hostname" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "invalid key" - #: py/compile.c #, fuzzy msgid "invalid micropython decorator" @@ -4314,6 +4306,21 @@ msgstr "zi must be of float type" msgid "zi must be of shape (n_section, 2)" msgstr "zi must be of shape (n_section, 2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Corrupt .mpy file" + +#~ msgid "Corrupt raw code" +#~ msgstr "Corrupt raw code" + +#~ msgid "can only save bytecode" +#~ msgstr "Can only save bytecode" + +#~ msgid "invalid cert" +#~ msgstr "invalid cert" + +#~ msgid "invalid key" +#~ msgstr "invalid key" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper functions don't currently support more than 4 arguments" diff --git a/locale/es.po b/locale/es.po index 18c6f56821..3dfe2adc7b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -757,14 +757,6 @@ msgstr "" "La conexión se ha desconectado y ya no se puede usar. Crea una nueva " "conexión." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Archivo .mpy corrupto" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Código crudo corrupto" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "No se puede inicializar Camera" @@ -2651,10 +2643,6 @@ msgstr "solo puede tener hasta 4 parámetros para ensamblar Thumb" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "solo puede tener hasta 4 parámetros para ensamblador Xtensa" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "solo puede almacenar bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "no se puede agregar un método a una clase ya subclasificada" @@ -3174,6 +3162,14 @@ msgstr "identificador redefinido como global" msgid "identifier redefined as nonlocal" msgstr "identificador redefinido como nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "formato incompleto" @@ -3293,6 +3289,10 @@ msgstr "interp está definido para arreglos de 1D del mismo tamaño" msgid "interval must be in range %s-%s" msgstr "el intervalo debe ser der rango %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "argumentos inválidos" @@ -3302,10 +3302,6 @@ msgstr "argumentos inválidos" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "los bits_per_pixel %d no son validos, deben ser 1, 4, 8, 16, 24 o 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "certificado inválido" - #: py/compile.c msgid "invalid decorator" msgstr "decorador invalido" @@ -3336,10 +3332,6 @@ msgstr "especificador de formato inválido" msgid "invalid hostname" msgstr "hostname inválido" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "llave inválida" - #: py/compile.c msgid "invalid micropython decorator" msgstr "decorador de micropython inválido" @@ -4358,6 +4350,21 @@ msgstr "zi debe ser de tipo flotante" msgid "zi must be of shape (n_section, 2)" msgstr "zi debe ser una forma (n_section,2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Archivo .mpy corrupto" + +#~ msgid "Corrupt raw code" +#~ msgstr "Código crudo corrupto" + +#~ msgid "can only save bytecode" +#~ msgstr "solo puede almacenar bytecode" + +#~ msgid "invalid cert" +#~ msgstr "certificado inválido" + +#~ msgid "invalid key" +#~ msgstr "llave inválida" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "funciones Viper no soportan por el momento, más de 4 argumentos" diff --git a/locale/fil.po b/locale/fil.po index 1e85ccbf4b..f5727a9da3 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -741,14 +741,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2603,10 +2595,6 @@ msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Thumb assembly" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "maaari lamang magkaroon ng hanggang 4 na parameter sa Xtensa assembly" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "maaring i-save lamang ang bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3131,6 +3119,14 @@ msgstr "identifier ginawang global" msgid "identifier redefined as nonlocal" msgstr "identifier ginawang nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "hindi kumpleto ang format" @@ -3250,6 +3246,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "mali ang mga argumento" @@ -3259,10 +3259,6 @@ msgstr "mali ang mga argumento" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "mali ang cert" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3293,10 +3289,6 @@ msgstr "mali ang format specifier" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "mali ang key" - #: py/compile.c msgid "invalid micropython decorator" msgstr "mali ang micropython decorator" @@ -4317,6 +4309,15 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "can only save bytecode" +#~ msgstr "maaring i-save lamang ang bytecode" + +#~ msgid "invalid cert" +#~ msgstr "mali ang cert" + +#~ msgid "invalid key" +#~ msgstr "mali ang key" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "" #~ "Ang mga function ng Viper ay kasalukuyang hindi sumusuporta sa higit sa 4 " diff --git a/locale/fr.po b/locale/fr.po index 0e8bbe3232..4b314c155d 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -764,14 +764,6 @@ msgstr "" "La connexion a été déconnectée et ne peut plus être utilisée. Créez une " "nouvelle connexion." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Fichier .mpy corrompu" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Code brut corrompu" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Impossible d'initialiser Camera" @@ -2666,10 +2658,6 @@ msgstr "il peut y avoir jusqu'à 4 paramètres pour l'assemblage Thumb" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "maximum 4 paramètres pour l'assembleur Xtensa" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "ne peut sauvegarder que du bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3197,6 +3185,14 @@ msgstr "identifiant redéfini comme global" msgid "identifier redefined as nonlocal" msgstr "identifiant redéfini comme nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "format incomplet" @@ -3317,6 +3313,10 @@ msgstr "interp est défini pour les matrices 1D de longueur égale" msgid "interval must be in range %s-%s" msgstr "interval doit être dans la portée %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "arguments invalides" @@ -3326,10 +3326,6 @@ msgstr "arguments invalides" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "bits_per_pixel %d est invalid, doit être 1, 4, 8, 16, 24 ou 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "certificat invalide" - #: py/compile.c msgid "invalid decorator" msgstr "décorateur invalide" @@ -3360,10 +3356,6 @@ msgstr "spécification de format invalide" msgid "invalid hostname" msgstr "hostname incorrect" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "clé invalide" - #: py/compile.c msgid "invalid micropython decorator" msgstr "décorateur micropython invalide" @@ -4384,6 +4376,21 @@ msgstr "zi doit être de type float" msgid "zi must be of shape (n_section, 2)" msgstr "zi doit être de forme (n_section, 2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Fichier .mpy corrompu" + +#~ msgid "Corrupt raw code" +#~ msgstr "Code brut corrompu" + +#~ msgid "can only save bytecode" +#~ msgstr "ne peut sauvegarder que du bytecode" + +#~ msgid "invalid cert" +#~ msgstr "certificat invalide" + +#~ msgid "invalid key" +#~ msgstr "clé invalide" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "" #~ "les fonctions de Viper ne supportent pas plus de 4 arguments actuellement" diff --git a/locale/hi.po b/locale/hi.po index 135f9781f1..4d23454770 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -733,14 +733,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2574,10 +2566,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3090,6 +3078,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3209,6 +3205,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "" @@ -3218,10 +3218,6 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3252,10 +3248,6 @@ msgstr "" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "" - #: py/compile.c msgid "invalid micropython decorator" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 53b78ea1ef..e39ad7594f 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -751,14 +751,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2621,10 +2613,6 @@ msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "sono disponibili fino a 4 parametri per il Xtensa assembly" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "È possibile salvare solo bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3144,6 +3132,14 @@ msgstr "identificatore ridefinito come globale" msgid "identifier redefined as nonlocal" msgstr "identificatore ridefinito come nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "formato incompleto" @@ -3263,6 +3259,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "argomenti non validi" @@ -3272,10 +3272,6 @@ msgstr "argomenti non validi" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "certificato non valido" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3306,10 +3302,6 @@ msgstr "specificatore di formato non valido" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "chiave non valida" - #: py/compile.c msgid "invalid micropython decorator" msgstr "decoratore non valido in micropython" @@ -4336,6 +4328,15 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "can only save bytecode" +#~ msgstr "È possibile salvare solo bytecode" + +#~ msgid "invalid cert" +#~ msgstr "certificato non valido" + +#~ msgid "invalid key" +#~ msgstr "chiave non valida" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" diff --git a/locale/ja.po b/locale/ja.po index 6c833f6f49..5df538a05d 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -744,14 +744,6 @@ msgid "" "connection." msgstr "接続は切断済みでもう使えません。新しい接続を作成してください" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "破損した .mpy ファイル" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "破損したraw code" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "カメラを初期化できません" @@ -2597,10 +2589,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "サブクラス化済みのクラスに特殊メソッドを追加できません" @@ -3117,6 +3105,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3237,6 +3233,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "intervalは%s-%sの範囲でなければなりません" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "不正な引数" @@ -3246,10 +3246,6 @@ msgstr "不正な引数" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "不正な証明書" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3280,10 +3276,6 @@ msgstr "" msgid "invalid hostname" msgstr "不正なホスト名" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "不正な鍵" - #: py/compile.c msgid "invalid micropython decorator" msgstr "不正なmicropythonデコレータ" @@ -4295,6 +4287,18 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Corrupt .mpy file" +#~ msgstr "破損した .mpy ファイル" + +#~ msgid "Corrupt raw code" +#~ msgstr "破損したraw code" + +#~ msgid "invalid cert" +#~ msgstr "不正な証明書" + +#~ msgid "invalid key" +#~ msgstr "不正な鍵" + #~ msgid "parameter annotation must be an identifier" #~ msgstr "引数アノテーションは識別子でなければなりません" diff --git a/locale/ko.po b/locale/ko.po index 1178d45dd6..06edd419c2 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -736,14 +736,6 @@ msgid "" "connection." msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2578,10 +2570,6 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3094,6 +3082,14 @@ msgstr "" msgid "identifier redefined as nonlocal" msgstr "" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "" @@ -3213,6 +3209,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "" @@ -3222,10 +3222,6 @@ msgstr "" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "cert가 유효하지 않습니다" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3256,10 +3252,6 @@ msgstr "형식 지정자(format specifier)가 유효하지 않습니다" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "키가 유효하지 않습니다" - #: py/compile.c msgid "invalid micropython decorator" msgstr "" @@ -4268,6 +4260,12 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "invalid cert" +#~ msgstr "cert가 유효하지 않습니다" + +#~ msgid "invalid key" +#~ msgstr "키가 유효하지 않습니다" + #~ msgid "bits must be 7, 8 or 9" #~ msgstr "비트(bits)는 7, 8 또는 9 여야합니다" diff --git a/locale/nl.po b/locale/nl.po index 3498a11820..57ff2337b8 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -744,14 +744,6 @@ msgstr "" "Verbinding is verbroken en kan niet langer gebruikt worden. Creëer een " "nieuwe verbinding." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Corrupt .mpy bestand" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Corrupt raw code" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Kon camera niet initialiseren" @@ -2625,10 +2617,6 @@ msgstr "kan slechts 4 parameters aan Thumb assembly geven" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "kan slechts 4 parameters aan Xtensa assembly geven" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "kan alleen byte-code opslaan" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "" @@ -3146,6 +3134,14 @@ msgstr "identifier is opnieuw gedefinieerd als global" msgid "identifier redefined as nonlocal" msgstr "identifier is opnieuw gedefinieerd als nonlocal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "incompleet formaat" @@ -3265,6 +3261,10 @@ msgstr "interp is gedefinieerd voor eendimensionale arrays van gelijke lengte" msgid "interval must be in range %s-%s" msgstr "interval moet binnen bereik %s-%s vallen" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "ongeldige argumenten" @@ -3274,10 +3274,6 @@ msgstr "ongeldige argumenten" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "ongeldig certificaat" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3308,10 +3304,6 @@ msgstr "ongeldige formaatspecificatie" msgid "invalid hostname" msgstr "onjuiste hostnaam" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "ongeldige sleutel" - #: py/compile.c msgid "invalid micropython decorator" msgstr "ongeldige micropython decorator" @@ -4326,6 +4318,21 @@ msgstr "zi moet van type float zijn" msgid "zi must be of shape (n_section, 2)" msgstr "zi moet vorm (n_section, 2) hebben" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Corrupt .mpy bestand" + +#~ msgid "Corrupt raw code" +#~ msgstr "Corrupt raw code" + +#~ msgid "can only save bytecode" +#~ msgstr "kan alleen byte-code opslaan" + +#~ msgid "invalid cert" +#~ msgstr "ongeldig certificaat" + +#~ msgid "invalid key" +#~ msgstr "ongeldige sleutel" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-functies ondersteunen momenteel niet meer dan 4 argumenten" diff --git a/locale/pl.po b/locale/pl.po index 32d839de23..984ed10275 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -744,14 +744,6 @@ msgstr "" "Połączenie zostało rozłączone i nie można go już używać. Utwórz nowe " "połączenie." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Uszkodzony plik .mpy" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "" @@ -2593,10 +2585,6 @@ msgstr "asembler Thumb może przyjąć do 4 parameterów" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "asembler Xtensa może przyjąć do 4 parameterów" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "można zapisać tylko bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "nie można dodać specjalnej metody do podklasy" @@ -3110,6 +3098,14 @@ msgstr "nazwa przedefiniowana jako globalna" msgid "identifier redefined as nonlocal" msgstr "nazwa przedefiniowana jako nielokalna" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "niepełny format" @@ -3229,6 +3225,10 @@ msgstr "" msgid "interval must be in range %s-%s" msgstr "interwał musi mieścić się w zakresie %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "złe arguemnty" @@ -3238,10 +3238,6 @@ msgstr "złe arguemnty" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "zły ceryfikat" - #: py/compile.c msgid "invalid decorator" msgstr "" @@ -3272,10 +3268,6 @@ msgstr "zła specyfikacja formatu" msgid "invalid hostname" msgstr "" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "zły klucz" - #: py/compile.c msgid "invalid micropython decorator" msgstr "zły dekorator micropythona" @@ -4286,6 +4278,18 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Uszkodzony plik .mpy" + +#~ msgid "can only save bytecode" +#~ msgstr "można zapisać tylko bytecode" + +#~ msgid "invalid cert" +#~ msgstr "zły ceryfikat" + +#~ msgid "invalid key" +#~ msgstr "zły klucz" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 3ca69c24e2..cfe04562a0 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -761,14 +761,6 @@ msgid "" msgstr "" "A conexão foi desconectada e não pode mais ser usada. Crie uma nova conexão." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Arquivo .mpy corrompido" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Código bruto corrompido" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Não foi possível inicializar a Câmera" @@ -2658,10 +2650,6 @@ msgstr "só pode haver até 4 parâmetros para a montagem Thumb" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "só pode haver até 4 parâmetros para a montagem Xtensa" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "apenas o bytecode pode ser salvo" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "não é possível adicionar o método especial à classe já subclassificada" @@ -3183,6 +3171,14 @@ msgstr "o identificador foi redefinido como global" msgid "identifier redefined as nonlocal" msgstr "o identificador foi redefinido como não-local" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "formato incompleto" @@ -3303,6 +3299,10 @@ msgstr "o interp é definido para matrizes 1D de igual comprimento" msgid "interval must be in range %s-%s" msgstr "o intervalo deve estar entre %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "argumentos inválidos" @@ -3312,10 +3312,6 @@ msgstr "argumentos inválidos" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "bits_per_pixel %d é inválido, deve ser, 1, 4, 8, 16, 24, ou 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "certificado inválido" - #: py/compile.c msgid "invalid decorator" msgstr "decorador inválido" @@ -3346,10 +3342,6 @@ msgstr "o especificador do formato é inválido" msgid "invalid hostname" msgstr "o nome do host é inválido" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "chave inválida" - #: py/compile.c msgid "invalid micropython decorator" msgstr "o decorador micropython é inválido" @@ -4370,6 +4362,21 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Arquivo .mpy corrompido" + +#~ msgid "Corrupt raw code" +#~ msgstr "Código bruto corrompido" + +#~ msgid "can only save bytecode" +#~ msgstr "apenas o bytecode pode ser salvo" + +#~ msgid "invalid cert" +#~ msgstr "certificado inválido" + +#~ msgid "invalid key" +#~ msgstr "chave inválida" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Atualmente, as funções do Viper não suportam mais de 4 argumentos" diff --git a/locale/sv.po b/locale/sv.po index 8defcb5546..afa32f410a 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -750,14 +750,6 @@ msgstr "" "Anslutningen har kopplats bort och kan inte längre användas. Skapa en ny " "anslutning." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Skadad .mpy-fil" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Korrupt rå kod" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Kunde inte initiera Camera" @@ -2628,10 +2620,6 @@ msgstr "kan bara ha upp till 4 parametrar för Thumbs assembly" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "kan bara ha upp till 4 parametrar att Xtensa assembly" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "kan bara spara bytecode" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "kan inte lägga till särskild metod för redan subklassad klass" @@ -3149,6 +3137,14 @@ msgstr "identifieraren omdefinierad till global" msgid "identifier redefined as nonlocal" msgstr "identifieraren omdefinierad som icke-lokal" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "ofullständigt format" @@ -3268,6 +3264,10 @@ msgstr "interp är definierad för 1D-matriser med samma längd" msgid "interval must be in range %s-%s" msgstr "interval måste vara i intervallet %s-%s" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "ogiltiga argument" @@ -3277,10 +3277,6 @@ msgstr "ogiltiga argument" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "ogiltig bits_per_pixel %d, måste vara 1, 4, 8, 16, 24 eller 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "ogiltigt certifikat" - #: py/compile.c msgid "invalid decorator" msgstr "ogiltig dekorator" @@ -3311,10 +3307,6 @@ msgstr "ogiltig formatspecificerare" msgid "invalid hostname" msgstr "Ogiltigt värdnamn" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "ogiltig nyckel" - #: py/compile.c msgid "invalid micropython decorator" msgstr "ogiltig mikropython-dekorator" @@ -4329,6 +4321,21 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Skadad .mpy-fil" + +#~ msgid "Corrupt raw code" +#~ msgstr "Korrupt rå kod" + +#~ msgid "can only save bytecode" +#~ msgstr "kan bara spara bytecode" + +#~ msgid "invalid cert" +#~ msgstr "ogiltigt certifikat" + +#~ msgid "invalid key" +#~ msgstr "ogiltig nyckel" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper-funktioner stöder för närvarande inte mer än fyra argument" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8a21a68f42..49bf62a3a6 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -749,14 +749,6 @@ msgid "" "connection." msgstr "Liánjiē yǐ duàn kāi, wúfǎ zài shǐyòng. Chuàngjiàn yīgè xīn de liánjiē." -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "Fǔbài de .mpy wénjiàn" - -#: py/emitglue.c -msgid "Corrupt raw code" -msgstr "Sǔnhuài de yuánshǐ dàimǎ" - #: ports/cxd56/common-hal/camera/Camera.c msgid "Could not initialize Camera" msgstr "Wúfǎ chūshǐhuà xiàngjī" @@ -2626,10 +2618,6 @@ msgstr "zhǐyǒu Thumb zǔjiàn zuìduō 4 cānshù" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "zhǐyǒu Xtensa zǔjiàn zuìduō 4 cānshù" -#: py/persistentcode.c -msgid "can only save bytecode" -msgstr "zhǐ néng bǎocún zì jié mǎ jìlù" - #: py/objtype.c msgid "can't add special method to already-subclassed class" msgstr "wúfǎ tiānjiā tèshū fāngfǎ dào zi fēnlèi lèi" @@ -3148,6 +3136,14 @@ msgstr "biāozhì fú chóngxīn dìngyì wèi quánjú" msgid "identifier redefined as nonlocal" msgstr "biāozhì fú chóngxīn dìngyì wéi fēi běndì" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible native .mpy architecture" +msgstr "" + #: py/objstr.c msgid "incomplete format" msgstr "géshì bù wánzhěng" @@ -3267,6 +3263,10 @@ msgstr "interp shì wèi děng zhǎng de 1D shùzǔ dìngyì de" msgid "interval must be in range %s-%s" msgstr "Jiàngé bìxū zài %s-%s fànwéi nèi" +#: py/compile.c +msgid "invalid architecture" +msgstr "" + #: lib/netutils/netutils.c msgid "invalid arguments" msgstr "wúxiào de cānshù" @@ -3276,10 +3276,6 @@ msgstr "wúxiào de cānshù" msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32" msgstr "wú xiào bits_per_pixel %d, bì xū shì, 1, 4, 8, 16, 24, huò 32" -#: extmod/modussl_axtls.c -msgid "invalid cert" -msgstr "zhèngshū wúxiào" - #: py/compile.c msgid "invalid decorator" msgstr "wú xiào zhuāng shì" @@ -3310,10 +3306,6 @@ msgstr "wúxiào de géshì biāozhù" msgid "invalid hostname" msgstr "wú xiào zhǔ jī míng" -#: extmod/modussl_axtls.c -msgid "invalid key" -msgstr "wúxiào de mì yào" - #: py/compile.c msgid "invalid micropython decorator" msgstr "wúxiào de MicroPython zhuāngshì qì" @@ -4325,6 +4317,21 @@ msgstr "zi bìxū wèi fú diǎn xíng" msgid "zi must be of shape (n_section, 2)" msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" +#~ msgid "Corrupt .mpy file" +#~ msgstr "Fǔbài de .mpy wénjiàn" + +#~ msgid "Corrupt raw code" +#~ msgstr "Sǔnhuài de yuánshǐ dàimǎ" + +#~ msgid "can only save bytecode" +#~ msgstr "zhǐ néng bǎocún zì jié mǎ jìlù" + +#~ msgid "invalid cert" +#~ msgstr "zhèngshū wúxiào" + +#~ msgid "invalid key" +#~ msgstr "wúxiào de mì yào" + #~ msgid "Viper functions don't currently support more than 4 arguments" #~ msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù"