From 8889ac12e1306cf0a266deaf9f4371c8e12b3e2b Mon Sep 17 00:00:00 2001 From: Christian Walther Date: Thu, 29 Oct 2020 16:39:06 +0100 Subject: [PATCH 001/349] Add supervisor.set_next_code() function (prototype). Part of #1084. --- locale/circuitpython.pot | 6 +- main.c | 82 +++++++++++++++++++++---- shared-bindings/supervisor/__init__.c | 86 ++++++++++++++++++++++++++- supervisor/shared/autoreload.c | 2 + supervisor/shared/autoreload.h | 18 ++++++ supervisor/shared/memory.c | 2 + 6 files changed, 182 insertions(+), 14 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 3ffc31cc6c..bcce38b1cc 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -47,6 +47,10 @@ msgstr "" msgid " is of type %q\n" msgstr "" +#: main.c +msgid " not found.\n" +msgstr "" + #: main.c msgid " output:\n" msgstr "" @@ -2213,7 +2217,7 @@ msgstr "" msgid "argsort is not implemented for flattened arrays" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/__init__.c msgid "argument has wrong type" msgstr "" diff --git a/main.c b/main.c index d9cdcca1da..2a0c92e551 100755 --- a/main.c +++ b/main.c @@ -272,7 +272,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { result.exception_type = NULL; result.exception_line = 0; + bool skip_repl; bool found_main = false; + uint8_t next_code_options = 0; + // Collects stickiness bits that apply in the current situation. + uint8_t next_code_stickiness_situation = SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; if (safe_mode == NO_SAFE_MODE) { new_status_color(MAIN_RUNNING); @@ -290,22 +294,62 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { supervisor_allocation* heap = allocate_remaining_memory(); start_mp(heap); - found_main = maybe_run_list(supported_filenames, &result); - #if CIRCUITPY_FULL_BUILD - if (!found_main){ - found_main = maybe_run_list(double_extension_filenames, &result); - if (found_main) { - serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); + if (next_code_allocation) { + ((next_code_info_t*)next_code_allocation->ptr)->options &= ~SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; + next_code_options = ((next_code_info_t*)next_code_allocation->ptr)->options; + if (((next_code_info_t*)next_code_allocation->ptr)->filename[0] != '\0') { + const char* next_list[] = {((next_code_info_t*)next_code_allocation->ptr)->filename, ""}; + found_main = maybe_run_list(next_list, &result); + if (!found_main) { + serial_write(((next_code_info_t*)next_code_allocation->ptr)->filename); + serial_write_compressed(translate(" not found.\n")); + } } } - #endif + if (!found_main) { + found_main = maybe_run_list(supported_filenames, &result); + #if CIRCUITPY_FULL_BUILD + if (!found_main){ + found_main = maybe_run_list(double_extension_filenames, &result); + if (found_main) { + serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); + } + } + #endif + } // TODO: on deep sleep, make sure display is refreshed before sleeping (for e-ink). cleanup_after_vm(heap); + // If a new next code file was set, that is a reason to keep it (obviously). Stuff this into + // the options because it can be treated like any other reason-for-stickiness bit. The + // source is different though: it comes from the options that will apply to the next run, + // while the rest of next_code_options is what applied to this run. + if (next_code_allocation != NULL && (((next_code_info_t*)next_code_allocation->ptr)->options & SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET)) { + next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; + } + + if (reload_requested) { + next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; + } + else if (result.return_code == 0) { //TODO mask out PYEXEC_DEEP_SLEEP? + next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS; + if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) { + skip_repl = true; + goto done; + } + } + else { + next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_ERROR; + if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR) { + skip_repl = true; + goto done; + } + } if (result.return_code & PYEXEC_FORCED_EXIT) { - return reload_requested; + skip_repl = reload_requested; + goto done; } if (reload_requested && result.return_code == PYEXEC_EXCEPTION) { @@ -333,9 +377,16 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { board_init(); } #endif + next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; + // Should the STICKY_ON_SUCCESS and STICKY_ON_ERROR bits be cleared in + // next_code_stickiness_situation? I can see arguments either way, but I'm deciding + // "no" for now, mainly because it's a bit less code. At this point, we have both a + // success or error and a reload, so let's have both of the respective options take + // effect (in OR combination). supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD); reload_requested = false; - return true; + skip_repl = true; + goto done; } if (serial_connected() && serial_bytes_available()) { @@ -345,11 +396,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { } #endif // Skip REPL if reload was requested. - bool ctrl_d = serial_read() == CHAR_CTRL_D; - if (ctrl_d) { + skip_repl = serial_read() == CHAR_CTRL_D; + if (skip_repl) { supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); } - return ctrl_d; + goto done; } // Check for a deep sleep alarm and restart the VM. This can happen if @@ -428,6 +479,13 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { port_idle_until_interrupt(); } } + +done: + if ((next_code_options & next_code_stickiness_situation) == 0) { + free_memory(next_code_allocation); + next_code_allocation = NULL; + } + return skip_repl; } FIL* boot_output_file; diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index ad86030478..d904d11c6e 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -23,9 +23,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include + #include "py/obj.h" #include "py/runtime.h" #include "py/reload.h" +#include "py/objstr.h" #include "lib/utils/interrupt_char.h" #include "supervisor/shared/autoreload.h" @@ -112,6 +115,87 @@ STATIC mp_obj_t supervisor_set_next_stack_limit(mp_obj_t size_obj) { } MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_next_stack_limit_obj, supervisor_set_next_stack_limit); +//| def set_next_code_file(filename: Optional[str], *, reload_on_success : bool = False, reload_on_error: bool = False, sticky_on_success: bool = False, sticky_on_error: bool = False, sticky_on_reload: bool = False) -> None: +//| """Set what file to run on the next vm run. +//| +//| When not ``None``, the given ``filename`` is inserted at the front of the usual ['code.py', +//| 'main.py'] search sequence. +//| +//| The optional keyword arguments specify what happens after the specified file has run: +//| +//| ``sticky_on_…`` determine whether the newly set filename and options stay in effect: If +//| True, further runs will continue to run that file (unless it says otherwise by calling +//| ``set_next_code_filename()`` itself). If False, the settings will only affect one run and +//| revert to the standard code.py/main.py afterwards. +//| +//| ``reload_on_…`` determine how to continue: If False, wait in the usual "Code done running. +//| Waiting for reload. / Press any key to enter the REPL. Use CTRL-D to reload." state. If +//| True, reload immediately as if CTRL-D was pressed. +//| +//| ``…_on_success`` take effect when the program runs to completion or calls ``sys.exit()``. +//| +//| ``…_on_error`` take effect when the program exits with an exception, including the +//| KeyboardInterrupt caused by CTRL-C. +//| +//| ``…_on_reload`` take effect when the program is interrupted by files being written to the USB +//| drive (auto-reload) or when it calls ``supervisor.reload()``. +//| +//| These settings are stored in RAM, not in persistent memory, and will therefore only affect +//| soft reloads. Powering off or resetting the device will always revert to standard settings. +//| +//| When called multiple times in the same run, only the last call takes effect, replacing any +//| settings made by previous ones. This is the main use of passing ``None`` as a filename: to +//| reset to the standard search sequence.""" +//| ... +//| +STATIC mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + { MP_QSTR_filename, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_reload_on_success, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_reload_on_error, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_sticky_on_success, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_sticky_on_error, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_sticky_on_reload, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + struct { + mp_arg_val_t filename; + mp_arg_val_t reload_on_success; + mp_arg_val_t reload_on_error; + mp_arg_val_t sticky_on_success; + mp_arg_val_t sticky_on_error; + mp_arg_val_t sticky_on_reload; + } args; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); + if (!MP_OBJ_IS_STR_OR_BYTES(args.filename.u_obj) && args.filename.u_obj != mp_const_none) { + mp_raise_TypeError(translate("argument has wrong type")); + } + if (args.filename.u_obj == mp_const_none) args.filename.u_obj = mp_const_empty_bytes; + uint8_t options = 0; + if (args.reload_on_success.u_bool) options |= SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS; + if (args.reload_on_error.u_bool) options |= SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR; + if (args.sticky_on_success.u_bool) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS; + if (args.sticky_on_error.u_bool) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_ERROR; + if (args.sticky_on_reload.u_bool) options |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD; + size_t len; + const char* filename = mp_obj_str_get_data(args.filename.u_obj, &len); + free_memory(next_code_allocation); + if (options != 0 || len != 0) { + next_code_allocation = allocate_memory(align32_size(sizeof(next_code_info_t) + len + 1), false, true); + if (next_code_allocation == NULL) { + m_malloc_fail(sizeof(next_code_info_t) + len + 1); + } + next_code_info_t* next_code = (next_code_info_t*)next_code_allocation->ptr; + next_code->options = options | SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; + memcpy(&next_code->filename, filename, len); + next_code->filename[len] = '\0'; + } + else { + next_code_allocation = NULL; + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_next_code_file_obj, 0, supervisor_set_next_code_file); + STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, { MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, @@ -121,7 +205,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_reload), MP_ROM_PTR(&supervisor_reload_obj) }, { MP_ROM_QSTR(MP_QSTR_RunReason), MP_ROM_PTR(&supervisor_run_reason_type) }, { MP_ROM_QSTR(MP_QSTR_set_next_stack_limit), MP_ROM_PTR(&supervisor_set_next_stack_limit_obj) }, - + { MP_ROM_QSTR(MP_QSTR_set_next_code_file), MP_ROM_PTR(&supervisor_set_next_code_file_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table); diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c index 1976f66470..a267879a60 100644 --- a/supervisor/shared/autoreload.c +++ b/supervisor/shared/autoreload.c @@ -30,6 +30,8 @@ #include "py/reload.h" #include "supervisor/shared/tick.h" +supervisor_allocation* next_code_allocation; + static volatile uint32_t autoreload_delay_ms = 0; static bool autoreload_enabled = false; static bool autoreload_suspended = false; diff --git a/supervisor/shared/autoreload.h b/supervisor/shared/autoreload.h index fbd482c19a..069be997dc 100644 --- a/supervisor/shared/autoreload.h +++ b/supervisor/shared/autoreload.h @@ -29,6 +29,24 @@ #include +#include "supervisor/memory.h" + +enum { + SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS = 0x1, + SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_ERROR = 0x2, + SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS = 0x4, + SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_ERROR = 0x8, + SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD = 0x10, + SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET = 0x20, +}; + +typedef struct { + uint8_t options; + char filename[]; +} next_code_info_t; + +extern supervisor_allocation* next_code_allocation; + extern volatile bool reload_requested; void autoreload_tick(void); diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 480c322b01..74747d6cf6 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -36,6 +36,8 @@ enum { CIRCUITPY_SUPERVISOR_IMMOVABLE_ALLOC_COUNT = // stack + heap 2 + // next_code_allocation + + 1 #ifdef EXTERNAL_FLASH_DEVICES + 1 #endif From b74dc546fc2d7d04853db3acc4dc6ed92cc77f67 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 20 Apr 2021 21:39:53 +1000 Subject: [PATCH 002/349] tools/metrics.py: Add rp2 port to table of ports that can be built. Signed-off-by: Damien George --- tools/metrics.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/metrics.py b/tools/metrics.py index 98291e25a9..c857d0733e 100755 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -67,6 +67,7 @@ port_data = { "8": PortData("esp8266", "esp8266", "build-GENERIC/firmware.elf"), "3": PortData("esp32", "esp32", "build-GENERIC/micropython.elf"), "r": PortData("nrf", "nrf", "build-pca10040/firmware.elf"), + "p": PortData("rp2", "rp2", "build-PICO/firmware.elf"), "d": PortData("samd", "samd", "build-ADAFRUIT_ITSYBITSY_M4_EXPRESS/firmware.elf"), } From 6e0f9b9262a2948391704d53eafec8d2bd2e5ad2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Apr 2021 16:12:32 +1000 Subject: [PATCH 003/349] stm32/boards/pllvalues.py: Support wider range of PLL values for F413. Signed-off-by: Damien George --- ports/stm32/boards/pllvalues.py | 38 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/ports/stm32/boards/pllvalues.py b/ports/stm32/boards/pllvalues.py index 619146cd47..e0fff40dd3 100644 --- a/ports/stm32/boards/pllvalues.py +++ b/ports/stm32/boards/pllvalues.py @@ -31,15 +31,26 @@ mcu_default = MCU( range_vco_out=range(192, 432 + 1), ) -mcu_h7 = MCU( - range_sysclk=range(2, 400 + 1, 2), # above 400MHz currently unsupported - range_m=range(1, 63 + 1), - range_n=range(4, 512 + 1), - range_p=range(2, 128 + 1, 2), - range_q=range(1, 128 + 1), - range_vco_in=range(1, 16 + 1), - range_vco_out=range(150, 960 + 1), # 150-420=medium, 192-960=wide -) +mcu_table = { + "stm32f413": MCU( + range_sysclk=range(2, 100 + 1, 2), + range_m=range(2, 63 + 1), + range_n=range(50, 432 + 1), + range_p=range(2, 8 + 1, 2), + range_q=range(2, 15 + 1), + range_vco_in=range(1, 2 + 1), + range_vco_out=range(100, 432 + 1), + ), + "stm32h7": MCU( + range_sysclk=range(2, 400 + 1, 2), # above 400MHz currently unsupported + range_m=range(1, 63 + 1), + range_n=range(4, 512 + 1), + range_p=range(2, 128 + 1, 2), + range_q=range(1, 128 + 1), + range_vco_in=range(1, 16 + 1), + range_vco_out=range(150, 960 + 1), # 150-420=medium, 192-960=wide + ), +} def close_int(x): @@ -271,10 +282,11 @@ def main(): hse = int(argv[0]) # Select MCU parameters - if mcu_series.startswith("stm32h7"): - mcu = mcu_h7 - else: - mcu = mcu_default + mcu = mcu_default + for m in mcu_table: + if mcu_series.startswith(m): + mcu = mcu_table[m] + break # Relax constraint on PLLQ being 48MHz on MCUs which have separate PLLs for 48MHz relax_pll48 = mcu_series.startswith(("stm32f413", "stm32f7", "stm32h7")) From 00d6a79b3d5dc80d840dc1d51166e7d95856b3d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 21 Apr 2021 14:06:14 +1000 Subject: [PATCH 004/349] stm32/machine_timer: Improve usability of Timer constructor and init. Improvements are: - Default period is 1000ms with callback disabled. - if period is not specified then it's not updated (previously, if period was not specified then it was set to -1 and running the timer callback as fast as possible, making the REPL unresponsive). - Use uint64_t to compute delta_ms, and raise a ValueError if the period is too large. - If callback is not specified then it's not updated. - Specifying None for the callback will disable the timer. Signed-off-by: Damien George --- ports/stm32/machine_timer.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index e9b16ab72f..c37ac87672 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -42,7 +42,7 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar enum { ARG_mode, ARG_callback, ARG_period, ARG_tick_hz, ARG_freq, }; static const mp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SOFT_TIMER_MODE_PERIODIC} }, - { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} }, { MP_QSTR_tick_hz, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, @@ -53,24 +53,35 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); self->mode = args[ARG_mode].u_int; + + uint64_t delta_ms = self->delta_ms; if (args[ARG_freq].u_obj != mp_const_none) { // Frequency specified in Hz #if MICROPY_PY_BUILTINS_FLOAT - self->delta_ms = (uint32_t)(MICROPY_FLOAT_CONST(1000.0) / mp_obj_get_float(args[ARG_freq].u_obj)); + delta_ms = (uint32_t)(MICROPY_FLOAT_CONST(1000.0) / mp_obj_get_float(args[ARG_freq].u_obj)); #else - self->delta_ms = 1000 / mp_obj_get_int(args[ARG_freq].u_obj); + delta_ms = 1000 / mp_obj_get_int(args[ARG_freq].u_obj); #endif - } else { + } else if (args[ARG_period].u_int != 0xffffffff) { // Period specified - self->delta_ms = args[ARG_period].u_int * 1000 / args[ARG_tick_hz].u_int; + delta_ms = (uint64_t)args[ARG_period].u_int * 1000 / args[ARG_tick_hz].u_int; } - if (self->delta_ms < 1) { - self->delta_ms = 1; + + if (delta_ms < 1) { + delta_ms = 1; + } else if (delta_ms >= 0x40000000) { + mp_raise_ValueError(MP_ERROR_TEXT("period too large")); } + self->delta_ms = (uint32_t)delta_ms; self->expiry_ms = mp_hal_ticks_ms() + self->delta_ms; - self->callback = args[ARG_callback].u_obj; - soft_timer_insert(self); + if (args[ARG_callback].u_obj != MP_OBJ_NULL) { + self->callback = args[ARG_callback].u_obj; + } + + if (self->callback != mp_const_none) { + soft_timer_insert(self); + } return mp_const_none; } @@ -78,6 +89,8 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t); self->pairheap.base.type = &machine_timer_type; + self->delta_ms = 1000; + self->callback = mp_const_none; // Get timer id (only soft timer (-1) supported at the moment) mp_int_t id = -1; From 5669a6095444e079af5e38b2b04ca5ff2e7c11f9 Mon Sep 17 00:00:00 2001 From: David Michieli Date: Thu, 22 Apr 2021 13:43:50 +1000 Subject: [PATCH 005/349] stm32/mboot: Allow unpacking dfu without secret key. - unpack-dfu command no longer requies a secret key to be present - pack-dfu command raises an exception if no secret key is found --- ports/stm32/mboot/mboot_pack_dfu.py | 13 ++++++++++--- tools/ci.sh | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ports/stm32/mboot/mboot_pack_dfu.py b/ports/stm32/mboot/mboot_pack_dfu.py index 540057e06e..683cdd0a71 100644 --- a/ports/stm32/mboot/mboot_pack_dfu.py +++ b/ports/stm32/mboot/mboot_pack_dfu.py @@ -86,9 +86,14 @@ class Keys: def load(self): with open(self.filename) as f: - self.sign_sk = self._load_data("mboot_pack_sign_secret_key", f.readline()) - self.sign_pk = self._load_data("mboot_pack_sign_public_key", f.readline()) - self.secretbox = self._load_data("mboot_pack_secretbox_key", f.readline()) + for line in f: + for key, attr in ( + ("mboot_pack_sign_secret_key", "sign_sk"), + ("mboot_pack_sign_public_key", "sign_pk"), + ("mboot_pack_secretbox_key", "secretbox"), + ): + if key in line: + setattr(self, attr, self._load_data(key, line)) def dfu_read(filename): @@ -135,6 +140,8 @@ def encrypt(keys, data): def sign(keys, data): + if not hasattr(keys, "sign_sk"): + raise Exception("packing a dfu requires a secret key") return pyhy.hydro_sign_create(data, MBOOT_PACK_HYDRO_CONTEXT, keys.sign_sk) diff --git a/tools/ci.sh b/tools/ci.sh index c018b55002..33cf364ddd 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -243,6 +243,10 @@ function ci_stm32_nucleo_build { BUILD_WB55=ports/stm32/build-NUCLEO_WB55 python3 ports/stm32/mboot/mboot_pack_dfu.py -k $BOARD_WB55/mboot_keys.h unpack-dfu $BUILD_WB55/firmware.pack.dfu $BUILD_WB55/firmware.unpack.dfu diff $BUILD_WB55/firmware.unpack.dfu $BUILD_WB55/firmware.dfu + # Test unpack-dfu command works without a secret key + tail -n +2 $BOARD_WB55/mboot_keys.h > $BOARD_WB55/mboot_keys_no_sk.h + python3 ports/stm32/mboot/mboot_pack_dfu.py -k $BOARD_WB55/mboot_keys_no_sk.h unpack-dfu $BUILD_WB55/firmware.pack.dfu $BUILD_WB55/firmware.unpack_no_sk.dfu + diff $BUILD_WB55/firmware.unpack.dfu $BUILD_WB55/firmware.unpack_no_sk.dfu } ######################################################################################## From 3c4bfd1dec28ffbefc6379dedeaa24feaa2ef373 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 20 Apr 2021 17:11:13 +1000 Subject: [PATCH 006/349] py/objexcept: Support errno attribute on OSError exceptions. This commit adds the errno attribute to exceptions, so code can retrieve errno codes from an OSError using exc.errno. The implementation here simply lets `errno` (and the existing `value`) attributes work on any exception instance (they both alias args[0]). This is for efficiency and to keep code size down. The pros and cons of this are: Pros: - more compatible with CPython, less difference to document and learn - OSError().errno will correctly return None, whereas the current way of doing it via OSError().args[0] will raise an IndexError - it reduces code size on most bare-metal ports (because they already have the errno qstr) - for Python code that uses exc.errno the generated bytecode is 2 bytes smaller and more efficient to execute (compared with exc.args[0]); so bytecode loaded to RAM saves 2 bytes RAM for each use of this attribute, and bytecode that is frozen saves 2 bytes flash/ROM for each use - it's easier/shorter to type, and saves 2 bytes of space in .py files that use it (for each use) Cons: - increases code size by 4-8 bytes on minimal ports that don't already have the `errno` qstr - all exceptions now have .errno and .value attributes (a cpydiff test is added to address this) See also #2407. Signed-off-by: Damien George --- docs/library/builtins.rst | 4 ---- docs/library/uerrno.rst | 4 ++-- py/objexcept.c | 4 +++- tests/basics/exception1.py | 5 +++++ tests/basics/subclass_native3.py | 20 ++++++++++++++++++++ tests/cpydiff/types_exception_attrs.py | 9 +++++++++ 6 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 tests/cpydiff/types_exception_attrs.py diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index 365248dc76..3029cd9e3b 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -176,10 +176,6 @@ Exceptions .. exception:: OSError - |see_cpython| `python:OSError`. MicroPython doesn't implement ``errno`` - attribute, instead use the standard way to access exception arguments: - ``exc.args[0]``. - .. exception:: RuntimeError .. exception:: StopIteration diff --git a/docs/library/uerrno.rst b/docs/library/uerrno.rst index def01362f1..1d60c80e11 100644 --- a/docs/library/uerrno.rst +++ b/docs/library/uerrno.rst @@ -16,13 +16,13 @@ Constants Error codes, based on ANSI C/POSIX standard. All error codes start with "E". As mentioned above, inventory of the codes depends on - :term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]`` + :term:`MicroPython port`. Errors are usually accessible as ``exc.errno`` where ``exc`` is an instance of `OSError`. Usage example:: try: uos.mkdir("my_dir") except OSError as exc: - if exc.args[0] == uerrno.EEXIST: + if exc.errno == uerrno.EEXIST: print("Directory already exists") .. data:: errorcode diff --git a/py/objexcept.c b/py/objexcept.c index 885032c3e3..f6bffec383 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -261,7 +261,9 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR_args) { decompress_error_text_maybe(self); dest[0] = MP_OBJ_FROM_PTR(self->args); - } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { + } else if (attr == MP_QSTR_value || attr == MP_QSTR_errno) { + // These are aliases for args[0]: .value for StopIteration and .errno for OSError. + // For efficiency let these attributes apply to all exception instances. dest[0] = mp_obj_exception_get_value(self_in); } } diff --git a/tests/basics/exception1.py b/tests/basics/exception1.py index d83764cb93..a0ca8a74e2 100644 --- a/tests/basics/exception1.py +++ b/tests/basics/exception1.py @@ -1,3 +1,5 @@ +# test basic properties of exceptions + print(repr(IndexError())) print(str(IndexError())) @@ -12,3 +14,6 @@ s = StopIteration() print(s.value) s = StopIteration(1, 2, 3) print(s.value) + +print(OSError().errno) +print(OSError(1, "msg").errno) diff --git a/tests/basics/subclass_native3.py b/tests/basics/subclass_native3.py index 6745b77bb2..ac5aabfed7 100644 --- a/tests/basics/subclass_native3.py +++ b/tests/basics/subclass_native3.py @@ -1,6 +1,10 @@ +# test subclassing a native exception + + class MyExc(Exception): pass + e = MyExc(100, "Some error") print(e) print(repr(e)) @@ -20,3 +24,19 @@ try: raise MyExc("Some error2") except: print("Caught user exception") + + +class MyStopIteration(StopIteration): + pass + + +print(MyStopIteration().value) +print(MyStopIteration(1).value) + + +class MyOSError(OSError): + pass + + +print(MyOSError().errno) +print(MyOSError(1, "msg").errno) diff --git a/tests/cpydiff/types_exception_attrs.py b/tests/cpydiff/types_exception_attrs.py new file mode 100644 index 0000000000..ad72b62a61 --- /dev/null +++ b/tests/cpydiff/types_exception_attrs.py @@ -0,0 +1,9 @@ +""" +categories: Types,Exception +description: All exceptions have readable ``value`` and ``errno`` attributes, not just ``StopIteration`` and ``OSError``. +cause: MicroPython is optimised to reduce code size. +workaround: Only use ``value`` on ``StopIteration`` exceptions, and ``errno`` on ``OSError`` exceptions. Do not use or rely on these attributes on other exceptions. +""" +e = Exception(1) +print(e.value) +print(e.errno) From ac1d01d43ee02d294f5fe762ae608fbb3f72babb Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 20 Apr 2021 17:11:59 +1000 Subject: [PATCH 007/349] tools/upip.py: Use .errno instead of .args[0] for OSError exceptions. Signed-off-by: Damien George --- tools/upip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/upip.py b/tools/upip.py index aa8aecedfc..728b843c94 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -60,7 +60,7 @@ def _makedirs(name, mode=0o777): os.mkdir(s) ret = True except OSError as e: - if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR: + if e.errno != errno.EEXIST and e.errno != errno.EISDIR: raise e ret = False return ret From 342d55529d6f3312fc158d7af005f56d5e30adef Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 20 Apr 2021 17:12:08 +1000 Subject: [PATCH 008/349] extmod/uasyncio: Use .errno instead of .args[0] for OSError exceptions. Signed-off-by: Damien George --- extmod/uasyncio/stream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extmod/uasyncio/stream.py b/extmod/uasyncio/stream.py index b6d787e4f0..395ff1f6af 100644 --- a/extmod/uasyncio/stream.py +++ b/extmod/uasyncio/stream.py @@ -82,7 +82,7 @@ async def open_connection(host, port): try: s.connect(ai[-1]) except OSError as er: - if er.args[0] != EINPROGRESS: + if er.errno != EINPROGRESS: raise er yield core._io_queue.queue_write(s) return ss, ss From 3123f6918ba18b0a3f7a89500b450f4cb15e1aee Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Apr 2021 19:32:21 +1000 Subject: [PATCH 009/349] tests: Use .errno instead of .args[0] for OSError exceptions. Signed-off-by: Damien George --- tests/extmod/btree1.py | 2 +- tests/extmod/btree_error.py | 2 +- tests/extmod/uselect_poll_basic.py | 2 +- tests/extmod/usocket_tcp_basic.py | 2 +- tests/extmod/usocket_udp_nonblock.py | 2 +- tests/extmod/vfs_fat_fileio1.py | 10 +++++----- tests/extmod/vfs_fat_fileio2.py | 12 ++++++------ tests/extmod/vfs_fat_more.py | 2 +- tests/extmod/vfs_fat_ramdisk.py | 6 +++--- tests/extmod/websocket_basic.py | 2 +- tests/multi_net/tcp_accept_recv.py | 2 +- tests/multi_net/tcp_client_rst.py | 2 +- tests/multi_net/uasyncio_tcp_client_rst.py | 2 +- tests/net_hosted/accept_nonblock.py | 2 +- tests/net_hosted/accept_timeout.py | 2 +- tests/net_hosted/connect_nonblock.py | 2 +- tests/net_hosted/connect_nonblock_xfer.py | 10 +++++----- tests/net_inet/ssl_errors.py | 2 +- tests/net_inet/test_tls_nonblock.py | 6 +++--- 19 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tests/extmod/btree1.py b/tests/extmod/btree1.py index 4890d92b42..1f4853eaa3 100644 --- a/tests/extmod/btree1.py +++ b/tests/extmod/btree1.py @@ -65,7 +65,7 @@ print(db.seq(1, b"qux")) try: db.seq(b"foo1") except OSError as e: - print(e.args[0] == uerrno.EINVAL) + print(e.errno == uerrno.EINVAL) print(list(db.keys())) print(list(db.values())) diff --git a/tests/extmod/btree_error.py b/tests/extmod/btree_error.py index 00e07ec8c7..b64769e884 100644 --- a/tests/extmod/btree_error.py +++ b/tests/extmod/btree_error.py @@ -27,7 +27,7 @@ class Device(uio.IOBase): try: db = btree.open(Device(), pagesize=511) except OSError as er: - print("OSError", er.args[0] == uerrno.EINVAL) + print("OSError", er.errno == uerrno.EINVAL) # Valid pagesize, device returns error on read; errno comes from Device.readinto try: diff --git a/tests/extmod/uselect_poll_basic.py b/tests/extmod/uselect_poll_basic.py index 07328365b3..97fbd6fd15 100644 --- a/tests/extmod/uselect_poll_basic.py +++ b/tests/extmod/uselect_poll_basic.py @@ -33,7 +33,7 @@ poller.unregister(s) try: poller.modify(s, select.POLLIN) except OSError as e: - assert e.args[0] == errno.ENOENT + assert e.errno == errno.ENOENT # poll after closing the socket, should return POLLNVAL poller.register(s) diff --git a/tests/extmod/usocket_tcp_basic.py b/tests/extmod/usocket_tcp_basic.py index 368dfe3c98..c2fe8cd14c 100644 --- a/tests/extmod/usocket_tcp_basic.py +++ b/tests/extmod/usocket_tcp_basic.py @@ -14,4 +14,4 @@ s = socket.socket() try: s.recv(1) except OSError as er: - print("ENOTCONN:", er.args[0] == errno.ENOTCONN) + print("ENOTCONN:", er.errno == errno.ENOTCONN) diff --git a/tests/extmod/usocket_udp_nonblock.py b/tests/extmod/usocket_udp_nonblock.py index 7dc0e562a3..bc560de142 100644 --- a/tests/extmod/usocket_udp_nonblock.py +++ b/tests/extmod/usocket_udp_nonblock.py @@ -17,4 +17,4 @@ s.settimeout(0) try: s.recv(1) except OSError as er: - print("EAGAIN:", er.args[0] == errno.EAGAIN) + print("EAGAIN:", er.errno == errno.EAGAIN) diff --git a/tests/extmod/vfs_fat_fileio1.py b/tests/extmod/vfs_fat_fileio1.py index e42911093f..7da08b80cf 100644 --- a/tests/extmod/vfs_fat_fileio1.py +++ b/tests/extmod/vfs_fat_fileio1.py @@ -58,22 +58,22 @@ f.close() # allowed try: f.write("world!") except OSError as e: - print(e.args[0] == uerrno.EINVAL) + print(e.errno == uerrno.EINVAL) try: f.read() except OSError as e: - print(e.args[0] == uerrno.EINVAL) + print(e.errno == uerrno.EINVAL) try: f.flush() except OSError as e: - print(e.args[0] == uerrno.EINVAL) + print(e.errno == uerrno.EINVAL) try: open("foo_file.txt", "x") except OSError as e: - print(e.args[0] == uerrno.EEXIST) + print(e.errno == uerrno.EEXIST) with open("foo_file.txt", "a") as f: f.write("world!") @@ -105,7 +105,7 @@ vfs.mkdir("foo_dir") try: vfs.rmdir("foo_file.txt") except OSError as e: - print(e.args[0] == 20) # uerrno.ENOTDIR + print(e.errno == 20) # uerrno.ENOTDIR vfs.remove("foo_file.txt") print(list(vfs.ilistdir())) diff --git a/tests/extmod/vfs_fat_fileio2.py b/tests/extmod/vfs_fat_fileio2.py index 531dd91f94..13978a0af6 100644 --- a/tests/extmod/vfs_fat_fileio2.py +++ b/tests/extmod/vfs_fat_fileio2.py @@ -51,22 +51,22 @@ uos.chdir("/ramdisk") try: vfs.mkdir("foo_dir") except OSError as e: - print(e.args[0] == uerrno.EEXIST) + print(e.errno == uerrno.EEXIST) try: vfs.remove("foo_dir") except OSError as e: - print(e.args[0] == uerrno.EISDIR) + print(e.errno == uerrno.EISDIR) try: vfs.remove("no_file.txt") except OSError as e: - print(e.args[0] == uerrno.ENOENT) + print(e.errno == uerrno.ENOENT) try: vfs.rename("foo_dir", "/null/file") except OSError as e: - print(e.args[0] == uerrno.ENOENT) + print(e.errno == uerrno.ENOENT) # file in dir with open("foo_dir/file-in-dir.txt", "w+t") as f: @@ -82,7 +82,7 @@ with open("foo_dir/sub_file.txt", "w") as f: try: vfs.rmdir("foo_dir") except OSError as e: - print(e.args[0] == uerrno.EACCES) + print(e.errno == uerrno.EACCES) # trim full path vfs.rename("foo_dir/file-in-dir.txt", "foo_dir/file.txt") @@ -111,5 +111,5 @@ try: f = open("large_file.txt", "wb") f.write(bytearray(bsize * free)) except OSError as e: - print("ENOSPC:", e.args[0] == 28) # uerrno.ENOSPC + print("ENOSPC:", e.errno == 28) # uerrno.ENOSPC f.close() diff --git a/tests/extmod/vfs_fat_more.py b/tests/extmod/vfs_fat_more.py index 076802f6ad..f9b54fda00 100644 --- a/tests/extmod/vfs_fat_more.py +++ b/tests/extmod/vfs_fat_more.py @@ -90,7 +90,7 @@ for exist in ("", "/", "dir", "/dir", "dir/subdir"): try: uos.mkdir(exist) except OSError as er: - print("mkdir OSError", er.args[0] == 17) # EEXIST + print("mkdir OSError", er.errno == 17) # EEXIST uos.chdir("/") print(uos.stat("test5.txt")[:-3]) diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py index 9a68d94fed..4decb5557d 100644 --- a/tests/extmod/vfs_fat_ramdisk.py +++ b/tests/extmod/vfs_fat_ramdisk.py @@ -57,7 +57,7 @@ print("getcwd:", vfs.getcwd()) try: vfs.stat("no_file.txt") except OSError as e: - print(e.args[0] == uerrno.ENOENT) + print(e.errno == uerrno.ENOENT) with vfs.open("foo_file.txt", "w") as f: f.write("hello!") @@ -80,7 +80,7 @@ with vfs.open("sub_file.txt", "w") as f: try: vfs.chdir("sub_file.txt") except OSError as e: - print(e.args[0] == uerrno.ENOENT) + print(e.errno == uerrno.ENOENT) vfs.chdir("..") print("getcwd:", vfs.getcwd()) @@ -94,4 +94,4 @@ print(list(vfs.ilistdir(b""))) try: vfs.ilistdir(b"no_exist") except OSError as e: - print("ENOENT:", e.args[0] == uerrno.ENOENT) + print("ENOENT:", e.errno == uerrno.ENOENT) diff --git a/tests/extmod/websocket_basic.py b/tests/extmod/websocket_basic.py index 10396e914d..a07542f965 100644 --- a/tests/extmod/websocket_basic.py +++ b/tests/extmod/websocket_basic.py @@ -59,4 +59,4 @@ print(ws.ioctl(9)) try: ws.ioctl(-1) except OSError as e: - print("ioctl: EINVAL:", e.args[0] == uerrno.EINVAL) + print("ioctl: EINVAL:", e.errno == uerrno.EINVAL) diff --git a/tests/multi_net/tcp_accept_recv.py b/tests/multi_net/tcp_accept_recv.py index d61108ed1c..f93ede3bf4 100644 --- a/tests/multi_net/tcp_accept_recv.py +++ b/tests/multi_net/tcp_accept_recv.py @@ -17,7 +17,7 @@ def instance0(): try: print("recv", s.recv(10)) # should raise Errno 107 ENOTCONN except OSError as er: - print(er.args[0]) + print(er.errno) s.close() diff --git a/tests/multi_net/tcp_client_rst.py b/tests/multi_net/tcp_client_rst.py index 08f262db50..14da8b1470 100644 --- a/tests/multi_net/tcp_client_rst.py +++ b/tests/multi_net/tcp_client_rst.py @@ -33,7 +33,7 @@ def instance0(): print(s2.recv(10)) print(convert_poll_list(poll.poll(1000))) except OSError as er: - print(er.args[0]) + print(er.errno) print(convert_poll_list(poll.poll(1000))) # TODO lwip raises here but apparently it shouldn't print(s2.recv(10)) diff --git a/tests/multi_net/uasyncio_tcp_client_rst.py b/tests/multi_net/uasyncio_tcp_client_rst.py index a3a05490c7..d81f22748e 100644 --- a/tests/multi_net/uasyncio_tcp_client_rst.py +++ b/tests/multi_net/uasyncio_tcp_client_rst.py @@ -24,7 +24,7 @@ async def handle_connection(reader, writer): writer.close() await writer.wait_closed() except OSError as er: - print("OSError", er.args[0]) + print("OSError", er.errno) ev.set() diff --git a/tests/net_hosted/accept_nonblock.py b/tests/net_hosted/accept_nonblock.py index 941965e178..d17e287498 100644 --- a/tests/net_hosted/accept_nonblock.py +++ b/tests/net_hosted/accept_nonblock.py @@ -12,5 +12,5 @@ s.listen(1) try: s.accept() except OSError as er: - print(er.args[0] == 11) # 11 is EAGAIN + print(er.errno == 11) # 11 is EAGAIN s.close() diff --git a/tests/net_hosted/accept_timeout.py b/tests/net_hosted/accept_timeout.py index 5f528d557d..734fe217ca 100644 --- a/tests/net_hosted/accept_timeout.py +++ b/tests/net_hosted/accept_timeout.py @@ -18,5 +18,5 @@ s.listen(1) try: s.accept() except OSError as er: - print(er.args[0] in (errno.ETIMEDOUT, "timed out")) # CPython uses a string instead of errno + print(er.errno in (errno.ETIMEDOUT, "timed out")) # CPython uses a string instead of errno s.close() diff --git a/tests/net_hosted/connect_nonblock.py b/tests/net_hosted/connect_nonblock.py index c024b65a0a..4b8055c161 100644 --- a/tests/net_hosted/connect_nonblock.py +++ b/tests/net_hosted/connect_nonblock.py @@ -13,7 +13,7 @@ def test(peer_addr): try: s.connect(peer_addr) except OSError as er: - print(er.args[0] == errno.EINPROGRESS) + print(er.errno == errno.EINPROGRESS) s.close() diff --git a/tests/net_hosted/connect_nonblock_xfer.py b/tests/net_hosted/connect_nonblock_xfer.py index feb648ea0a..1a0b242276 100644 --- a/tests/net_hosted/connect_nonblock_xfer.py +++ b/tests/net_hosted/connect_nonblock_xfer.py @@ -25,9 +25,9 @@ def do_connect(peer_addr, tls, handshake): # print("Connecting to", peer_addr) s.connect(peer_addr) except OSError as er: - print("connect:", er.args[0] == errno.EINPROGRESS) - if er.args[0] != errno.EINPROGRESS: - print(" got", er.args[0]) + print("connect:", er.errno == errno.EINPROGRESS) + if er.errno != errno.EINPROGRESS: + print(" got", er.errno) # wrap with ssl/tls if desired if tls: try: @@ -67,7 +67,7 @@ def test(peer_addr, tls=False, handshake=False): except OSError as er: # dp(er) - print("send:", er.args[0] in (errno.EAGAIN, errno.EINPROGRESS)) + print("send:", er.errno in (errno.EAGAIN, errno.EINPROGRESS)) s.close() else: # fake it... print("connect:", True) @@ -103,7 +103,7 @@ def test(peer_addr, tls=False, handshake=False): print("recv:", s.recv(10)) except OSError as er: dp(er) - print("recv:", er.args[0] == errno.EAGAIN) + print("recv:", er.errno == errno.EAGAIN) s.close() else: # fake it... print("connect:", True) diff --git a/tests/net_inet/ssl_errors.py b/tests/net_inet/ssl_errors.py index fd281b1c49..ece1f6e253 100644 --- a/tests/net_inet/ssl_errors.py +++ b/tests/net_inet/ssl_errors.py @@ -17,7 +17,7 @@ def test(addr, hostname, block=True): s.connect(addr) print("connected") except OSError as e: - if e.args[0] != errno.EINPROGRESS: + if e.errno != errno.EINPROGRESS: raise print("EINPROGRESS") diff --git a/tests/net_inet/test_tls_nonblock.py b/tests/net_inet/test_tls_nonblock.py index c27ead3d50..54abc6966f 100644 --- a/tests/net_inet/test_tls_nonblock.py +++ b/tests/net_inet/test_tls_nonblock.py @@ -16,7 +16,7 @@ def test_one(site, opts): s.connect(addr) raise OSError(-1, "connect blocks") except OSError as e: - if e.args[0] != errno.EINPROGRESS: + if e.errno != errno.EINPROGRESS: raise if sys.implementation.name != "micropython": @@ -31,7 +31,7 @@ def test_one(site, opts): else: s = ssl.wrap_socket(s, do_handshake_on_connect=False) except OSError as e: - if e.args[0] != errno.EINPROGRESS: + if e.errno != errno.EINPROGRESS: raise print("wrapped") @@ -69,7 +69,7 @@ def test_one(site, opts): try: b = s.read(128) except OSError as err: - if err.args[0] == 2: # 2=ssl.SSL_ERROR_WANT_READ: + if err.errno == 2: # 2=ssl.SSL_ERROR_WANT_READ: continue raise if b is None: From 178198a01df51b5f4c5ef9f38ab2fb8f6269d5f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 21 Apr 2021 11:00:43 +1000 Subject: [PATCH 010/349] tools/pyboard.py: Support opening serial port in exclusive mode. This is now the default, but can be overridden with CLI `--no-exclusive`, or constructing `Pyboard(..., exclusive=False)`. Signed-off-by: Damien George --- tools/pyboard.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 069f7490d0..29a15f7eae 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -4,7 +4,7 @@ # # The MIT License (MIT) # -# Copyright (c) 2014-2019 Damien P. George +# Copyright (c) 2014-2021 Damien P. George # Copyright (c) 2017 Paul Sokolovsky # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -252,7 +252,9 @@ class ProcessPtyToTerminal: class Pyboard: - def __init__(self, device, baudrate=115200, user="micro", password="python", wait=0): + def __init__( + self, device, baudrate=115200, user="micro", password="python", wait=0, exclusive=True + ): self.use_raw_paste = True if device.startswith("exec:"): self.serial = ProcessToSerial(device[len("exec:") :]) @@ -264,10 +266,15 @@ class Pyboard: else: import serial + # Set options, and exclusive if pyserial supports it + serial_kwargs = {"baudrate": baudrate, "interCharTimeout": 1} + if serial.__version__ >= "3.3": + serial_kwargs["exclusive"] = exclusive + delayed = False for attempt in range(wait + 1): try: - self.serial = serial.Serial(device, baudrate=baudrate, interCharTimeout=1) + self.serial = serial.Serial(device, **serial_kwargs) break except (OSError, IOError): # Py2 and Py3 have different errors if wait == 0: @@ -650,6 +657,11 @@ def main(): action="store_true", help="Do not follow the output after running the scripts.", ) + group.add_argument( + "--no-exclusive", + action="store_true", + help="Do not try to open the serial device for exclusive access.", + ) cmd_parser.add_argument( "-f", "--filesystem", @@ -662,7 +674,9 @@ def main(): # open the connection to the pyboard try: - pyb = Pyboard(args.device, args.baudrate, args.user, args.password, args.wait) + pyb = Pyboard( + args.device, args.baudrate, args.user, args.password, args.wait, not args.no_exclusive + ) except PyboardError as er: print(er) sys.exit(1) From df4e9bdf5c69e36775de313b098651bbd97132a7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Apr 2021 10:26:52 +1000 Subject: [PATCH 011/349] esp32/CMakeLists.txt: Require CMake version 3.12. Because "find_package(Python3 ...)" requires at least this version of CMake. And other features like GREATER_EQUAL and COMMAND_EXPAND_LISTS need at least CMake 3.7 and 3.8 respectively. Signed-off-by: Damien George --- ports/esp32/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/CMakeLists.txt b/ports/esp32/CMakeLists.txt index fa419202f9..29409adc74 100644 --- a/ports/esp32/CMakeLists.txt +++ b/ports/esp32/CMakeLists.txt @@ -1,6 +1,6 @@ # Top-level cmake file for building MicroPython on ESP32. -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.12) # Set the location of this port's directory. set(MICROPY_PORT_DIR ${CMAKE_SOURCE_DIR}) From bb2007b05ccf0e41684cc61f1677c11b7df93f7a Mon Sep 17 00:00:00 2001 From: stijn Date: Thu, 22 Apr 2021 18:01:46 +0200 Subject: [PATCH 012/349] windows/mpconfigport.h: Enable features also present in unix port. --- ports/windows/mpconfigport.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/windows/mpconfigport.h b/ports/windows/mpconfigport.h index faf10752ee..6421c93bdb 100644 --- a/ports/windows/mpconfigport.h +++ b/ports/windows/mpconfigport.h @@ -65,6 +65,7 @@ #define MICROPY_VFS_POSIX_FILE (1) #define MICROPY_PY_FUNCTION_ATTRS (1) #define MICROPY_PY_DESCRIPTORS (1) +#define MICROPY_PY_DELATTR_SETATTR (1) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) #define MICROPY_PY_BUILTINS_STR_CENTER (1) #define MICROPY_PY_BUILTINS_STR_PARTITION (1) @@ -75,12 +76,14 @@ #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_BUILTINS_INPUT (1) #define MICROPY_PY_BUILTINS_POW3 (1) +#define MICROPY_PY_BUILTINS_ROUND_INT (1) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_SYS_EXIT (1) +#define MICROPY_PY_SYS_ATEXIT (1) #define MICROPY_PY_SYS_PLATFORM "win32" #ifndef MICROPY_PY_SYS_PATH_DEFAULT #define MICROPY_PY_SYS_PATH_DEFAULT "~/.micropython/lib" @@ -93,6 +96,7 @@ #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) #define MICROPY_PY_MATH_ISCLOSE (1) #define MICROPY_PY_CMATH (1) +#define MICROPY_PY_IO_IOBASE (1) #define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_GC_COLLECT_RETVAL (1) #define MICROPY_MODULE_FROZEN_STR (0) From a1bc32d8a8fbb09bc04c2ca07b10475f7ddde8c3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 23 Apr 2021 23:44:37 +1000 Subject: [PATCH 013/349] drivers/sdcard: Add sleep_ms(1) delay in SDCard.readinto sync loop. So this driver works on faster MCUs (that run this loop fast) with older, slower SD cards. Fixes issue #7129. Signed-off-by: Damien George --- drivers/sdcard/sdcard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py index c991fe5608..0ba3076a3d 100644 --- a/drivers/sdcard/sdcard.py +++ b/drivers/sdcard/sdcard.py @@ -176,6 +176,7 @@ class SDCard: self.spi.readinto(self.tokenbuf, 0xFF) if self.tokenbuf[0] == _TOKEN_DATA: break + time.sleep_ms(1) else: self.cs(1) raise OSError("timeout waiting for response") From 530c76f6caee9445f468380f58b98f4e3ceda759 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 24 Apr 2021 00:10:59 +1000 Subject: [PATCH 014/349] lib/utils: Remove unused PYEXEC_SWITCH_MODE from pyexec.h. It was made obsolete by commit c98c128fe885e539ecd73843756340f8950115c8. Signed-off-by: Damien George --- lib/utils/pyexec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h index f69c5ce9a8..981e7dca9f 100644 --- a/lib/utils/pyexec.h +++ b/lib/utils/pyexec.h @@ -41,7 +41,6 @@ extern pyexec_mode_kind_t pyexec_mode_kind; extern int pyexec_system_exit; #define PYEXEC_FORCED_EXIT (0x100) -#define PYEXEC_SWITCH_MODE (0x200) int pyexec_raw_repl(void); int pyexec_friendly_repl(void); From 65b90cd0f9cb3ee8b5954820cd6d68b782121cd1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Apr 2021 11:04:58 +1000 Subject: [PATCH 015/349] teensy: Provide own implementation of gc_collect, to not use stm32. Signed-off-by: Damien George --- ports/teensy/Makefile | 1 - ports/teensy/main.c | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/teensy/Makefile b/ports/teensy/Makefile index d3978718e0..cf9529442a 100644 --- a/ports/teensy/Makefile +++ b/ports/teensy/Makefile @@ -95,7 +95,6 @@ SRC_C = \ usb.c \ STM_SRC_C = $(addprefix ports/stm32/,\ - gccollect.c \ irq.c \ pin.c \ pin_named_pins.c \ diff --git a/ports/teensy/main.c b/ports/teensy/main.c index df3fd1ffcf..d4c5f0396f 100644 --- a/ports/teensy/main.c +++ b/ports/teensy/main.c @@ -9,6 +9,7 @@ #include "py/gc.h" #include "py/mphal.h" #include "gccollect.h" +#include "lib/utils/gchelper.h" #include "lib/utils/pyexec.h" #include "lib/mp-readline/readline.h" #include "lexermemzip.h" @@ -349,6 +350,12 @@ soft_reset: goto soft_reset; } +void gc_collect(void) { + gc_collect_start(); + gc_helper_collect_regs_and_stack(); + gc_collect_end(); +} + // stub out __libc_init_array. It's called by mk20dx128.c and is used to call // global C++ constructors. Since this is a C-only projects, we don't need to // call constructors. From 0f78c36c5aa458a954eed39a46942209107a553e Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 27 Apr 2021 01:15:43 +0200 Subject: [PATCH 016/349] tools/gen-cpydiff.py: Fix formatting of doc strings for new Black. Since version 21.4b0, Black now processes one-line docstrings by stripping leading and trailing spaces, and adding a padding space when needed to break up """"; see https://github.com/psf/black/pull/1740 This commit makes the Python code in this repository conform to this rule. --- tools/gen-cpydiff.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/gen-cpydiff.py b/tools/gen-cpydiff.py index c45bad1058..c9f58ec505 100644 --- a/tools/gen-cpydiff.py +++ b/tools/gen-cpydiff.py @@ -74,7 +74,7 @@ Output = namedtuple( def readfiles(): - """ Reads test files """ + """Reads test files""" tests = list(filter(lambda x: x.endswith(".py"), os.listdir(TESTPATH))) tests.sort() files = [] @@ -95,7 +95,7 @@ def readfiles(): def uimports(code): - """ converts CPython module names into MicroPython equivalents """ + """converts CPython module names into MicroPython equivalents""" for uimport in UIMPORTLIST: uimport = bytes(uimport, "utf8") code = code.replace(uimport, b"u" + uimport) @@ -103,7 +103,7 @@ def uimports(code): def run_tests(tests): - """ executes all tests """ + """executes all tests""" results = [] for test in tests: with open(TESTPATH + test.name, "rb") as f: @@ -152,7 +152,7 @@ def run_tests(tests): def indent(block, spaces): - """ indents paragraphs of text for rst formatting """ + """indents paragraphs of text for rst formatting""" new_block = "" for line in block.split("\n"): new_block += spaces + line + "\n" @@ -160,7 +160,7 @@ def indent(block, spaces): def gen_table(contents): - """ creates a table given any set of columns """ + """creates a table given any set of columns""" xlengths = [] ylengths = [] for column in contents: @@ -194,7 +194,7 @@ def gen_table(contents): def gen_rst(results): - """ creates restructured text documents to display tests """ + """creates restructured text documents to display tests""" # make sure the destination directory exists try: @@ -254,7 +254,7 @@ def gen_rst(results): def main(): - """ Main function """ + """Main function""" # set search path so that test scripts find the test modules (and no other ones) os.environ["PYTHONPATH"] = TESTPATH From 30d9f77cc535306eeb9eed6f17e71355fd58995a Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 27 Apr 2021 23:46:46 +1000 Subject: [PATCH 017/349] top: Update .git-blame-ignore-revs for latest formatting commit. Signed-off-by: Damien George --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 83726922a5..c5039f58b5 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,6 @@ +# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black. +0f78c36c5aa458a954eed39a46942209107a553e + # tests/run-tests.py: Reformat with Black. 2a38d7103672580882fb621a5b76e8d26805d593 From d4b706c4d01377d42855ff1544ced77536f69caf Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Apr 2021 12:13:58 +1000 Subject: [PATCH 018/349] py: Add option to compile without any error messages at all. This introduces a new option, MICROPY_ERROR_REPORTING_NONE, which completely disables all error messages. To be used in cases where MicroPython needs to fit in very limited systems. Signed-off-by: Damien George --- py/argcheck.c | 14 ++++++------ py/bc.c | 4 ++-- py/builtinimport.c | 4 ++-- py/compile.c | 4 ++-- py/misc.h | 4 ++++ py/modbuiltins.c | 2 +- py/mpconfig.h | 2 ++ py/obj.c | 20 ++++++++--------- py/obj.h | 5 +++++ py/objexcept.c | 4 ++++ py/objnamedtuple.c | 6 +++--- py/objstr.c | 38 ++++++++++++++++---------------- py/objtype.c | 8 +++---- py/parsenum.c | 2 +- py/runtime.c | 54 ++++++++++++++++++++++++++++++++-------------- py/runtime.h | 13 +++++++++++ 16 files changed, 117 insertions(+), 67 deletions(-) diff --git a/py/argcheck.c b/py/argcheck.c index c333ead05b..ffcca4cb65 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -38,7 +38,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { size_t n_args_max = (sig >> 1) & 0xffff; if (n_kw && !takes_kw) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_TypeError(MP_ERROR_TEXT("function doesn't take keyword arguments")); @@ -47,7 +47,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { if (n_args_min == n_args_max) { if (n_args != n_args_min) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -57,7 +57,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { } } else { if (n_args < n_args_min) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -65,7 +65,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { n_args_min - n_args); #endif } else if (n_args > n_args_max) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -90,7 +90,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP); if (kw == NULL) { if (allowed[i].flags & MP_ARG_REQUIRED) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%q' argument required"), allowed[i].qst); @@ -114,7 +114,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n } if (pos_found < n_pos) { extra_positional: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else // TODO better error message @@ -122,7 +122,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n #endif } if (kws_found < kws->used) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else // TODO better error message diff --git a/py/bc.c b/py/bc.c index 34bc78fd3a..58694b97dc 100644 --- a/py/bc.c +++ b/py/bc.c @@ -75,7 +75,7 @@ const byte *mp_decode_uint_skip(const byte *ptr) { #endif STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE // generic message, used also for other argument issues (void)f; (void)expected; @@ -212,7 +212,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw } // Didn't find name match with positional args if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("unexpected keyword argument")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/builtinimport.c b/py/builtinimport.c index bdc82e77c8..874d2dd7f0 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -396,7 +396,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif if (module_obj == MP_OBJ_NULL) { // couldn't find the file, so fail - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), mod_name); @@ -499,7 +499,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif // Couldn't find the module, so fail - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), module_name_qstr); diff --git a/py/compile.c b/py/compile.c index d1a4d65c8b..1182b8b1eb 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2597,7 +2597,7 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t * compile_node(comp, pn_i); if (is_dict) { if (!is_key_value) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax")); #else compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting key:value for dict")); @@ -2607,7 +2607,7 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t * EMIT(store_map); } else { if (is_key_value) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax")); #else compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting just a value for set")); diff --git a/py/misc.h b/py/misc.h index fe2b3b8afa..9538098383 100644 --- a/py/misc.h +++ b/py/misc.h @@ -264,6 +264,10 @@ typedef union _mp_float_union_t { #if MICROPY_ROM_TEXT_COMPRESSION +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +#error "MICROPY_ERROR_REPORTING_NONE requires MICROPY_ROM_TEXT_COMPRESSION disabled" +#endif + #ifdef NO_QSTR // Compression enabled but doing QSTR extraction. diff --git a/py/modbuiltins.c b/py/modbuiltins.c index cfbfc5a256..ac41942b9c 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -372,7 +372,7 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) { } } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("ord expects a character")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/mpconfig.h b/py/mpconfig.h index 3dd83a34ab..5c7212fd1f 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -667,6 +667,8 @@ typedef long long mp_longint_impl_t; #define MICROPY_ENABLE_DOC_STRING (0) #endif +// Exception messages are removed (requires disabling MICROPY_ROM_TEXT_COMPRESSION) +#define MICROPY_ERROR_REPORTING_NONE (0) // Exception messages are short static strings #define MICROPY_ERROR_REPORTING_TERSE (1) // Exception messages provide basic error details diff --git a/py/obj.c b/py/obj.c index ed047acc39..f66a9d183c 100644 --- a/py/obj.c +++ b/py/obj.c @@ -359,7 +359,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { mp_float_t val; if (!mp_obj_get_float_maybe(arg, &val)) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to float")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -399,7 +399,7 @@ bool mp_obj_get_complex_maybe(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { if (!mp_obj_get_complex_maybe(arg, real, imag)) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to complex")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -417,7 +417,7 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { } 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 + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("expected tuple/list")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -431,7 +431,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { size_t seq_len; mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("tuple/list has wrong length")); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -446,7 +446,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool 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 + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("indices must be integers")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -466,7 +466,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool } } else { if (i < 0 || (mp_uint_t)i >= len) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("index out of range")); #else mp_raise_msg_varg(&mp_type_IndexError, MP_ERROR_TEXT("%q index out of range"), type->name); @@ -500,7 +500,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in) { mp_obj_t mp_obj_len(mp_obj_t o_in) { mp_obj_t len = mp_obj_len_maybe(o_in); if (len == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object has no len")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -541,21 +541,21 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { // TODO: call base classes here? } if (value == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item deletion")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%s' object doesn't support item deletion"), mp_obj_get_type_str(base)); #endif } else if (value == MP_OBJ_SENTINEL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object isn't subscriptable")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%s' object isn't subscriptable"), mp_obj_get_type_str(base)); #endif } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item assignment")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/obj.h b/py/obj.h index 6a040b7773..86e5d83125 100644 --- a/py/obj.h +++ b/py/obj.h @@ -741,8 +741,13 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args); +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +#define mp_obj_new_exception_msg(exc_type, msg) mp_obj_new_exception(exc_type) +#define mp_obj_new_exception_msg_varg(exc_type, ...) mp_obj_new_exception(exc_type) +#else mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) +#endif #ifdef va_start mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list arg); // same fmt restrictions as above #endif diff --git a/py/objexcept.c b/py/objexcept.c index f6bffec383..f03bb1b416 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -373,6 +373,8 @@ mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, return mp_obj_exception_make_new(exc_type, n_args, 0, args); } +#if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_NONE + mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { // Check that the given type is an exception type assert(exc_type->make_new == mp_obj_exception_make_new); @@ -518,6 +520,8 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_er return mp_obj_exception_make_new(exc_type, 1, 0, &arg); } +#endif + // 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)) { diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index e4543f5b9b..214cad2572 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -95,7 +95,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t *)type_in; size_t num_fields = type->n_fields; if (n_args + n_kw != num_fields) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL mp_raise_msg_varg(&mp_type_TypeError, @@ -121,14 +121,14 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, qstr kw = mp_obj_str_get_qstr(args[i]); size_t id = mp_obj_namedtuple_find_field(type, kw); if (id == (size_t)-1) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), kw); #endif } if (tuple->items[id] != MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/objstr.c b/py/objstr.c index 9f8da873d6..98657bd217 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -942,7 +942,7 @@ STATIC mp_obj_t arg_as_int(mp_obj_t arg) { } #endif -#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE +#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE STATIC NORETURN void terse_str_format_value_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("bad format string")); } @@ -963,7 +963,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar vstr_add_byte(&vstr, '}'); continue; } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("single '}' encountered in format string")); @@ -1002,7 +1002,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (str < top && (*str == 'r' || *str == 's')) { conversion = *str++; } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL mp_raise_ValueError(MP_ERROR_TEXT("bad conversion specifier")); @@ -1040,14 +1040,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } } if (str >= top) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("unmatched '{' in format")); #endif } if (*str != '}') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("expected ':' after format specifier")); @@ -1060,7 +1060,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar int index = 0; if (MP_LIKELY(unichar_isdigit(*field_name))) { if (*arg_i > 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1090,7 +1090,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } } else { if (*arg_i < 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1183,7 +1183,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar type = *s++; } if (*s) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("invalid format specifier")); @@ -1204,14 +1204,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (flags & (PF_FLAG_SHOW_SIGN | PF_FLAG_SPACE_SIGN)) { if (type == 's') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("sign not allowed in string format specifier")); #endif } if (type == 'c') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1275,7 +1275,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar break; default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1347,7 +1347,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar #endif default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1359,7 +1359,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar // arg doesn't look like a number if (align == '=') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1383,7 +1383,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1412,7 +1412,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ mp_check_self(mp_obj_is_str_or_bytes(pattern)); GET_STR_DATA_LEN(pattern, str, len); - #if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING > MICROPY_ERROR_REPORTING_TERSE const byte *start_str = str; #endif bool is_bytes = mp_obj_is_type(pattern, &mp_type_bytes); @@ -1444,7 +1444,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ const byte *key = ++str; while (*str != ')') { if (str >= top) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("incomplete format key")); @@ -1508,7 +1508,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (str >= top) { incomplete_format: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("incomplete format")); @@ -1594,7 +1594,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ break; default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -2131,7 +2131,7 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { } STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to str implicitly")); #else const qstr src_name = mp_obj_get_type(self_in)->name; diff --git a/py/objtype.c b/py/objtype.c index 7f75232941..508bab99d3 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -348,7 +348,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw); } if (init_ret != mp_const_none) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("__init__() should return None")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -860,7 +860,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons mp_obj_t member[2] = {MP_OBJ_NULL, MP_OBJ_NULL}; mp_obj_t call = mp_obj_instance_get_call(self_in, member); if (call == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -985,7 +985,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); if (self->make_new == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't create instance")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("can't create '%q' instances"), self->name); @@ -1125,7 +1125,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("type isn't an acceptable base type")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/parsenum.c b/py/parsenum.c index e665da7d8c..1cfe842577 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -145,7 +145,7 @@ overflow: value_error: { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("invalid syntax for integer")); raise_exc(exc, lex); diff --git a/py/runtime.c b/py/runtime.c index 0ce6854732..18a7c8565d 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -189,7 +189,7 @@ mp_obj_t mp_load_global(qstr qst) { #endif elem = mp_map_lookup((mp_map_t *)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined")); #else mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst); @@ -289,7 +289,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { } // With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int(). // In this case provide a more focused error message to not confuse, e.g. chr(1.0) - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE if (op == MP_UNARY_OP_INT) { mp_raise_TypeError(MP_ERROR_TEXT("can't convert to int")); } else { @@ -610,7 +610,7 @@ generic_binary_op: } unsupported_op: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -652,7 +652,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons return type->call(fun_in, n_args, n_kw, args); } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -881,13 +881,13 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { return; too_short: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len); #endif too_long: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("too many values to unpack (expected %d)"), (int)num); @@ -948,7 +948,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { return; too_short: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len); @@ -1117,7 +1117,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // no attribute/method called attr - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute")); #else // following CPython, we give a more detailed error message for type objects @@ -1161,7 +1161,7 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { return; } } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute")); #else mp_raise_msg_varg(&mp_type_AttributeError, @@ -1206,7 +1206,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { } // object not iterable - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not iterable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1229,7 +1229,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { // __next__ exists, call it and return its result return mp_call_method_n_kw(0, 0, dest); } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1265,7 +1265,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1512,6 +1512,26 @@ NORETURN void m_malloc_fail(size_t num_bytes) { MP_ERROR_TEXT("memory allocation failed, allocating %u bytes"), (uint)num_bytes); } +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE + +NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) { + nlr_raise(mp_obj_new_exception(exc_type)); +} + +NORETURN void mp_raise_ValueError_no_msg(void) { + mp_raise_type(&mp_type_ValueError); +} + +NORETURN void mp_raise_TypeError_no_msg(void) { + mp_raise_type(&mp_type_TypeError); +} + +NORETURN void mp_raise_NotImplementedError_no_msg(void) { + mp_raise_type(&mp_type_NotImplementedError); +} + +#else + NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); @@ -1536,14 +1556,16 @@ NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_TypeError, msg); } -NORETURN void mp_raise_OSError(int errno_) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); -} - NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } +#endif + +NORETURN void mp_raise_OSError(int errno_) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); +} + #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK NORETURN void mp_raise_recursion_depth(void) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError, diff --git a/py/runtime.h b/py/runtime.h index 0bf988b905..0cbbb287ac 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -159,12 +159,25 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); mp_obj_t mp_import_from(mp_obj_t module, qstr name); void mp_import_all(mp_obj_t module); +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +NORETURN void mp_raise_type(const mp_obj_type_t *exc_type); +NORETURN void mp_raise_ValueError_no_msg(void); +NORETURN void mp_raise_TypeError_no_msg(void); +NORETURN void mp_raise_NotImplementedError_no_msg(void); +#define mp_raise_msg(exc_type, msg) mp_raise_type(exc_type) +#define mp_raise_msg_varg(exc_type, ...) mp_raise_type(exc_type) +#define mp_raise_ValueError(msg) mp_raise_ValueError_no_msg() +#define mp_raise_TypeError(msg) mp_raise_TypeError_no_msg() +#define mp_raise_NotImplementedError(msg) mp_raise_NotImplementedError_no_msg() +#else #define mp_raise_type(exc_type) mp_raise_msg(exc_type, NULL) NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); +#endif + NORETURN void mp_raise_OSError(int errno_); NORETURN void mp_raise_recursion_depth(void); From 43a8c8178e0b5e2460edde0fdf436509a7f28764 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 27 Apr 2021 23:52:40 +1000 Subject: [PATCH 019/349] bare-arm: Switch to use MICROPY_ERROR_REPORTING_NONE to reduce size. Reduces size of this port by about 3300 bytes, and demonstrates how to use this feature. Signed-off-by: Damien George --- ports/bare-arm/Makefile | 2 +- ports/bare-arm/README.md | 2 +- ports/bare-arm/mpconfigport.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/bare-arm/Makefile b/ports/bare-arm/Makefile index 455a9dc5ac..1a21eb56a8 100644 --- a/ports/bare-arm/Makefile +++ b/ports/bare-arm/Makefile @@ -5,7 +5,7 @@ include ../../py/mkenv.mk include $(TOP)/py/py.mk # Set makefile-level MicroPython feature configurations. -MICROPY_ROM_TEXT_COMPRESSION ?= 1 +MICROPY_ROM_TEXT_COMPRESSION ?= 0 # Define toolchain and other tools. CROSS_COMPILE ?= arm-none-eabi- diff --git a/ports/bare-arm/README.md b/ports/bare-arm/README.md index 496ee9c755..dfa5534d59 100644 --- a/ports/bare-arm/README.md +++ b/ports/bare-arm/README.md @@ -18,4 +18,4 @@ compiled and executed when the firmware starts. They produce output on the system's stdout. The size of the firmware (the machine code that is programmed to the -microcontroller's flash/ROM) is currently around 61200 bytes. +microcontroller's flash/ROM) is currently around 57900 bytes. diff --git a/ports/bare-arm/mpconfigport.h b/ports/bare-arm/mpconfigport.h index 41b6ee71a3..3bebc31594 100644 --- a/ports/bare-arm/mpconfigport.h +++ b/ports/bare-arm/mpconfigport.h @@ -37,7 +37,7 @@ // Python internal features #define MICROPY_ENABLE_EXTERNAL_IMPORT (0) -#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NONE) #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_MODULE_GETATTR (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) From c5cbfd545ab436ef526e7fce7fafab89ac1b69f8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 24 Apr 2021 09:18:09 +1000 Subject: [PATCH 020/349] py/dynruntime.h: Add mp_obj_get_array() function. Signed-off-by: Damien George --- py/dynruntime.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/py/dynruntime.h b/py/dynruntime.h index eb8301284e..a8256c1948 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -81,6 +81,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_type_type (*mp_fun_table.type_type) #define mp_type_str (*mp_fun_table.type_str) +#define mp_type_tuple (*((mp_obj_base_t *)mp_const_empty_tuple)->type) #define mp_type_list (*mp_fun_table.type_list) #define mp_type_EOFError (*(mp_obj_type_t *)(mp_load_global(MP_QSTR_EOFError))) #define mp_type_IndexError (*(mp_obj_type_t *)(mp_load_global(MP_QSTR_IndexError))) @@ -121,6 +122,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_obj_len(o) (mp_obj_len_dyn(o)) #define mp_obj_subscr(base, index, val) (mp_fun_table.obj_subscr((base), (index), (val))) +#define mp_obj_get_array(o, len, items) (mp_obj_get_array_dyn((o), (len), (items))) #define mp_obj_list_append(list, item) (mp_fun_table.list_append((list), (item))) static inline mp_obj_t mp_obj_new_str_of_type_dyn(const mp_obj_type_t *type, const byte *data, size_t len) { @@ -251,4 +253,23 @@ static inline void mp_raise_OSError_dyn(int er) { #define mp_obj_get_float(o) (mp_obj_get_float_to_d((o))) #endif +/******************************************************************************/ +// Inline function definitions. + +// *items may point inside a GC block +static inline void mp_obj_get_array_dyn(mp_obj_t o, size_t *len, mp_obj_t **items) { + const mp_obj_type_t *type = mp_obj_get_type(o); + if (type == &mp_type_tuple) { + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(o); + *len = t->len; + *items = &t->items[0]; + } else if (type == &mp_type_list) { + mp_obj_list_t *l = MP_OBJ_TO_PTR(o); + *len = l->len; + *items = l->items; + } else { + mp_raise_TypeError("expected tuple/list"); + } +} + #endif // MICROPY_INCLUDED_PY_DYNRUNTIME_H From f452b9c26569a4e05e026a668dd336f80203f06d Mon Sep 17 00:00:00 2001 From: Daniel Maslowski Date: Sat, 24 Apr 2021 17:41:55 +0200 Subject: [PATCH 021/349] pic16bit/Makefile: Make the XC compiler version user-configurable. --- ports/pic16bit/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/pic16bit/Makefile b/ports/pic16bit/Makefile index fa6de38e39..3c2bd54ea2 100644 --- a/ports/pic16bit/Makefile +++ b/ports/pic16bit/Makefile @@ -6,7 +6,8 @@ QSTR_DEFS = qstrdefsport.h # include py core make definitions include $(TOP)/py/py.mk -XC16 = /opt/microchip/xc16/v1.35 +XCVERSION ?= 1.35 +XC16 ?= /opt/microchip/xc16/v$(XCVERSION) CROSS_COMPILE ?= $(XC16)/bin/xc16- PARTFAMILY = dsPIC33F From 4dc802400fb81cf674067b9fcb177139ea5ae27e Mon Sep 17 00:00:00 2001 From: plan-do-break-fix Date: Sun, 25 Apr 2021 01:38:45 -0500 Subject: [PATCH 022/349] stm32,teensy: Correct typos in project README files. --- ports/stm32/mboot/README.md | 2 +- ports/teensy/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/stm32/mboot/README.md b/ports/stm32/mboot/README.md index 59213eb615..b85bc3e2ee 100644 --- a/ports/stm32/mboot/README.md +++ b/ports/stm32/mboot/README.md @@ -159,7 +159,7 @@ Signed and encrypted DFU support -------------------------------- Mboot optionally supports signing and encrypting the binary firmware in the DFU file. -In general this is refered to as a packed DFU file. This requires additional settings +In general this is referred to as a packed DFU file. This requires additional settings in the board config and requires the `pyhy` Python module to be installed for `python3` to be used when building packed firmware, eg: diff --git a/ports/teensy/README.md b/ports/teensy/README.md index c586853b52..dacc463ccd 100644 --- a/ports/teensy/README.md +++ b/ports/teensy/README.md @@ -5,7 +5,7 @@ Currently the Teensy 3.1 port of MicroPython builds under Linux and not under Wi The tool chain required for the build can be found at . Download the current Linux *.tar.bz2 file. Instructions regarding unpacking the file and moving it to the correct location -as well as adding the extracted folders to the enviroment variable can be found at +as well as adding the extracted folders to the environment variable can be found at In order to download the firmware image to the teensy, you'll need to use the From a708848b0cb0f304f43178140d84d5535e186a38 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 27 Apr 2021 00:54:21 +0200 Subject: [PATCH 023/349] stm32/uart: Fix H7 UART clock source configuration. Previously to this commit, Usart16ClockSelection was overwritten and Usart234578ClockSelection was not set. --- ports/stm32/uart.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 36c59cee4a..babdf63d96 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -118,16 +118,10 @@ STATIC const pyb_uart_irq_map_t mp_uart_irq_map[] = { void uart_init0(void) { #if defined(STM32H7) RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit = {0}; - // Configure USART1/6 clock source - RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART16; + // Configure USART1/6 and USART2/3/4/5/7/8 clock sources + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART16 | RCC_PERIPHCLK_USART234578; RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; - if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { - __fatal_error("HAL_RCCEx_PeriphCLKConfig"); - } - - // Configure USART2/3/4/5/7/8 clock source - RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART234578; - RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; + RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { __fatal_error("HAL_RCCEx_PeriphCLKConfig"); } From 21fee92be6c534d0d44518c0c76f0c7cf5f64b18 Mon Sep 17 00:00:00 2001 From: Steve App Date: Sun, 25 Apr 2021 11:05:47 +0100 Subject: [PATCH 024/349] esp32: Restore FROZEN_MANIFEST support with new CMake build system. This commit re-enables the command-line make option "FROZEN_MANIFEST". The boards/*/mpconfigboard.cmake will now use the command-line FROZEN_MANIFEST value if supplied. Usage: make FROZEN_MANIFEST=~/foo/my-manifest.py --- ports/esp32/Makefile | 4 ++++ ports/esp32/boards/GENERIC/mpconfigboard.cmake | 5 +++-- ports/esp32/boards/GENERIC_D2WD/mpconfigboard.cmake | 4 +++- ports/esp32/boards/GENERIC_OTA/mpconfigboard.cmake | 4 +++- ports/esp32/boards/GENERIC_S2/mpconfigboard.cmake | 4 +++- ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake | 4 +++- ports/esp32/boards/TINYPICO/mpconfigboard.cmake | 4 +++- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 39b740ffae..5a40cd9569 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -26,6 +26,10 @@ endif IDFPY_FLAGS += -D MICROPY_BOARD=$(BOARD) -B $(BUILD) $(CMAKE_ARGS) +ifdef FROZEN_MANIFEST + IDFPY_FLAGS += -D MICROPY_FROZEN_MANIFEST=$(FROZEN_MANIFEST) +endif + all: idf.py $(IDFPY_FLAGS) build @$(PYTHON) makeimg.py \ diff --git a/ports/esp32/boards/GENERIC/mpconfigboard.cmake b/ports/esp32/boards/GENERIC/mpconfigboard.cmake index f69b05f47b..4aaa0420d9 100644 --- a/ports/esp32/boards/GENERIC/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC/mpconfigboard.cmake @@ -2,5 +2,6 @@ set(SDKCONFIG_DEFAULTS boards/sdkconfig.base boards/sdkconfig.ble ) - -set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_D2WD/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_D2WD/mpconfigboard.cmake index 686c78df97..729377a5b4 100644 --- a/ports/esp32/boards/GENERIC_D2WD/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC_D2WD/mpconfigboard.cmake @@ -4,4 +4,6 @@ set(SDKCONFIG_DEFAULTS boards/GENERIC_D2WD/sdkconfig.board ) -set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_OTA/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_OTA/mpconfigboard.cmake index ca552d470c..88c0efa218 100644 --- a/ports/esp32/boards/GENERIC_OTA/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC_OTA/mpconfigboard.cmake @@ -4,4 +4,6 @@ set(SDKCONFIG_DEFAULTS boards/GENERIC_OTA/sdkconfig.board ) -set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_S2/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_S2/mpconfigboard.cmake index 23d52e8b94..73f2b24e66 100644 --- a/ports/esp32/boards/GENERIC_S2/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC_S2/mpconfigboard.cmake @@ -5,4 +5,6 @@ set(SDKCONFIG_DEFAULTS boards/sdkconfig.usb ) -set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake index 2128edb592..bb38f7df2b 100644 --- a/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake +++ b/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake @@ -4,4 +4,6 @@ set(SDKCONFIG_DEFAULTS boards/sdkconfig.spiram ) -set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/TINYPICO/mpconfigboard.cmake b/ports/esp32/boards/TINYPICO/mpconfigboard.cmake index 5c31f5c600..0c65103a85 100644 --- a/ports/esp32/boards/TINYPICO/mpconfigboard.cmake +++ b/ports/esp32/boards/TINYPICO/mpconfigboard.cmake @@ -6,4 +6,6 @@ set(SDKCONFIG_DEFAULTS boards/TINYPICO/sdkconfig.board ) -set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) +endif() From 326dd7f0dbbadc4a536636d486600ce93dade8c5 Mon Sep 17 00:00:00 2001 From: Steve App Date: Sun, 25 Apr 2021 12:45:06 +0000 Subject: [PATCH 025/349] tools/makemanifest.py: Show directory name if there is a FreezeError. --- tools/makemanifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/makemanifest.py b/tools/makemanifest.py index 117d1536e8..51de01dd8a 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -199,7 +199,7 @@ def mkdir(filename): def freeze_internal(kind, path, script, opt): path = convert_path(path) if not os.path.isdir(path): - raise FreezeError("freeze path must be a directory") + raise FreezeError("freeze path must be a directory: {}".format(path)) if script is None and kind == KIND_AS_STR: if any(f[0] == KIND_AS_STR for f in manifest_list): raise FreezeError("can only freeze one str directory") From 89b64478c73d2228419e77a4450c004157ec725a Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 27 Apr 2021 16:30:58 +1000 Subject: [PATCH 026/349] stm32/softtimer: Add support for having a C-based callback. Signed-off-by: Damien George --- ports/stm32/machine_timer.c | 7 ++++--- ports/stm32/softtimer.c | 6 +++++- ports/stm32/softtimer.h | 10 ++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index c37ac87672..3f83d5ba61 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -76,10 +76,10 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar self->expiry_ms = mp_hal_ticks_ms() + self->delta_ms; if (args[ARG_callback].u_obj != MP_OBJ_NULL) { - self->callback = args[ARG_callback].u_obj; + self->py_callback = args[ARG_callback].u_obj; } - if (self->callback != mp_const_none) { + if (self->py_callback != mp_const_none) { soft_timer_insert(self); } @@ -89,8 +89,9 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t); self->pairheap.base.type = &machine_timer_type; + self->flags = SOFT_TIMER_FLAG_PY_CALLBACK; self->delta_ms = 1000; - self->callback = mp_const_none; + self->py_callback = mp_const_none; // Get timer id (only soft timer (-1) supported at the moment) mp_int_t id = -1; diff --git a/ports/stm32/softtimer.c b/ports/stm32/softtimer.c index d0a186c7d0..7e439d4e75 100644 --- a/ports/stm32/softtimer.c +++ b/ports/stm32/softtimer.c @@ -64,7 +64,11 @@ void soft_timer_handler(void) { while (heap != NULL && TICKS_DIFF(heap->expiry_ms, ticks_ms) <= 0) { soft_timer_entry_t *entry = heap; heap = (soft_timer_entry_t *)mp_pairheap_pop(soft_timer_lt, &heap->pairheap); - mp_sched_schedule(entry->callback, MP_OBJ_FROM_PTR(entry)); + if (entry->flags & SOFT_TIMER_FLAG_PY_CALLBACK) { + mp_sched_schedule(entry->py_callback, MP_OBJ_FROM_PTR(entry)); + } else { + entry->c_callback(entry); + } if (entry->mode == SOFT_TIMER_MODE_PERIODIC) { entry->expiry_ms += entry->delta_ms; heap = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &heap->pairheap, &entry->pairheap); diff --git a/ports/stm32/softtimer.h b/ports/stm32/softtimer.h index a80d9087b5..6e06bbcc65 100644 --- a/ports/stm32/softtimer.h +++ b/ports/stm32/softtimer.h @@ -28,15 +28,21 @@ #include "py/pairheap.h" +#define SOFT_TIMER_FLAG_PY_CALLBACK (1) + #define SOFT_TIMER_MODE_ONE_SHOT (1) #define SOFT_TIMER_MODE_PERIODIC (2) typedef struct _soft_timer_entry_t { mp_pairheap_t pairheap; - uint32_t mode; + uint16_t flags; + uint16_t mode; uint32_t expiry_ms; uint32_t delta_ms; // for periodic mode - mp_obj_t callback; + union { + void (*c_callback)(struct _soft_timer_entry_t *); + mp_obj_t py_callback; + }; } soft_timer_entry_t; extern volatile uint32_t soft_timer_next; From 647fa63f9c457b616b1b20fdd98403b681302680 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 29 Apr 2021 15:21:22 +1000 Subject: [PATCH 027/349] stm32/softtimer: Support static soft timer instances. This adds support for making static (ie not on the Python GC heap) soft timers. This can be useful for a board to define a custom background handler, or eventually for BLE/network processing to use instead of systick slots; it will be more efficient using soft timer for this. The main issue with using the existing code for static soft timers is that it would combine heap allocated and statically allocated soft_timer_entry_t instances in the same pairing-heap data structure. This would prevent the GC from tracing some of the heap allocated entries (because the GC won't follow pointers outside the heap). This commit makes it so that soft timer entries are explicitly marked, instead of relying on implicit marking by having the root of the pairing heap in the root pointer section. Also, on soft reset only the heap- allocated soft timers are deleted from the pairing heap, leaving the statically allocated ones. Signed-off-by: Damien George --- ports/stm32/gccollect.c | 4 +++ ports/stm32/machine_timer.c | 5 ++- ports/stm32/mpconfigport.h | 2 -- ports/stm32/softtimer.c | 65 +++++++++++++++++++++++++++++++------ ports/stm32/softtimer.h | 6 +++- 5 files changed, 66 insertions(+), 16 deletions(-) diff --git a/ports/stm32/gccollect.c b/ports/stm32/gccollect.c index ad5645738e..8b47b121ec 100644 --- a/ports/stm32/gccollect.c +++ b/ports/stm32/gccollect.c @@ -32,6 +32,7 @@ #include "py/mpthread.h" #include "lib/utils/gchelper.h" #include "gccollect.h" +#include "softtimer.h" #include "systick.h" void gc_collect(void) { @@ -51,6 +52,9 @@ void gc_collect(void) { mp_thread_gc_others(); #endif + // trace soft timer nodes + soft_timer_gc_mark_all(); + // end the GC gc_collect_end(); diff --git a/ports/stm32/machine_timer.c b/ports/stm32/machine_timer.c index 3f83d5ba61..c945322187 100644 --- a/ports/stm32/machine_timer.c +++ b/ports/stm32/machine_timer.c @@ -73,14 +73,13 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar mp_raise_ValueError(MP_ERROR_TEXT("period too large")); } self->delta_ms = (uint32_t)delta_ms; - self->expiry_ms = mp_hal_ticks_ms() + self->delta_ms; if (args[ARG_callback].u_obj != MP_OBJ_NULL) { self->py_callback = args[ARG_callback].u_obj; } if (self->py_callback != mp_const_none) { - soft_timer_insert(self); + soft_timer_insert(self, self->delta_ms); } return mp_const_none; @@ -89,7 +88,7 @@ STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_ar STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t); self->pairheap.base.type = &machine_timer_type; - self->flags = SOFT_TIMER_FLAG_PY_CALLBACK; + self->flags = SOFT_TIMER_FLAG_PY_CALLBACK | SOFT_TIMER_FLAG_GC_ALLOCATED; self->delta_ms = 1000; self->py_callback = mp_const_none; diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 2888cac88c..28a2d6a76d 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -371,8 +371,6 @@ struct _mp_bluetooth_btstack_root_pointers_t; \ mp_obj_t pyb_extint_callback[PYB_EXTI_NUM_VECTORS]; \ \ - struct _soft_timer_entry_t *soft_timer_heap; \ - \ /* pointers to all Timer objects (if they have been created) */ \ struct _pyb_timer_obj_t *pyb_timer_obj_all[MICROPY_HW_MAX_TIMER]; \ \ diff --git a/ports/stm32/softtimer.c b/ports/stm32/softtimer.c index 7e439d4e75..7f19eccd2d 100644 --- a/ports/stm32/softtimer.c +++ b/ports/stm32/softtimer.c @@ -25,6 +25,8 @@ */ #include +#include "py/gc.h" +#include "py/mphal.h" #include "py/runtime.h" #include "irq.h" #include "softtimer.h" @@ -36,9 +38,10 @@ extern __IO uint32_t uwTick; volatile uint32_t soft_timer_next; -void soft_timer_deinit(void) { - MP_STATE_PORT(soft_timer_heap) = NULL; -} +// Pointer to the pairheap of soft timer objects. +// This may contain bss/data pointers as well as GC-heap pointers, +// and is explicitly GC traced by soft_timer_gc_mark_all(). +STATIC soft_timer_entry_t *soft_timer_heap; STATIC int soft_timer_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) { soft_timer_entry_t *e1 = (soft_timer_entry_t *)n1; @@ -57,10 +60,26 @@ STATIC void soft_timer_schedule_systick(uint32_t ticks_ms) { enable_irq(irq_state); } +void soft_timer_deinit(void) { + // Pop off all the nodes which are allocated on the GC-heap. + uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV); + soft_timer_entry_t *heap_from = soft_timer_heap; + soft_timer_entry_t *heap_to = (soft_timer_entry_t *)mp_pairheap_new(soft_timer_lt); + while (heap_from != NULL) { + soft_timer_entry_t *entry = (soft_timer_entry_t *)mp_pairheap_peek(soft_timer_lt, &heap_from->pairheap); + heap_from = (soft_timer_entry_t *)mp_pairheap_pop(soft_timer_lt, &heap_from->pairheap); + if (!(entry->flags & SOFT_TIMER_FLAG_GC_ALLOCATED)) { + heap_to = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &heap_to->pairheap, &entry->pairheap); + } + } + soft_timer_heap = heap_to; + restore_irq_pri(irq_state); +} + // Must be executed at IRQ_PRI_PENDSV void soft_timer_handler(void) { uint32_t ticks_ms = uwTick; - soft_timer_entry_t *heap = MP_STATE_PORT(soft_timer_heap); + soft_timer_entry_t *heap = soft_timer_heap; while (heap != NULL && TICKS_DIFF(heap->expiry_ms, ticks_ms) <= 0) { soft_timer_entry_t *entry = heap; heap = (soft_timer_entry_t *)mp_pairheap_pop(soft_timer_lt, &heap->pairheap); @@ -74,7 +93,7 @@ void soft_timer_handler(void) { heap = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &heap->pairheap, &entry->pairheap); } } - MP_STATE_PORT(soft_timer_heap) = heap; + soft_timer_heap = heap; if (heap == NULL) { // No more timers left, set largest delay possible soft_timer_next = uwTick; @@ -84,11 +103,37 @@ void soft_timer_handler(void) { } } -void soft_timer_insert(soft_timer_entry_t *entry) { - mp_pairheap_init_node(soft_timer_lt, &entry->pairheap); +void soft_timer_gc_mark_all(void) { + // Mark all soft timer nodes that are allocated on the GC-heap. + // To avoid deep C recursion, pop and recreate the pairheap as nodes are marked. uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV); - MP_STATE_PORT(soft_timer_heap) = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &MP_STATE_PORT(soft_timer_heap)->pairheap, &entry->pairheap); - if (entry == MP_STATE_PORT(soft_timer_heap)) { + soft_timer_entry_t *heap_from = soft_timer_heap; + soft_timer_entry_t *heap_to = (soft_timer_entry_t *)mp_pairheap_new(soft_timer_lt); + while (heap_from != NULL) { + soft_timer_entry_t *entry = (soft_timer_entry_t *)mp_pairheap_peek(soft_timer_lt, &heap_from->pairheap); + heap_from = (soft_timer_entry_t *)mp_pairheap_pop(soft_timer_lt, &heap_from->pairheap); + if (entry->flags & SOFT_TIMER_FLAG_GC_ALLOCATED) { + gc_collect_root((void **)&entry, 1); + } + heap_to = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &heap_to->pairheap, &entry->pairheap); + } + soft_timer_heap = heap_to; + restore_irq_pri(irq_state); +} + +void soft_timer_static_init(soft_timer_entry_t *entry, uint16_t mode, uint32_t delta_ms, void (*cb)(soft_timer_entry_t *)) { + entry->flags = 0; + entry->mode = mode; + entry->delta_ms = delta_ms; + entry->c_callback = cb; +} + +void soft_timer_insert(soft_timer_entry_t *entry, uint32_t initial_delta_ms) { + mp_pairheap_init_node(soft_timer_lt, &entry->pairheap); + entry->expiry_ms = mp_hal_ticks_ms() + initial_delta_ms; + uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV); + soft_timer_heap = (soft_timer_entry_t *)mp_pairheap_push(soft_timer_lt, &soft_timer_heap->pairheap, &entry->pairheap); + if (entry == soft_timer_heap) { // This new timer became the earliest one so set soft_timer_next soft_timer_schedule_systick(entry->expiry_ms); } @@ -97,6 +142,6 @@ void soft_timer_insert(soft_timer_entry_t *entry) { void soft_timer_remove(soft_timer_entry_t *entry) { uint32_t irq_state = raise_irq_pri(IRQ_PRI_PENDSV); - MP_STATE_PORT(soft_timer_heap) = (soft_timer_entry_t *)mp_pairheap_delete(soft_timer_lt, &MP_STATE_PORT(soft_timer_heap)->pairheap, &entry->pairheap); + soft_timer_heap = (soft_timer_entry_t *)mp_pairheap_delete(soft_timer_lt, &soft_timer_heap->pairheap, &entry->pairheap); restore_irq_pri(irq_state); } diff --git a/ports/stm32/softtimer.h b/ports/stm32/softtimer.h index 6e06bbcc65..25d828a9fd 100644 --- a/ports/stm32/softtimer.h +++ b/ports/stm32/softtimer.h @@ -29,6 +29,7 @@ #include "py/pairheap.h" #define SOFT_TIMER_FLAG_PY_CALLBACK (1) +#define SOFT_TIMER_FLAG_GC_ALLOCATED (2) #define SOFT_TIMER_MODE_ONE_SHOT (1) #define SOFT_TIMER_MODE_PERIODIC (2) @@ -49,7 +50,10 @@ extern volatile uint32_t soft_timer_next; void soft_timer_deinit(void); void soft_timer_handler(void); -void soft_timer_insert(soft_timer_entry_t *entry); +void soft_timer_gc_mark_all(void); + +void soft_timer_static_init(soft_timer_entry_t *entry, uint16_t mode, uint32_t delta_ms, void (*cb)(soft_timer_entry_t *)); +void soft_timer_insert(soft_timer_entry_t *entry, uint32_t initial_delta_ms); void soft_timer_remove(soft_timer_entry_t *entry); #endif // MICROPY_INCLUDED_STM32_SOFTTIMER_H From a72b8443cae183ecd5396d3ae963984f4d2e1cdc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:30:17 +1000 Subject: [PATCH 028/349] stm32/boardctrl: Add constants for reset mode values. And use the same boardctrl.h header for both the application and mboot so these constants are consistent. Signed-off-by: Damien George --- ports/stm32/boardctrl.c | 18 ++++++++++-------- ports/stm32/boardctrl.h | 9 +++++++++ ports/stm32/main.c | 5 +++-- ports/stm32/mboot/main.c | 7 ++++--- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/ports/stm32/boardctrl.c b/ports/stm32/boardctrl.c index c82fefa97c..ce04914ea9 100644 --- a/ports/stm32/boardctrl.c +++ b/ports/stm32/boardctrl.c @@ -57,8 +57,8 @@ STATIC uint update_reset_mode(uint reset_mode) { } mp_hal_delay_ms(20); if (i % 30 == 29) { - if (++reset_mode > 3) { - reset_mode = 1; + if (++reset_mode > BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; } led_state(2, reset_mode & 1); led_state(3, reset_mode & 2); @@ -97,8 +97,8 @@ STATIC uint update_reset_mode(uint reset_mode) { if (!switch_get()) { break; } - if (++reset_mode > 3) { - reset_mode = 1; + if (++reset_mode > BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; } } // Flash the selected reset mode @@ -124,7 +124,7 @@ void boardctrl_before_soft_reset_loop(boardctrl_state_t *state) { #if !MICROPY_HW_USES_BOOTLOADER // Update the reset_mode via the default // method which uses the board switch/button and LEDs. - state->reset_mode = update_reset_mode(1); + state->reset_mode = update_reset_mode(BOARDCTRL_RESET_MODE_NORMAL); #endif } @@ -142,7 +142,8 @@ void boardctrl_top_soft_reset_loop(boardctrl_state_t *state) { } int boardctrl_run_boot_py(boardctrl_state_t *state) { - bool run_boot_py = state->reset_mode == 1 || state->reset_mode == 3; + bool run_boot_py = state->reset_mode == BOARDCTRL_RESET_MODE_NORMAL + || state->reset_mode == BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM; if (run_boot_py) { // Run boot.py, if it exists. @@ -174,7 +175,8 @@ int boardctrl_run_boot_py(boardctrl_state_t *state) { } int boardctrl_run_main_py(boardctrl_state_t *state) { - bool run_main_py = (state->reset_mode == 1 || state->reset_mode == 3) + bool run_main_py = (state->reset_mode == BOARDCTRL_RESET_MODE_NORMAL + || state->reset_mode == BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL; if (run_main_py) { @@ -205,5 +207,5 @@ void boardctrl_start_soft_reset(boardctrl_state_t *state) { void boardctrl_end_soft_reset(boardctrl_state_t *state) { // Set reset_mode to normal boot. - state->reset_mode = 1; + state->reset_mode = BOARDCTRL_RESET_MODE_NORMAL; } diff --git a/ports/stm32/boardctrl.h b/ports/stm32/boardctrl.h index 33e71b65c9..551be3453e 100644 --- a/ports/stm32/boardctrl.h +++ b/ports/stm32/boardctrl.h @@ -60,11 +60,20 @@ #define MICROPY_BOARD_END_SOFT_RESET boardctrl_end_soft_reset #endif +// Constants to return from boardctrl_run_boot_py, boardctrl_run_main_py. enum { BOARDCTRL_CONTINUE, BOARDCTRL_GOTO_SOFT_RESET_EXIT, }; +// Constants for boardctrl_state_t.reset_mode. +enum { + BOARDCTRL_RESET_MODE_NORMAL = 1, + BOARDCTRL_RESET_MODE_SAFE_MODE = 2, + BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM = 3, + BOARDCTRL_RESET_MODE_BOOTLOADER = 4, +}; + typedef struct _boardctrl_state_t { uint8_t reset_mode; bool log_soft_reset; diff --git a/ports/stm32/main.c b/ports/stm32/main.c index bc8e6f0691..ca80daaceb 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -156,7 +156,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pyb_main_obj, 1, pyb_main); #if MICROPY_HW_FLASH_MOUNT_AT_BOOT // avoid inlining to avoid stack usage within main() MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) { - if (reset_mode == 3) { + if (reset_mode == BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { // Asked by user to reset filesystem factory_reset_create_filesystem(); } @@ -210,7 +210,8 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) { mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash); ret = mp_vfs_mount_and_chdir_protected(bdev, mount_point); - if (ret == -MP_ENODEV && bdev == MP_OBJ_FROM_PTR(&pyb_flash_obj) && reset_mode != 3) { + if (ret == -MP_ENODEV && bdev == MP_OBJ_FROM_PTR(&pyb_flash_obj) + && reset_mode != BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { // No filesystem, bdev is still the default (so didn't detect a possibly corrupt littlefs), // and didn't already create a filesystem, so try to create a fresh one now. ret = factory_reset_create_filesystem(); diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 4407ca9da9..a77060ab2b 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -29,6 +29,7 @@ #include "py/mphal.h" #include "extmod/crypto-algorithms/sha256.c" +#include "boardctrl.h" #include "usbd_core.h" #include "storage.h" #include "flash.h" @@ -1289,7 +1290,7 @@ static int pyb_usbdd_shutdown(void) { static int get_reset_mode(void) { usrbtn_init(); - int reset_mode = 1; + int reset_mode = BOARDCTRL_RESET_MODE_NORMAL; if (usrbtn_state()) { // Cycle through reset modes while USR is held // Timeout is roughly 20s, where reset_mode=1 @@ -1299,7 +1300,7 @@ static int get_reset_mode(void) { for (int i = 0; i < (RESET_MODE_NUM_STATES * RESET_MODE_TIMEOUT_CYCLES + 1) * 32; i++) { if (i % 32 == 0) { if (++reset_mode > RESET_MODE_NUM_STATES) { - reset_mode = 1; + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; } uint8_t l = RESET_MODE_LED_STATES >> ((reset_mode - 1) * 4); led_state_all(l); @@ -1396,7 +1397,7 @@ void stm32_main(int initial_r0) { int reset_mode = get_reset_mode(); uint32_t msp = *(volatile uint32_t*)APPLICATION_ADDR; - if (reset_mode != 4 && (msp & APP_VALIDITY_BITS) == 0) { + if (reset_mode != BOARDCTRL_RESET_MODE_BOOTLOADER && (msp & APP_VALIDITY_BITS) == 0) { // not DFU mode so jump to application, passing through reset_mode // undo our DFU settings // TODO probably should disable all IRQ sources first From 885b246ca91592ba48637a8519dd4fbd576ad38a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 29 Apr 2021 23:48:58 +1000 Subject: [PATCH 029/349] stm32/boardctrl: Show first reset-mode state on LEDs when selecting. Commit 1e297c88989592258965b69cb740039e26c7636c introduced a bug where the very first reset-mode state on the LEDs was not shown, because prior to that commit the first reset-mode state was the same as the initial LED state (green on, others off) and update_reset_mode() was called after setting this initial LED state. This is fixed in this commit by changing the update_reset_mode() loop so that it displays the current reset mode before doing the delay. Signed-off-by: Damien George --- ports/stm32/boardctrl.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ports/stm32/boardctrl.c b/ports/stm32/boardctrl.c index ce04914ea9..8cc519d8e9 100644 --- a/ports/stm32/boardctrl.c +++ b/ports/stm32/boardctrl.c @@ -51,20 +51,21 @@ STATIC uint update_reset_mode(uint reset_mode) { // The original method used on the pyboard is appropriate if you have 2 // or more LEDs. #if defined(MICROPY_HW_LED2) - for (uint i = 0; i < 3000; i++) { - if (!switch_get()) { - break; - } - mp_hal_delay_ms(20); - if (i % 30 == 29) { - if (++reset_mode > BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { - reset_mode = BOARDCTRL_RESET_MODE_NORMAL; + for (uint i = 0; i < 100; i++) { + led_state(2, reset_mode & 1); + led_state(3, reset_mode & 2); + led_state(4, reset_mode & 4); + for (uint j = 0; j < 30; ++j) { + mp_hal_delay_ms(20); + if (!switch_get()) { + goto select_mode; } - led_state(2, reset_mode & 1); - led_state(3, reset_mode & 2); - led_state(4, reset_mode & 4); + } + if (++reset_mode > BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) { + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; } } + select_mode: // flash the selected reset mode for (uint i = 0; i < 6; i++) { led_state(2, 0); From ef2896bdeacdfa3f6dc9faaa3f9c0f3d9bef291b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:10:42 +1000 Subject: [PATCH 030/349] stm32/mboot: Allow a board to add source files to the build. A board can now use BUILDING_MBOOT at the Makefile-level to do things conditional on building mboot, for example add source files to SRC_C. Signed-off-by: Damien George --- ports/stm32/mboot/Makefile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index 0c92442597..534622c030 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -23,6 +23,9 @@ ifeq ($(wildcard $(BOARD_DIR)/.),) $(error Invalid BOARD specified: $(BOARD_DIR)) endif +# Enable BUILDING_MBOOT so boards can configure their .mk file accordingly. +BUILDING_MBOOT = 1 + include ../../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk @@ -78,7 +81,7 @@ CFLAGS += -DAPPLICATION_ADDR=$(TEXT0_ADDR) CFLAGS += -DFFCONF_H=\"ports/stm32/mboot/ffconf.h\" CFLAGS += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT CFLAGS += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT -DLFS2_READONLY -CFLAGS += -DBUILDING_MBOOT=1 +CFLAGS += -DBUILDING_MBOOT=$(BUILDING_MBOOT) CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0 CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID) @@ -98,7 +101,7 @@ COPT += -Os -DNDEBUG endif $(BUILD)/lib/libc/string0.o: CFLAGS += $(CFLAGS_BUILTIN) -LIB_SRC_C = \ +LIB_SRC_C += \ lib/libc/string0.c \ lib/littlefs/lfs1.c \ lib/littlefs/lfs1_util.c \ @@ -111,7 +114,7 @@ LIB_SRC_C = \ extmod/uzlib/tinflate.c \ extmod/uzlib/tinfgzip.c -SRC_C = \ +SRC_C += \ main.c \ elem.c \ fsload.c \ @@ -131,7 +134,7 @@ SRC_C = \ ports/stm32/usbd_conf.c \ $(wildcard $(BOARD_DIR)/*.c) -SRC_O = \ +SRC_O += \ $(STARTUP_FILE) \ $(SYSTEM_FILE) \ ports/stm32/resethandler.o \ @@ -146,7 +149,7 @@ CFLAGS += -DMBOOT_PACK_KEYS_FILE=\"$(MBOOT_PACK_KEYS_FILE)\" endif $(BUILD)/$(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_ll_usb.o: CFLAGS += -Wno-attributes -SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ +SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ hal_cortex.c \ hal_flash.c \ hal_flash_ex.c \ @@ -155,13 +158,12 @@ SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\ ll_usb.c \ ) -SRC_USBDEV = $(addprefix ports/stm32/$(USBDEV_DIR)/,\ +SRC_USBDEV += $(addprefix ports/stm32/$(USBDEV_DIR)/,\ core/src/usbd_core.c \ core/src/usbd_ctlreq.c \ core/src/usbd_ioreq.c \ ) -OBJ = OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_O)) From fd01b6c779d39eae1aaa0f038b4ec15d86db44fe Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:12:07 +1000 Subject: [PATCH 031/349] stm32/adc: Allow mboot to use basic ADC functions. Signed-off-by: Damien George --- ports/stm32/adc.h | 5 +++++ ports/stm32/machine_adc.c | 8 ++++++-- ports/stm32/mboot/Makefile | 1 + ports/stm32/mboot/mphalport.h | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h index 6f2e61e099..64864b1967 100644 --- a/ports/stm32/adc.h +++ b/ports/stm32/adc.h @@ -26,8 +26,13 @@ #ifndef MICROPY_INCLUDED_STM32_ADC_H #define MICROPY_INCLUDED_STM32_ADC_H +#if !BUILDING_MBOOT extern const mp_obj_type_t pyb_adc_type; extern const mp_obj_type_t pyb_adc_all_type; +#endif + +void adc_config(ADC_TypeDef *adc, uint32_t bits); +uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint32_t sample_time); #if defined(ADC_CHANNEL_VBAT) diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index d9e5a64da5..f28bd5b398 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -96,7 +96,7 @@ STATIC const uint8_t adc_cr_to_bits_table[] = {16, 14, 12, 10, 8, 8, 8, 8}; STATIC const uint8_t adc_cr_to_bits_table[] = {12, 10, 8, 6}; #endif -STATIC void adc_config(ADC_TypeDef *adc, uint32_t bits) { +void adc_config(ADC_TypeDef *adc, uint32_t bits) { // Configure ADC clock source and enable ADC clock #if defined(STM32L4) || defined(STM32WB) __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK); @@ -331,7 +331,7 @@ STATIC uint32_t adc_read_channel(ADC_TypeDef *adc) { return value; } -STATIC uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint32_t sample_time) { +uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint32_t sample_time) { if (channel == ADC_CHANNEL_VREF) { return 0xffff; } @@ -357,6 +357,8 @@ STATIC uint32_t adc_config_and_read_u16(ADC_TypeDef *adc, uint32_t channel, uint /******************************************************************************/ // MicroPython bindings for machine.ADC +#if !BUILDING_MBOOT + const mp_obj_type_t machine_adc_type; typedef struct _machine_adc_obj_t { @@ -462,3 +464,5 @@ const mp_obj_type_t machine_adc_type = { .make_new = machine_adc_make_new, .locals_dict = (mp_obj_dict_t *)&machine_adc_locals_dict, }; + +#endif diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index 534622c030..d57b9368ee 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -128,6 +128,7 @@ SRC_C += \ ports/stm32/flash.c \ ports/stm32/flashbdev.c \ ports/stm32/i2cslave.c \ + ports/stm32/machine_adc.c \ ports/stm32/powerctrlboot.c \ ports/stm32/qspi.c \ ports/stm32/spibdev.c \ diff --git a/ports/stm32/mboot/mphalport.h b/ports/stm32/mboot/mphalport.h index 56d18a9b05..ab0bc1587c 100644 --- a/ports/stm32/mboot/mphalport.h +++ b/ports/stm32/mboot/mphalport.h @@ -39,6 +39,11 @@ static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) { #define MP_HAL_PIN_MODE_OUTPUT (1) #define MP_HAL_PIN_MODE_ALT (2) #define MP_HAL_PIN_MODE_ANALOG (3) +#if defined(GPIO_ASCR_ASC0) +#define MP_HAL_PIN_MODE_ADC (11) +#else +#define MP_HAL_PIN_MODE_ADC (3) +#endif #define MP_HAL_PIN_MODE_OPEN_DRAIN (5) #define MP_HAL_PIN_MODE_ALT_OPEN_DRAIN (6) #define MP_HAL_PIN_PULL_NONE (GPIO_NOPULL) From 97f09fda3e00b4da11bed3d7fb3d83d89deeeafb Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:21:38 +1000 Subject: [PATCH 032/349] stm32/mboot: Fix mp_hal_delay_us() and add mp_hal_ticks_ms(). Signed-off-by: Damien George --- ports/stm32/mboot/main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index a77060ab2b..c82e460faf 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -95,6 +95,9 @@ // These bits are used to detect valid application firmware at APPLICATION_ADDR #define APP_VALIDITY_BITS (0x00000003) +// For 1ms system ticker. +static volatile uint32_t systick_ms; + // Global dfu state dfu_context_t dfu_context SECTION_NOZERO_BSS; @@ -104,6 +107,10 @@ uint32_t get_le32(const uint8_t *b) { return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24; } +mp_uint_t mp_hal_ticks_ms(void) { + return systick_ms; +} + void mp_hal_delay_us(mp_uint_t usec) { // use a busy loop for the delay // sys freq is always a multiple of 2MHz, so division here won't lose precision @@ -113,11 +120,10 @@ void mp_hal_delay_us(mp_uint_t usec) { const uint32_t ucount = SystemCoreClock / 2000000 * usec / 2; #endif for (uint32_t count = 0; ++count <= ucount;) { + __NOP(); } } -static volatile uint32_t systick_ms; - void mp_hal_delay_ms(mp_uint_t ms) { if (__get_PRIMASK() == 0) { // IRQs enabled, use systick From 58be5a5aa328e687a3560d4a85fb069400b0b8ca Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:26:20 +1000 Subject: [PATCH 033/349] stm32/mboot: Allow a board to customise the linker scripts. A board can now define MBOOT_LD_FILES (at the Makefile-level) to specify custom linker scripts. And stm32_generic.ld has been split into 2 pieces so one or the other can be reused (usually stm32_sections.ld wolud be reused by a board, and stm32_memory.ld redefined). Signed-off-by: Damien George --- ports/stm32/mboot/Makefile | 3 ++- ports/stm32/mboot/stm32_memory.ld | 10 ++++++++++ .../mboot/{stm32_generic.ld => stm32_sections.ld} | 10 ++-------- 3 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 ports/stm32/mboot/stm32_memory.ld rename ports/stm32/mboot/{stm32_generic.ld => stm32_sections.ld} (87%) diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index d57b9368ee..de090da1c6 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -85,7 +85,8 @@ CFLAGS += -DBUILDING_MBOOT=$(BUILDING_MBOOT) CFLAGS += -DMICROPY_HW_STM32WB_FLASH_SYNCRONISATION=0 CFLAGS += -DBOOTLOADER_DFU_USB_VID=$(BOOTLOADER_DFU_USB_VID) -DBOOTLOADER_DFU_USB_PID=$(BOOTLOADER_DFU_USB_PID) -LDFLAGS = -nostdlib -L . -T stm32_generic.ld -Map=$(@:.elf=.map) --cref +MBOOT_LD_FILES ?= stm32_memory.ld stm32_sections.ld +LDFLAGS = -nostdlib -L . $(addprefix -T,$(MBOOT_LD_FILES)) -Map=$(@:.elf=.map) --cref LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Remove uncalled code from the final image. diff --git a/ports/stm32/mboot/stm32_memory.ld b/ports/stm32/mboot/stm32_memory.ld new file mode 100644 index 0000000000..cfcac4096b --- /dev/null +++ b/ports/stm32/mboot/stm32_memory.ld @@ -0,0 +1,10 @@ +/* + Linker script fragment for mboot on an STM32xxx MCU. + This defines the memory sections for the bootloader to use. +*/ + +MEMORY +{ + FLASH_BL (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 120K +} diff --git a/ports/stm32/mboot/stm32_generic.ld b/ports/stm32/mboot/stm32_sections.ld similarity index 87% rename from ports/stm32/mboot/stm32_generic.ld rename to ports/stm32/mboot/stm32_sections.ld index ade4349674..3302c5f972 100644 --- a/ports/stm32/mboot/stm32_generic.ld +++ b/ports/stm32/mboot/stm32_sections.ld @@ -1,14 +1,8 @@ /* - GNU linker script for generic STM32xxx MCU + Linker script fragment for mboot on an STM32xxx MCU. + This needs the following MEMORY sections to be defined: FLASH_BL, RAM. */ -/* Specify the memory areas */ -MEMORY -{ - FLASH_BL (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sector 0 (can be 32K) */ - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 120K -} - /* produce a link error if there is not this amount of RAM for these sections */ _minimum_stack_size = 8K; From 37494b8c8a3e61612081aa737997201e7b24b536 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:45:51 +1000 Subject: [PATCH 034/349] stm32/mboot: Allow mboot to be placed at any location in flash. A board can now define MBOOT_TEXT0_ADDR to place mboot at a location other than 0x08000000. This can be useful if, for example, there is already a different bootloader on the device. Signed-off-by: Damien George --- ports/stm32/Makefile | 5 +++++ ports/stm32/mboot/Makefile | 10 ++++++---- ports/stm32/mboot/main.c | 2 +- ports/stm32/modmachine.c | 6 +++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index e7a8f0aee6..e94e7d72f3 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -27,6 +27,10 @@ MICROPY_ROM_TEXT_COMPRESSION ?= 1 # File containing description of content to be frozen into firmware. FROZEN_MANIFEST ?= boards/manifest.py +# Location of mboot (or other bootloader) if the device has one. +# Used by machine.bootloader(). +MBOOT_TEXT0_ADDR ?= 0x08000000 + # include py core make definitions include $(TOP)/py/py.mk @@ -101,6 +105,7 @@ CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(COPT) CFLAGS += -I$(BOARD_DIR) CFLAGS += -DSTM32_HAL_H='' +CFLAGS += -DMBOOT_VTOR=$(MBOOT_TEXT0_ADDR) CFLAGS += -DMICROPY_HW_VTOR=$(TEXT0_ADDR) # Configure for nan-boxing object model if requested diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile index de090da1c6..17de685a61 100755 --- a/ports/stm32/mboot/Makefile +++ b/ports/stm32/mboot/Makefile @@ -29,6 +29,9 @@ BUILDING_MBOOT = 1 include ../../../py/mkenv.mk include $(BOARD_DIR)/mpconfigboard.mk +# A board can set MBOOT_TEXT0_ADDR to a custom location where mboot should reside. +MBOOT_TEXT0_ADDR ?= 0x08000000 + MCU_SERIES_UPPER = $(shell echo $(MCU_SERIES) | tr '[:lower:]' '[:upper:]') CMSIS_MCU_LOWER = $(shell echo $(CMSIS_MCU) | tr '[:upper:]' '[:lower:]') @@ -77,6 +80,7 @@ CFLAGS += $(COPT) CFLAGS += -I$(BOARD_DIR) CFLAGS += -DSTM32_HAL_H='' CFLAGS += -DBOARD_$(BOARD) +CFLAGS += -DMBOOT_VTOR=$(MBOOT_TEXT0_ADDR) CFLAGS += -DAPPLICATION_ADDR=$(TEXT0_ADDR) CFLAGS += -DFFCONF_H=\"ports/stm32/mboot/ffconf.h\" CFLAGS += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT @@ -181,20 +185,18 @@ $(TOP)/lib/stm32lib/README.md: .PHONY: deploy deploy-stlink -FLASH_ADDR = 0x08000000 - deploy: $(BUILD)/firmware.dfu $(ECHO) "Writing $< to the board" $(Q)$(PYTHON) $(PYDFU) -u $< deploy-stlink: $(BUILD)/firmware.dfu $(ECHO) "Writing $< to the board via ST-LINK" - $(Q)$(STFLASH) write $(BUILD)/firmware.bin $(FLASH_ADDR) + $(Q)$(STFLASH) write $(BUILD)/firmware.bin $(MBOOT_TEXT0_ADDR) $(BUILD)/firmware.dfu: $(BUILD)/firmware.elf $(ECHO) "Create $@" $(Q)$(OBJCOPY) -O binary -j .isr_vector -j .text -j .data $^ $(BUILD)/firmware.bin - $(Q)$(PYTHON) $(DFU) -b $(FLASH_ADDR):$(BUILD)/firmware.bin $@ + $(Q)$(PYTHON) $(DFU) -b $(MBOOT_TEXT0_ADDR):$(BUILD)/firmware.bin $@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf $(ECHO) "Create $@" diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index c82e460faf..36b6890361 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -1358,7 +1358,7 @@ void stm32_main(int initial_r0) { #endif // Make sure IRQ vector table points to flash where this bootloader lives. - SCB->VTOR = FLASH_BASE; + SCB->VTOR = MBOOT_VTOR; // Enable 8-byte stack alignment for IRQ handlers, in accord with EABI SCB->CCR |= SCB_CCR_STKALIGN_Msk; diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index f9fd1d9a64..aee563ee88 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -270,16 +270,16 @@ STATIC NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args) #if MICROPY_HW_USES_BOOTLOADER if (n_args == 0 || !mp_obj_is_true(args[0])) { // By default, with no args given, we enter the custom bootloader (mboot) - powerctrl_enter_bootloader(0x70ad0000, 0x08000000); + powerctrl_enter_bootloader(0x70ad0000, MBOOT_VTOR); } if (n_args == 1 && mp_obj_is_str_or_bytes(args[0])) { // With a string/bytes given, pass its data to the custom bootloader size_t len; const char *data = mp_obj_str_get_data(args[0], &len); - void *mboot_region = (void *)*((volatile uint32_t *)0x08000000); + void *mboot_region = (void *)*((volatile uint32_t *)MBOOT_VTOR); memmove(mboot_region, data, len); - powerctrl_enter_bootloader(0x70ad0080, 0x08000000); + powerctrl_enter_bootloader(0x70ad0080, MBOOT_VTOR); } #endif From cf7e71fa4377e30c8612fa19032ae3004670c7e3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 29 Apr 2021 12:08:20 +1000 Subject: [PATCH 035/349] stm32/sdcard: Allow configuring the SDMMC periph used for SD/MMC card. This can now be selected by setting MICROPY_HW_SDCARD_SDMMC, which defaults to 1, ie SDMMC1. This commit also renames the SD pin configuration macros from MICROPY_HW_SDMMC2_xxx to MICROPY_HW_SDCARD_xxx, as well as renaming MICROPY_HW_SDMMC_BUS_WIDTH to MICROPY_HW_SDCARD_BUS_WIDTH. Signed-off-by: Damien George --- ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 13 +-- .../boards/STM32F769DISC/mpconfigboard.h | 15 +-- ports/stm32/mpconfigboard_common.h | 20 +++- ports/stm32/sdcard.c | 97 ++++++++----------- 4 files changed, 75 insertions(+), 70 deletions(-) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index dc42751fff..7d89e17cf4 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -165,12 +165,13 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) // SD card -#define MICROPY_HW_SDMMC2_CK (pyb_pin_SD_CK) -#define MICROPY_HW_SDMMC2_CMD (pyb_pin_SD_CMD) -#define MICROPY_HW_SDMMC2_D0 (pyb_pin_SD_D0) -#define MICROPY_HW_SDMMC2_D1 (pyb_pin_SD_D1) -#define MICROPY_HW_SDMMC2_D2 (pyb_pin_SD_D2) -#define MICROPY_HW_SDMMC2_D3 (pyb_pin_SD_D3) +#define MICROPY_HW_SDCARD_SDMMC (2) +#define MICROPY_HW_SDCARD_CK (pyb_pin_SD_CK) +#define MICROPY_HW_SDCARD_CMD (pyb_pin_SD_CMD) +#define MICROPY_HW_SDCARD_D0 (pyb_pin_SD_D0) +#define MICROPY_HW_SDCARD_D1 (pyb_pin_SD_D1) +#define MICROPY_HW_SDCARD_D2 (pyb_pin_SD_D2) +#define MICROPY_HW_SDCARD_D3 (pyb_pin_SD_D3) #define MICROPY_HW_SDCARD_DETECT_PIN (pyb_pin_SD_SW) #define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) #define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h index 843b987cee..5004a8ecac 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h @@ -90,13 +90,14 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) -// SD card detect switch -#define MICROPY_HW_SDMMC2_CK (pin_D6) -#define MICROPY_HW_SDMMC2_CMD (pin_D7) -#define MICROPY_HW_SDMMC2_D0 (pin_G9) -#define MICROPY_HW_SDMMC2_D1 (pin_G10) -#define MICROPY_HW_SDMMC2_D2 (pin_B3) -#define MICROPY_HW_SDMMC2_D3 (pin_B4) +// SD card +#define MICROPY_HW_SDCARD_SDMMC (2) +#define MICROPY_HW_SDCARD_CK (pin_D6) +#define MICROPY_HW_SDCARD_CMD (pin_D7) +#define MICROPY_HW_SDCARD_D0 (pin_G9) +#define MICROPY_HW_SDCARD_D1 (pin_G10) +#define MICROPY_HW_SDCARD_D2 (pin_B3) +#define MICROPY_HW_SDCARD_D3 (pin_B4) #define MICROPY_HW_SDCARD_DETECT_PIN (pin_I15) #define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) #define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 6fb9289e00..37ce8bbf19 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -107,9 +107,14 @@ #define MICROPY_HW_ENABLE_MMCARD (0) #endif -// SD/MMC interface bus width (defaults to 4 bits) -#ifndef MICROPY_HW_SDMMC_BUS_WIDTH -#define MICROPY_HW_SDMMC_BUS_WIDTH (4) +// Which SDMMC peripheral to use for the SD/MMC card driver (1 or 2) +#ifndef MICROPY_HW_SDCARD_SDMMC +#define MICROPY_HW_SDCARD_SDMMC (1) +#endif + +// SD/MMC card driver interface bus width (defaults to 4 bits) +#ifndef MICROPY_HW_SDCARD_BUS_WIDTH +#define MICROPY_HW_SDCARD_BUS_WIDTH (4) #endif // Whether to automatically mount (and boot from) the SD card if it's present @@ -383,6 +388,15 @@ #define MICROPY_HW_MAX_CAN (1) #endif +// Define MICROPY_HW_SDMMCx_CK values if that peripheral is used, so that make-pins.py +// generates the relevant AF constants. +#if MICROPY_HW_SDCARD_SDMMC == 1 +#define MICROPY_HW_SDMMC1_CK (1) +#endif +#if MICROPY_HW_SDCARD_SDMMC == 2 +#define MICROPY_HW_SDMMC2_CK (1) +#endif + // Whether the USB peripheral is device-only, or multiple OTG #if defined(STM32L0) || defined(STM32L432xx) || defined(STM32WB) #define MICROPY_HW_USB_IS_MULTI_OTG (0) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index b255ee82ca..ea69e7285b 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -42,30 +42,39 @@ #if defined(STM32F7) || defined(STM32H7) || defined(STM32L4) -// The F7 has 2 SDMMC units but at the moment we only support using one of them in -// a given build. If a boards config file defines MICROPY_HW_SDMMC2_CK then SDMMC2 -// is used, otherwise SDMMC1 is used. +// The H7/F7/L4 have 2 SDMMC peripherals, but at the moment this driver only supports +// using one of them in a given build, selected by MICROPY_HW_SDCARD_SDMMC. -#if defined(MICROPY_HW_SDMMC2_CK) +#if MICROPY_HW_SDCARD_SDMMC == 2 #define SDIO SDMMC2 #define SDMMC_IRQHandler SDMMC2_IRQHandler #define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC2_CLK_ENABLE() #define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC2_CLK_DISABLE() +#define SDMMC_FORCE_RESET() __HAL_RCC_SDMMC2_FORCE_RESET() +#define SDMMC_RELEASE_RESET() __HAL_RCC_SDMMC2_RELEASE_RESET() #define SDMMC_IRQn SDMMC2_IRQn #define SDMMC_DMA dma_SDMMC_2 +#define STATIC_AF_SDCARD_CK STATIC_AF_SDMMC2_CK +#define STATIC_AF_SDCARD_CMD STATIC_AF_SDMMC2_CMD +#define STATIC_AF_SDCARD_D0 STATIC_AF_SDMMC2_D0 +#define STATIC_AF_SDCARD_D1 STATIC_AF_SDMMC2_D1 +#define STATIC_AF_SDCARD_D2 STATIC_AF_SDMMC2_D2 +#define STATIC_AF_SDCARD_D3 STATIC_AF_SDMMC2_D3 #else #define SDIO SDMMC1 #define SDMMC_IRQHandler SDMMC1_IRQHandler #define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE() #define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE() +#define SDMMC_FORCE_RESET() __HAL_RCC_SDMMC1_FORCE_RESET() +#define SDMMC_RELEASE_RESET() __HAL_RCC_SDMMC1_RELEASE_RESET() #define SDMMC_IRQn SDMMC1_IRQn #define SDMMC_DMA dma_SDIO_0 -#define STATIC_AF_SDMMC_CK STATIC_AF_SDMMC1_CK -#define STATIC_AF_SDMMC_CMD STATIC_AF_SDMMC1_CMD -#define STATIC_AF_SDMMC_D0 STATIC_AF_SDMMC1_D0 -#define STATIC_AF_SDMMC_D1 STATIC_AF_SDMMC1_D1 -#define STATIC_AF_SDMMC_D2 STATIC_AF_SDMMC1_D2 -#define STATIC_AF_SDMMC_D3 STATIC_AF_SDMMC1_D3 +#define STATIC_AF_SDCARD_CK STATIC_AF_SDMMC1_CK +#define STATIC_AF_SDCARD_CMD STATIC_AF_SDMMC1_CMD +#define STATIC_AF_SDCARD_D0 STATIC_AF_SDMMC1_D0 +#define STATIC_AF_SDCARD_D1 STATIC_AF_SDMMC1_D1 +#define STATIC_AF_SDCARD_D2 STATIC_AF_SDMMC1_D2 +#define STATIC_AF_SDCARD_D3 STATIC_AF_SDMMC1_D3 #endif // The F7 & L4 series calls the peripheral SDMMC rather than SDIO, so provide some @@ -105,25 +114,23 @@ #define SDMMC_IRQHandler SDIO_IRQHandler #define SDMMC_DMA dma_SDIO_0 #define SDIO_USE_GPDMA 1 -#define STATIC_AF_SDMMC_CK STATIC_AF_SDIO_CK -#define STATIC_AF_SDMMC_CMD STATIC_AF_SDIO_CMD -#define STATIC_AF_SDMMC_D0 STATIC_AF_SDIO_D0 -#define STATIC_AF_SDMMC_D1 STATIC_AF_SDIO_D1 -#define STATIC_AF_SDMMC_D2 STATIC_AF_SDIO_D2 -#define STATIC_AF_SDMMC_D3 STATIC_AF_SDIO_D3 +#define STATIC_AF_SDCARD_CK STATIC_AF_SDIO_CK +#define STATIC_AF_SDCARD_CMD STATIC_AF_SDIO_CMD +#define STATIC_AF_SDCARD_D0 STATIC_AF_SDIO_D0 +#define STATIC_AF_SDCARD_D1 STATIC_AF_SDIO_D1 +#define STATIC_AF_SDCARD_D2 STATIC_AF_SDIO_D2 +#define STATIC_AF_SDCARD_D3 STATIC_AF_SDIO_D3 #endif // If no custom SDIO pins defined, use the default ones -#ifndef MICROPY_HW_SDMMC_CK - -#define MICROPY_HW_SDMMC_D0 (pin_C8) -#define MICROPY_HW_SDMMC_D1 (pin_C9) -#define MICROPY_HW_SDMMC_D2 (pin_C10) -#define MICROPY_HW_SDMMC_D3 (pin_C11) -#define MICROPY_HW_SDMMC_CK (pin_C12) -#define MICROPY_HW_SDMMC_CMD (pin_D2) - +#ifndef MICROPY_HW_SDCARD_CK +#define MICROPY_HW_SDCARD_D0 (pin_C8) +#define MICROPY_HW_SDCARD_D1 (pin_C9) +#define MICROPY_HW_SDCARD_D2 (pin_C10) +#define MICROPY_HW_SDCARD_D3 (pin_C11) +#define MICROPY_HW_SDCARD_CK (pin_C12) +#define MICROPY_HW_SDCARD_CMD (pin_D2) #endif #define PYB_SDMMC_FLAG_SD (0x01) @@ -152,26 +159,13 @@ void sdcard_init(void) { // Note: the mp_hal_pin_config function will configure the GPIO in // fast mode which can do up to 50MHz. This should be plenty for SDIO // which clocks up to 25MHz maximum. - #if defined(MICROPY_HW_SDMMC2_CK) - // Use SDMMC2 peripheral with pins provided by the board's config - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_CK); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_CMD); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_D0); - #if MICROPY_HW_SDMMC_BUS_WIDTH == 4 - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_D1); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_D2); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC2_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC2_D3); - #endif - #else - // Default SDIO/SDMMC1 config - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_CK); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_CMD); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D0); - #if MICROPY_HW_SDMMC_BUS_WIDTH == 4 - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D1); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D2); - mp_hal_pin_config_alt_static(MICROPY_HW_SDMMC_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D3); - #endif + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_CK); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_CMD); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D0); + #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D1); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D2); + mp_hal_pin_config_alt_static(MICROPY_HW_SDCARD_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDCARD_D3); #endif // configure the SD card detect pin @@ -187,13 +181,8 @@ STATIC void sdmmc_msp_init(void) { #if defined(STM32H7) // Reset SDMMC - #if defined(MICROPY_HW_SDMMC2_CK) - __HAL_RCC_SDMMC2_FORCE_RESET(); - __HAL_RCC_SDMMC2_RELEASE_RESET(); - #else - __HAL_RCC_SDMMC1_FORCE_RESET(); - __HAL_RCC_SDMMC1_RELEASE_RESET(); - #endif + SDMMC_FORCE_RESET(); + SDMMC_RELEASE_RESET(); #endif // NVIC configuration for SDIO interrupts @@ -263,7 +252,7 @@ STATIC HAL_StatusTypeDef sdmmc_init_sd(void) { mp_hal_delay_ms(50); } - #if MICROPY_HW_SDMMC_BUS_WIDTH == 4 + #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 // configure the SD bus width for 4-bit wide operation status = HAL_SD_ConfigWideBusOperation(&sdmmc_handle.sd, SDIO_BUS_WIDE_4B); if (status != HAL_OK) { @@ -298,7 +287,7 @@ STATIC HAL_StatusTypeDef sdmmc_init_mmc(void) { // As this is an eMMC card, overwrite LogBlockNbr with actual value sdmmc_handle.mmc.MmcCard.LogBlockNbr = 7469056 + 2048; - #if MICROPY_HW_SDMMC_BUS_WIDTH == 4 + #if MICROPY_HW_SDCARD_BUS_WIDTH == 4 // Configure the SDIO bus width for 4-bit wide operation #ifdef STM32F7 sdmmc_handle.mmc.Init.ClockBypass = SDIO_CLOCK_BYPASS_ENABLE; From 4d967868238e3c359187921edab8e6fc164f357d Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 20:49:29 +0200 Subject: [PATCH 036/349] stm32/uart: Enable HW flow control for UART 1/5/7/8. --- ports/stm32/uart.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index babdf63d96..a2b69967b6 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -223,6 +223,16 @@ bool uart_init(pyb_uart_obj_t *uart_obj, irqn = USART1_IRQn; pins[0] = MICROPY_HW_UART1_TX; pins[1] = MICROPY_HW_UART1_RX; + #if defined(MICROPY_HW_UART1_RTS) + if (flow & UART_HWCONTROL_RTS) { + pins[2] = MICROPY_HW_UART1_RTS; + } + #endif + #if defined(MICROPY_HW_UART1_CTS) + if (flow & UART_HWCONTROL_CTS) { + pins[3] = MICROPY_HW_UART1_CTS; + } + #endif __HAL_RCC_USART1_CLK_ENABLE(); break; #endif @@ -322,6 +332,16 @@ bool uart_init(pyb_uart_obj_t *uart_obj, #endif pins[0] = MICROPY_HW_UART5_TX; pins[1] = MICROPY_HW_UART5_RX; + #if defined(MICROPY_HW_UART5_RTS) + if (flow & UART_HWCONTROL_RTS) { + pins[2] = MICROPY_HW_UART5_RTS; + } + #endif + #if defined(MICROPY_HW_UART5_CTS) + if (flow & UART_HWCONTROL_CTS) { + pins[3] = MICROPY_HW_UART5_CTS; + } + #endif break; #endif @@ -364,6 +384,16 @@ bool uart_init(pyb_uart_obj_t *uart_obj, #endif pins[0] = MICROPY_HW_UART7_TX; pins[1] = MICROPY_HW_UART7_RX; + #if defined(MICROPY_HW_UART7_RTS) + if (flow & UART_HWCONTROL_RTS) { + pins[2] = MICROPY_HW_UART7_RTS; + } + #endif + #if defined(MICROPY_HW_UART7_CTS) + if (flow & UART_HWCONTROL_CTS) { + pins[3] = MICROPY_HW_UART7_CTS; + } + #endif break; #endif @@ -381,6 +411,16 @@ bool uart_init(pyb_uart_obj_t *uart_obj, #endif pins[0] = MICROPY_HW_UART8_TX; pins[1] = MICROPY_HW_UART8_RX; + #if defined(MICROPY_HW_UART8_RTS) + if (flow & UART_HWCONTROL_RTS) { + pins[2] = MICROPY_HW_UART8_RTS; + } + #endif + #if defined(MICROPY_HW_UART8_CTS) + if (flow & UART_HWCONTROL_CTS) { + pins[3] = MICROPY_HW_UART8_CTS; + } + #endif break; #endif From 80788154b31c6097fd152e6e2e971319e8e3da1e Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 21:32:57 +0200 Subject: [PATCH 037/349] stm32/sdio: Add functions to re/enable SDIO/SDIOIT. --- ports/stm32/sdio.c | 15 +++++++++++++++ ports/stm32/sdio.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index 87f550e3a6..3ebd4947f4 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -93,6 +93,21 @@ void sdio_deinit(void) { #endif } +void sdio_reenable(void) { + if (__HAL_RCC_SDMMC1_IS_CLK_DISABLED()) { + __HAL_RCC_SDMMC1_CLK_ENABLE(); // enable SDIO peripheral + sdio_enable_high_speed_4bit(); + } +} + +void sdio_enable_irq(bool enable) { + if (enable) { + SDMMC1->MASK |= SDMMC_MASK_SDIOITIE; + } else { + SDMMC1->MASK &= ~SDMMC_MASK_SDIOITIE; + } +} + void sdio_enable_high_speed_4bit(void) { SDMMC_TypeDef *SDIO = SDMMC1; SDIO->POWER = 0; // power off diff --git a/ports/stm32/sdio.h b/ports/stm32/sdio.h index e7115e6f80..7cbf024ca8 100644 --- a/ports/stm32/sdio.h +++ b/ports/stm32/sdio.h @@ -31,6 +31,8 @@ void sdio_init(uint32_t irq_pri); void sdio_deinit(void); +void sdio_reenable(void); +void sdio_enable_irq(bool enable); void sdio_enable_high_speed_4bit(void); int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp); int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t len, uint8_t *buf); From d3eb6d68a377c42bd37e609ce667bea815fecd4f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 21:35:10 +0200 Subject: [PATCH 038/349] drivers/cyw43/cyw43_ctrl: Use new sdio enable API functions. This removes any references to a specific SDMMC instance, making the driver more generic/portable. --- drivers/cyw43/cyw43_ctrl.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/cyw43/cyw43_ctrl.c b/drivers/cyw43/cyw43_ctrl.c index cc1fbecde8..aaa266b0d8 100644 --- a/drivers/cyw43/cyw43_ctrl.c +++ b/drivers/cyw43/cyw43_ctrl.c @@ -112,7 +112,7 @@ void cyw43_deinit(cyw43_t *self) { self->itf_state = 0; // Disable async polling - SDMMC1->MASK &= ~SDMMC_MASK_SDIOITIE; + sdio_enable_irq(false); cyw43_poll = NULL; #ifdef pyb_pin_WL_RFSW_VDD @@ -164,7 +164,7 @@ STATIC int cyw43_ensure_up(cyw43_t *self) { cyw43_sleep = CYW43_SLEEP_MAX; cyw43_poll = cyw43_poll_func; #if USE_SDIOIT - SDMMC1->MASK |= SDMMC_MASK_SDIOITIE; + sdio_enable_irq(true); #else extern void extint_set(const pin_obj_t *pin, uint32_t mode); extint_set(pyb_pin_WL_HOST_WAKE, GPIO_MODE_IT_FALLING); @@ -209,7 +209,7 @@ STATIC void cyw43_poll_func(void) { } #if USE_SDIOIT - SDMMC1->MASK |= SDMMC_MASK_SDIOITIE; + sdio_enable_irq(true); #endif } @@ -227,10 +227,7 @@ int cyw43_cb_read_host_interrupt_pin(void *cb_data) { void cyw43_cb_ensure_awake(void *cb_data) { cyw43_sleep = CYW43_SLEEP_MAX; #if !USE_SDIOIT - if (__HAL_RCC_SDMMC1_IS_CLK_DISABLED()) { - __HAL_RCC_SDMMC1_CLK_ENABLE(); // enable SDIO peripheral - sdio_enable_high_speed_4bit(); - } + sdio_reenable(); #endif } From d74e2aca3e30ff1d424e97ac0d37d07694d69b7d Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 20:09:34 +0200 Subject: [PATCH 039/349] drivers/cyw43/cywbt: Add compile option for RF switch. --- drivers/cyw43/cywbt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cyw43/cywbt.c b/drivers/cyw43/cywbt.c index defe670683..c4fecca81b 100644 --- a/drivers/cyw43/cywbt.c +++ b/drivers/cyw43/cywbt.c @@ -149,10 +149,14 @@ STATIC int cywbt_download_firmware(const uint8_t *firmware) { } // RF switch must select high path during BT patch boot + #if MICROPY_HW_ENABLE_RF_SWITCH mp_hal_pin_config(pyb_pin_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0); + #endif mp_hal_delay_ms(10); // give some time for CTS to go high cywbt_wait_cts_low(); + #if MICROPY_HW_ENABLE_RF_SWITCH mp_hal_pin_config(pyb_pin_WL_GPIO_1, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_DOWN, 0); // Select chip antenna (could also select external) + #endif mp_bluetooth_hci_uart_set_baudrate(115200); cywbt_set_baudrate(3000000); @@ -170,9 +174,11 @@ int mp_bluetooth_hci_controller_init(void) { mp_hal_pin_output(pyb_pin_BT_DEV_WAKE); mp_hal_pin_low(pyb_pin_BT_DEV_WAKE); + #if MICROPY_HW_ENABLE_RF_SWITCH // TODO don't select antenna if wifi is enabled mp_hal_pin_config(pyb_pin_WL_GPIO_4, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); // RF-switch power mp_hal_pin_high(pyb_pin_WL_GPIO_4); // Turn the RF-switch on + #endif uint8_t buf[256]; From baa712b7f093fdeec3ddd4122be9e2f171d35a33 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 20:10:30 +0200 Subject: [PATCH 040/349] stm32/boards/PYBD_SF2: Enable RF switch compile option. --- ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index 7d89e17cf4..57cc75efc6 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -39,6 +39,7 @@ #define MICROPY_HW_ENABLE_USB (1) #define MICROPY_HW_ENABLE_SDCARD (1) #define MICROPY_HW_ENABLE_MMCARD (1) +#define MICROPY_HW_ENABLE_RF_SWITCH (1) #define MICROPY_BOARD_EARLY_INIT board_early_init #define MICROPY_BOARD_ENTER_STOP board_sleep(1); From 0d4eb15392dfeee8c2113e46eb21f27800872524 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 28 Apr 2021 20:11:48 +0200 Subject: [PATCH 041/349] drivers/cyw43/cywbt: Remove hard-coded UART6 alternate function setting. --- drivers/cyw43/cywbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cyw43/cywbt.c b/drivers/cyw43/cywbt.c index c4fecca81b..64aeb871c3 100644 --- a/drivers/cyw43/cywbt.c +++ b/drivers/cyw43/cywbt.c @@ -55,7 +55,7 @@ STATIC void cywbt_wait_cts_low(void) { } mp_hal_delay_ms(1); } - mp_hal_pin_config_alt_static(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_USART6_CTS); + mp_hal_pin_config_alt(pyb_pin_BT_CTS, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_UART, mp_bluetooth_hci_uart_obj.uart_id); } STATIC int cywbt_hci_cmd_raw(size_t len, uint8_t *buf) { From a1111b83ed00542b4f5651d3aae9d38ecbbb6dd6 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Thu, 29 Apr 2021 23:18:54 +0200 Subject: [PATCH 042/349] stm32/sdio: Allow configuring the SDMMC periph used for SDIO. This can now be selected by setting MICROPY_HW_SDIO_SDMMC, which defaults to 1, ie SDMMC1. The pins can also be selected and default to the standard C8/C9/C10/C11/C12/D2. --- ports/stm32/mpconfigboard_common.h | 9 +- ports/stm32/sdio.c | 195 ++++++++++++++++++----------- 2 files changed, 127 insertions(+), 77 deletions(-) diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 37ce8bbf19..0df35918be 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -122,6 +122,11 @@ #define MICROPY_HW_SDCARD_MOUNT_AT_BOOT (MICROPY_HW_ENABLE_SDCARD) #endif +// Which SDMMC peripheral to use for the SDIO driver (1 or 2) +#ifndef MICROPY_HW_SDIO_SDMMC +#define MICROPY_HW_SDIO_SDMMC (1) +#endif + // Whether to enable the MMA7660 driver, exposed as pyb.Accel #ifndef MICROPY_HW_HAS_MMA7660 #define MICROPY_HW_HAS_MMA7660 (0) @@ -390,10 +395,10 @@ // Define MICROPY_HW_SDMMCx_CK values if that peripheral is used, so that make-pins.py // generates the relevant AF constants. -#if MICROPY_HW_SDCARD_SDMMC == 1 +#if MICROPY_HW_SDCARD_SDMMC == 1 || MICROPY_HW_SDIO_SDMMC == 1 #define MICROPY_HW_SDMMC1_CK (1) #endif -#if MICROPY_HW_SDCARD_SDMMC == 2 +#if MICROPY_HW_SDCARD_SDMMC == 2 || MICROPY_HW_SDIO_SDMMC == 2 #define MICROPY_HW_SDMMC2_CK (1) #endif diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index 3ebd4947f4..dfd4092577 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -28,7 +28,8 @@ #include "py/mperrno.h" #include "py/mphal.h" -#include "genhdr/pins.h" +#include "pin.h" +#include "pin_static_af.h" #include "pendsv.h" #include "sdio.h" @@ -50,18 +51,62 @@ static volatile uint32_t sdmmc_error; static volatile uint8_t *sdmmc_buf_cur; static volatile uint8_t *sdmmc_buf_top; +// The H7/F7/L4 have 2 SDMMC peripherals, but at the moment this driver only supports +// using one of them in a given build, selected by MICROPY_HW_SDIO_SDMMC. + +#if MICROPY_HW_SDIO_SDMMC == 1 +#define SDMMC SDMMC1 +#define SDMMC_IRQn SDMMC1_IRQn +#define SDMMC_IRQHandler SDMMC1_IRQHandler +#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE() +#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE() +#define SDMMC_IS_CLK_DISABLED() __HAL_RCC_SDMMC1_IS_CLK_DISABLED() +#define STATIC_AF_SDMMC_CK STATIC_AF_SDMMC1_CK +#define STATIC_AF_SDMMC_CMD STATIC_AF_SDMMC1_CMD +#define STATIC_AF_SDMMC_D0 STATIC_AF_SDMMC1_D0 +#define STATIC_AF_SDMMC_D1 STATIC_AF_SDMMC1_D1 +#define STATIC_AF_SDMMC_D2 STATIC_AF_SDMMC1_D2 +#define STATIC_AF_SDMMC_D3 STATIC_AF_SDMMC1_D3 +#else +#if defined(STM32F7) +#error Due to DMA configuration, only SDMMC1 is currently supported on F7 +#endif +#define SDMMC SDMMC2 +#define SDMMC_IRQn SDMMC2_IRQn +#define SDMMC_IRQHandler SDMMC2_IRQHandler +#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC2_CLK_ENABLE() +#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC2_CLK_DISABLE() +#define SDMMC_IS_CLK_DISABLED() __HAL_RCC_SDMMC2_IS_CLK_DISABLED() +#define STATIC_AF_SDMMC_CK STATIC_AF_SDMMC2_CK +#define STATIC_AF_SDMMC_CMD STATIC_AF_SDMMC2_CMD +#define STATIC_AF_SDMMC_D0 STATIC_AF_SDMMC2_D0 +#define STATIC_AF_SDMMC_D1 STATIC_AF_SDMMC2_D1 +#define STATIC_AF_SDMMC_D2 STATIC_AF_SDMMC2_D2 +#define STATIC_AF_SDMMC_D3 STATIC_AF_SDMMC2_D3 +#endif + +// If no custom SDIO pins defined, use the default ones +#ifndef MICROPY_HW_SDIO_CK +#define MICROPY_HW_SDIO_D0 (pin_C8) +#define MICROPY_HW_SDIO_D1 (pin_C9) +#define MICROPY_HW_SDIO_D2 (pin_C10) +#define MICROPY_HW_SDIO_D3 (pin_C11) +#define MICROPY_HW_SDIO_CK (pin_C12) +#define MICROPY_HW_SDIO_CMD (pin_D2) +#endif + void sdio_init(uint32_t irq_pri) { // configure IO pins - mp_hal_pin_config(pin_C8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, 12); - mp_hal_pin_config(pin_C9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, 12); - mp_hal_pin_config(pin_C10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, 12); - mp_hal_pin_config(pin_C11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, 12); - mp_hal_pin_config(pin_C12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 12); // CLK doesn't need pull-up - mp_hal_pin_config(pin_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, 12); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D0); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D1); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D2); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_D3); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_SDMMC_CK); + mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_CMD); - __HAL_RCC_SDMMC1_CLK_ENABLE(); // enable SDIO peripheral + SDMMC_CLK_ENABLE(); // enable SDIO peripheral - SDMMC_TypeDef *SDIO = SDMMC1; + SDMMC_TypeDef *SDIO = SDMMC; #if defined(STM32F7) SDIO->CLKCR = SDMMC_CLKCR_HWFC_EN | SDMMC_CLKCR_PWRSAV | (120 - 2); // 1-bit, 400kHz #else @@ -80,36 +125,36 @@ void sdio_init(uint32_t irq_pri) { __HAL_RCC_DMA2_CLK_ENABLE(); // enable DMA2 peripheral #endif - NVIC_SetPriority(SDMMC1_IRQn, irq_pri); + NVIC_SetPriority(SDMMC_IRQn, irq_pri); SDIO->MASK = 0; - HAL_NVIC_EnableIRQ(SDMMC1_IRQn); + HAL_NVIC_EnableIRQ(SDMMC_IRQn); } void sdio_deinit(void) { - __HAL_RCC_SDMMC1_CLK_DISABLE(); + SDMMC_CLK_DISABLE(); #if defined(STM32F7) __HAL_RCC_DMA2_CLK_DISABLE(); #endif } void sdio_reenable(void) { - if (__HAL_RCC_SDMMC1_IS_CLK_DISABLED()) { - __HAL_RCC_SDMMC1_CLK_ENABLE(); // enable SDIO peripheral + if (SDMMC_IS_CLK_DISABLED()) { + SDMMC_CLK_ENABLE(); // enable SDIO peripheral sdio_enable_high_speed_4bit(); } } void sdio_enable_irq(bool enable) { if (enable) { - SDMMC1->MASK |= SDMMC_MASK_SDIOITIE; + SDMMC->MASK |= SDMMC_MASK_SDIOITIE; } else { - SDMMC1->MASK &= ~SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= ~SDMMC_MASK_SDIOITIE; } } void sdio_enable_high_speed_4bit(void) { - SDMMC_TypeDef *SDIO = SDMMC1; + SDMMC_TypeDef *SDIO = SDMMC; SDIO->POWER = 0; // power off mp_hal_delay_us(10); #if defined(STM32F7) @@ -128,33 +173,33 @@ void sdio_enable_high_speed_4bit(void) { mp_hal_delay_us(10); } -void SDMMC1_IRQHandler(void) { - if (SDMMC1->STA & SDMMC_STA_CMDREND) { - SDMMC1->ICR = SDMMC_ICR_CMDRENDC; - uint32_t r1 = SDMMC1->RESP1; - if (SDMMC1->RESPCMD == 53 && r1 & 0x800) { - printf("bad RESP1: %lu %lx\n", SDMMC1->RESPCMD, r1); +void SDMMC_IRQHandler(void) { + if (SDMMC->STA & SDMMC_STA_CMDREND) { + SDMMC->ICR = SDMMC_ICR_CMDRENDC; + uint32_t r1 = SDMMC->RESP1; + if (SDMMC->RESPCMD == 53 && r1 & 0x800) { + printf("bad RESP1: %lu %lx\n", SDMMC->RESPCMD, r1); sdmmc_error = 0xffffffff; - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; sdmmc_irq_state = SDMMC_IRQ_STATE_DONE; return; } #if defined(STM32H7) if (!sdmmc_dma) { - while (sdmmc_buf_cur < sdmmc_buf_top && (SDMMC1->STA & SDMMC_STA_DPSMACT) && !(SDMMC1->STA & SDMMC_STA_RXFIFOE)) { - *(uint32_t *)sdmmc_buf_cur = SDMMC1->FIFO; + while (sdmmc_buf_cur < sdmmc_buf_top && (SDMMC->STA & SDMMC_STA_DPSMACT) && !(SDMMC->STA & SDMMC_STA_RXFIFOE)) { + *(uint32_t *)sdmmc_buf_cur = SDMMC->FIFO; sdmmc_buf_cur += 4; } } #endif if (sdmmc_buf_cur >= sdmmc_buf_top) { // data transfer finished, so we are done - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; sdmmc_irq_state = SDMMC_IRQ_STATE_DONE; return; } if (sdmmc_write) { - SDMMC1->DCTRL = + SDMMC->DCTRL = SDMMC_DCTRL_SDIOEN | SDMMC_DCTRL_RWMOD | sdmmc_block_size_log2 << SDMMC_DCTRL_DBLOCKSIZE_Pos @@ -165,51 +210,51 @@ void SDMMC1_IRQHandler(void) { | SDMMC_DCTRL_DTEN ; if (!sdmmc_dma) { - SDMMC1->MASK |= SDMMC_MASK_TXFIFOHEIE; + SDMMC->MASK |= SDMMC_MASK_TXFIFOHEIE; } } sdmmc_irq_state = SDMMC_IRQ_STATE_CMD_DONE; - } else if (SDMMC1->STA & SDMMC_STA_DATAEND) { + } else if (SDMMC->STA & SDMMC_STA_DATAEND) { // data transfer complete // note: it's possible to get DATAEND before CMDREND - SDMMC1->ICR = SDMMC_ICR_DATAENDC; + SDMMC->ICR = SDMMC_ICR_DATAENDC; #if defined(STM32F7) // check if there is some remaining data in RXFIFO if (!sdmmc_dma) { - while (SDMMC1->STA & SDMMC_STA_RXDAVL) { - *(uint32_t *)sdmmc_buf_cur = SDMMC1->FIFO; + while (SDMMC->STA & SDMMC_STA_RXDAVL) { + *(uint32_t *)sdmmc_buf_cur = SDMMC->FIFO; sdmmc_buf_cur += 4; } } #endif if (sdmmc_irq_state == SDMMC_IRQ_STATE_CMD_DONE) { // command and data finished, so we are done - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; sdmmc_irq_state = SDMMC_IRQ_STATE_DONE; } - } else if (SDMMC1->STA & SDMMC_STA_TXFIFOHE) { + } else if (SDMMC->STA & SDMMC_STA_TXFIFOHE) { if (!sdmmc_dma && sdmmc_write) { // write up to 8 words to fifo for (size_t i = 8; i && sdmmc_buf_cur < sdmmc_buf_top; --i) { - SDMMC1->FIFO = *(uint32_t *)sdmmc_buf_cur; + SDMMC->FIFO = *(uint32_t *)sdmmc_buf_cur; sdmmc_buf_cur += 4; } if (sdmmc_buf_cur >= sdmmc_buf_top) { // finished, disable IRQ - SDMMC1->MASK &= ~SDMMC_MASK_TXFIFOHEIE; + SDMMC->MASK &= ~SDMMC_MASK_TXFIFOHEIE; } } - } else if (SDMMC1->STA & SDMMC_STA_RXFIFOHF) { + } else if (SDMMC->STA & SDMMC_STA_RXFIFOHF) { if (!sdmmc_dma && !sdmmc_write) { // read up to 8 words from fifo for (size_t i = 8; i && sdmmc_buf_cur < sdmmc_buf_top; --i) { - *(uint32_t *)sdmmc_buf_cur = SDMMC1->FIFO; + *(uint32_t *)sdmmc_buf_cur = SDMMC->FIFO; sdmmc_buf_cur += 4; } } - } else if (SDMMC1->STA & SDMMC_STA_SDIOIT) { - SDMMC1->MASK &= ~SDMMC_MASK_SDIOITIE; - SDMMC1->ICR = SDMMC_ICR_SDIOITC; + } else if (SDMMC->STA & SDMMC_STA_SDIOIT) { + SDMMC->MASK &= ~SDMMC_MASK_SDIOITIE; + SDMMC->ICR = SDMMC_ICR_SDIOITC; #if MICROPY_PY_NETWORK_CYW43 extern void (*cyw43_poll)(void); @@ -217,11 +262,11 @@ void SDMMC1_IRQHandler(void) { pendsv_schedule_dispatch(PENDSV_DISPATCH_CYW43, cyw43_poll); } #endif - } else if (SDMMC1->STA & 0x3f) { + } else if (SDMMC->STA & 0x3f) { // an error - sdmmc_error = SDMMC1->STA; - SDMMC1->ICR = SDMMC_STATIC_FLAGS; - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + sdmmc_error = SDMMC->STA; + SDMMC->ICR = SDMMC_STATIC_FLAGS; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; sdmmc_irq_state = SDMMC_IRQ_STATE_DONE; } } @@ -229,22 +274,22 @@ void SDMMC1_IRQHandler(void) { int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { #if defined(STM32F7) // Wait for any outstanding TX to complete - while (SDMMC1->STA & SDMMC_STA_TXACT) { + while (SDMMC->STA & SDMMC_STA_TXACT) { } #endif #if defined(STM32F7) DMA2_Stream3->CR = 0; // ensure DMA is reset #endif - SDMMC1->ICR = SDMMC_STATIC_FLAGS; // clear interrupts - SDMMC1->ARG = arg; - SDMMC1->CMD = cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; + SDMMC->ICR = SDMMC_STATIC_FLAGS; // clear interrupts + SDMMC->ARG = arg; + SDMMC->CMD = cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; sdmmc_irq_state = SDMMC_IRQ_STATE_CMD_DATA_PENDING; sdmmc_error = 0; sdmmc_buf_cur = NULL; sdmmc_buf_top = NULL; - SDMMC1->MASK = (SDMMC1->MASK & SDMMC_MASK_SDIOITIE) | SDMMC_MASK_CMDRENDIE | 0x3f; + SDMMC->MASK = (SDMMC->MASK & SDMMC_MASK_SDIOITIE) | SDMMC_MASK_CMDRENDIE | 0x3f; uint32_t start = mp_hal_ticks_ms(); for (;;) { @@ -253,13 +298,13 @@ int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { break; } if (mp_hal_ticks_ms() - start > 1000) { - SDMMC1->MASK = DEFAULT_MASK; - printf("sdio_transfer timeout STA=0x%08x\n", (uint)SDMMC1->STA); + SDMMC->MASK = DEFAULT_MASK; + printf("sdio_transfer timeout STA=0x%08x\n", (uint)SDMMC->STA); return -MP_ETIMEDOUT; } } - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; if (sdmmc_error == SDMMC_STA_CCRCFAIL && cmd == 5) { // Errata: CMD CRC error is incorrectly generated for CMD 5 @@ -268,13 +313,13 @@ int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { return -(0x1000000 | sdmmc_error); } - uint32_t rcmd = SDMMC1->RESPCMD; + uint32_t rcmd = SDMMC->RESPCMD; if (rcmd != cmd) { printf("sdio_transfer: cmd=%lu rcmd=%lu\n", cmd, rcmd); return -MP_EIO; } if (resp != NULL) { - *resp = SDMMC1->RESP1; + *resp = SDMMC->RESP1; } return 0; } @@ -282,7 +327,7 @@ int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t len, uint8_t *buf) { #if defined(STM32F7) // Wait for any outstanding TX to complete - while (SDMMC1->STA & SDMMC_STA_TXACT) { + while (SDMMC->STA & SDMMC_STA_TXACT) { } #endif @@ -309,11 +354,11 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le bool dma = (len > 16); - SDMMC1->ICR = SDMMC_STATIC_FLAGS; // clear interrupts - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->ICR = SDMMC_STATIC_FLAGS; // clear interrupts + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; - SDMMC1->DTIMER = 0x2000000; // about 700ms running at 48MHz - SDMMC1->DLEN = (len + block_size - 1) & ~(block_size - 1); + SDMMC->DTIMER = 0x2000000; // about 700ms running at 48MHz + SDMMC->DLEN = (len + block_size - 1) & ~(block_size - 1); #if defined(STM32F7) DMA2_Stream3->CR = 0; @@ -339,7 +384,7 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #if defined(STM32F7) DMA2->LIFCR = 0x3f << 22; DMA2_Stream3->FCR = 0x07; // ? - DMA2_Stream3->PAR = (uint32_t)&SDMMC1->FIFO; + DMA2_Stream3->PAR = (uint32_t)&SDMMC->FIFO; if ((uint32_t)buf & 3) { printf("sdio_transfer_cmd53: buf=%p is not aligned for DMA\n", buf); return -MP_EINVAL; @@ -359,12 +404,12 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le | 1 << 0 // EN ; #else - SDMMC1->IDMABASE0 = (uint32_t)buf; - SDMMC1->IDMACTRL = SDMMC_IDMA_IDMAEN; + SDMMC->IDMABASE0 = (uint32_t)buf; + SDMMC->IDMACTRL = SDMMC_IDMA_IDMAEN; #endif } else { #if defined(STM32H7) - SDMMC1->IDMACTRL = 0; + SDMMC->IDMACTRL = 0; #endif } @@ -373,7 +418,7 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le // (and in case we get a long-running unrelated IRQ here on the host just // after writing to CMD to initiate the command) if (!write) { - SDMMC1->DCTRL = + SDMMC->DCTRL = SDMMC_DCTRL_SDIOEN | SDMMC_DCTRL_RWMOD | block_size_log2 << SDMMC_DCTRL_DBLOCKSIZE_Pos @@ -385,8 +430,8 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le ; } - SDMMC1->ARG = arg; - SDMMC1->CMD = 53 | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; + SDMMC->ARG = arg; + SDMMC->CMD = 53 | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN; sdmmc_irq_state = SDMMC_IRQ_STATE_CMD_DATA_PENDING; sdmmc_block_size_log2 = block_size_log2; @@ -395,7 +440,7 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le sdmmc_error = 0; sdmmc_buf_cur = (uint8_t *)buf; sdmmc_buf_top = (uint8_t *)buf + len; - SDMMC1->MASK = (SDMMC1->MASK & SDMMC_MASK_SDIOITIE) | SDMMC_MASK_CMDRENDIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_RXFIFOHFIE | 0x3f; + SDMMC->MASK = (SDMMC->MASK & SDMMC_MASK_SDIOITIE) | SDMMC_MASK_CMDRENDIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_RXFIFOHFIE | 0x3f; // wait to complete transfer uint32_t start = mp_hal_ticks_ms(); @@ -405,23 +450,23 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le break; } if (mp_hal_ticks_ms() - start > 200) { - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; #if defined(STM32F7) - printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x DMA=%08x:%08x:%08x RCC=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC1->STA, (uint)SDMMC1->DCOUNT, (uint)SDMMC1->FIFOCNT, (uint)DMA2->LISR, (uint)DMA2->HISR, (uint)DMA2_Stream3->NDTR, (uint)RCC->AHB1ENR); + printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x DMA=%08x:%08x:%08x RCC=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->FIFOCNT, (uint)DMA2->LISR, (uint)DMA2->HISR, (uint)DMA2_Stream3->NDTR, (uint)RCC->AHB1ENR); #else - printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC1->STA, (uint)SDMMC1->DCOUNT, (uint)SDMMC1->DCTRL, (uint)SDMMC1->IDMACTRL); + printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif return -MP_ETIMEDOUT; } } - SDMMC1->MASK &= SDMMC_MASK_SDIOITIE; + SDMMC->MASK &= SDMMC_MASK_SDIOITIE; if (sdmmc_error) { #if defined(STM32F7) - printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x DMA=%08x:%08x:%08x RCC=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC1->STA, (uint)SDMMC1->DCOUNT, (uint)SDMMC1->FIFOCNT, (uint)DMA2->LISR, (uint)DMA2->HISR, (uint)DMA2_Stream3->NDTR, (uint)RCC->AHB1ENR); + printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x DMA=%08x:%08x:%08x RCC=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->FIFOCNT, (uint)DMA2->LISR, (uint)DMA2->HISR, (uint)DMA2_Stream3->NDTR, (uint)RCC->AHB1ENR); #else - printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC1->STA, (uint)SDMMC1->DCOUNT, (uint)SDMMC1->DCTRL, (uint)SDMMC1->IDMACTRL); + printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif return -(0x1000000 | sdmmc_error); } From a41cd150be01adc59828ead26a01a9d9324773e1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:48:04 +1000 Subject: [PATCH 043/349] esp8266/modnetwork: Use mp_handle_pending() to raise pending exception. If MICROPY_ENABLE_SCHEDULER is enabled then MP_STATE_VM(sched_state) must be updated after handling the pending exception, which is done by the mp_handle_pending() function. Signed-off-by: Damien George --- ports/esp8266/modnetwork.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c index cad53d912c..3b8ef4b21f 100644 --- a/ports/esp8266/modnetwork.c +++ b/ports/esp8266/modnetwork.c @@ -239,9 +239,7 @@ STATIC mp_obj_t esp_scan(mp_obj_t self_in) { // esp_scan_list variable to NULL without disabling interrupts if (MP_STATE_VM(mp_pending_exception) != NULL) { esp_scan_list = NULL; - mp_obj_t obj = MP_STATE_VM(mp_pending_exception); - MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; - nlr_raise(obj); + mp_handle_pending(true); } ets_loop_iter(); } From 7e549b6718e80136b03074765f1d4add209a21a5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:50:09 +1000 Subject: [PATCH 044/349] py/profile: Use mp_handle_pending() to raise pending exception. If MICROPY_ENABLE_SCHEDULER is enabled then MP_STATE_VM(sched_state) must be updated after handling the pending exception, which is done by the mp_handle_pending() function. Signed-off-by: Damien George --- py/profile.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/py/profile.c b/py/profile.c index 9cf8c4b7ba..e5fb35f0ed 100644 --- a/py/profile.c +++ b/py/profile.c @@ -298,9 +298,7 @@ STATIC mp_obj_t mp_prof_callback_invoke(mp_obj_t callback, prof_callback_args_t mp_prof_is_executing = false; if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) { - mp_obj_t obj = MP_STATE_VM(mp_pending_exception); - MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; - nlr_raise(obj); + mp_handle_pending(true); } return top; } From 7cbf826a9575e18ce1b7fe11b0f0997509153260 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:52:19 +1000 Subject: [PATCH 045/349] py/scheduler: Add mp_sched_exception() to schedule a pending exception. This helper is added to properly set a pending exception, to mirror mp_sched_schedule(), which schedules a function. Signed-off-by: Damien George --- ports/esp32/mpconfigport.h | 1 + ports/esp8266/mpconfigport.h | 1 + py/mpconfig.h | 4 ++++ py/runtime.h | 1 + py/scheduler.c | 14 +++++++++----- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 8788963cb3..0c7d42210e 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -264,6 +264,7 @@ void *esp_native_code_commit(void *, size_t, void *); #endif // Functions that should go in IRAM +#define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) IRAM_ATTR f #define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) IRAM_ATTR f #define UINT_FMT "%u" diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 2c56b4188f..52028e833a 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -195,6 +195,7 @@ extern const struct _mp_obj_module_t mp_module_onewire; #define MICROPY_PY_SYS_PLATFORM "esp8266" #define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n +#define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) MP_FASTCODE(f) #define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) MP_FASTCODE(f) #define MICROPY_WRAP_MP_SCHED_SCHEDULE(f) MP_FASTCODE(f) diff --git a/py/mpconfig.h b/py/mpconfig.h index 5c7212fd1f..2934f8ec89 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1504,6 +1504,10 @@ typedef double mp_float_t; /*****************************************************************************/ /* Hooks for a port to wrap functions with attributes */ +#ifndef MICROPY_WRAP_MP_SCHED_EXCEPTION +#define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) f +#endif + #ifndef MICROPY_WRAP_MP_KEYBOARD_INTERRUPT #define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) f #endif diff --git a/py/runtime.h b/py/runtime.h index 0cbbb287ac..9ad4bc0242 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -64,6 +64,7 @@ extern const byte mp_binary_op_method_name[]; void mp_init(void); void mp_deinit(void); +void mp_sched_exception(mp_obj_t exc); void mp_keyboard_interrupt(void); void mp_handle_pending(bool raise_exc); void mp_handle_pending_tail(mp_uint_t atomic_state); diff --git a/py/scheduler.c b/py/scheduler.c index 6b138a631b..f37f8c3f86 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -28,17 +28,21 @@ #include "py/runtime.h" -#if MICROPY_KBD_EXCEPTION -// This function may be called asynchronously at any time so only do the bare minimum. -void MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(mp_keyboard_interrupt)(void) { - MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; - MP_STATE_VM(mp_pending_exception) = MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)); +void mp_sched_exception(mp_obj_t exc) { + MP_STATE_VM(mp_pending_exception) = exc; #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } #endif } + +#if MICROPY_KBD_EXCEPTION +// This function may be called asynchronously at any time so only do the bare minimum. +void MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(mp_keyboard_interrupt)(void) { + MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; + mp_sched_exception(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); +} #endif #if MICROPY_ENABLE_SCHEDULER From bd54eb566f85293279d02d0a663c7e4d9f59e660 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:53:54 +1000 Subject: [PATCH 046/349] nrf/boards/microbit: Use mp_sched_exception() where appropriate. Signed-off-by: Damien George --- ports/nrf/boards/microbit/modules/microbitdisplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/nrf/boards/microbit/modules/microbitdisplay.c b/ports/nrf/boards/microbit/modules/microbitdisplay.c index 979a4ddd08..c2eaf4179b 100644 --- a/ports/nrf/boards/microbit/modules/microbitdisplay.c +++ b/ports/nrf/boards/microbit/modules/microbitdisplay.c @@ -305,7 +305,7 @@ static void draw_object(mp_obj_t obj) { async_stop(); } } else { - MP_STATE_VM(mp_pending_exception) = mp_obj_new_exception_msg(&mp_type_TypeError, MP_ERROR_TEXT("not an image.")); + mp_sched_exception(mp_obj_new_exception_msg(&mp_type_TypeError, MP_ERROR_TEXT("not an image."))); async_stop(); } } @@ -341,7 +341,7 @@ static void microbit_display_update(void) { if (mp_obj_get_type(nlr.ret_val) == &mp_type_MemoryError) { mp_printf(&mp_plat_print, "Allocation in interrupt handler"); } - MP_STATE_VM(mp_pending_exception) = MP_OBJ_FROM_PTR(nlr.ret_val); + mp_sched_exception(MP_OBJ_FROM_PTR(nlr.ret_val)); } obj = MP_OBJ_STOP_ITERATION; } From e9e9c76ddf131f8e50b0ae2d44501d3cd88537ef Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 10:57:34 +1000 Subject: [PATCH 047/349] all: Rename mp_keyboard_interrupt to mp_sched_keyboard_interrupt. To match mp_sched_exception() and mp_sched_schedule(). Signed-off-by: Damien George --- extmod/uos_dupterm.c | 2 +- ports/cc3200/mods/pybuart.c | 2 +- ports/cc3200/telnet/telnet.c | 2 +- ports/esp32/mpconfigport.h | 2 +- ports/esp32/uart.c | 2 +- ports/esp32/usb.c | 2 +- ports/esp8266/esp_mphal.h | 2 +- ports/esp8266/mpconfigport.h | 2 +- ports/esp8266/uart.c | 6 +++--- ports/javascript/Makefile | 2 +- ports/javascript/library.js | 2 +- ports/mimxrt/mphalport.c | 2 +- ports/nrf/drivers/bluetooth/ble_uart.c | 2 +- ports/nrf/modules/machine/uart.c | 2 +- ports/rp2/mphalport.c | 2 +- ports/rp2/uart.c | 2 +- ports/samd/mphalport.c | 2 +- ports/stm32/pendsv.c | 2 +- ports/unix/coverage.c | 8 ++++---- ports/unix/unix_mphal.c | 2 +- ports/windows/windows_mphal.c | 2 +- ports/zephyr/src/zephyr_getchar.c | 4 ++-- py/mpconfig.h | 4 ++-- py/runtime.h | 2 +- py/scheduler.c | 2 +- 25 files changed, 32 insertions(+), 32 deletions(-) diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c index ad706d5246..b661803875 100644 --- a/extmod/uos_dupterm.c +++ b/extmod/uos_dupterm.c @@ -133,7 +133,7 @@ int mp_uos_dupterm_rx_chr(void) { nlr_pop(); if (buf[0] == mp_interrupt_char) { // Signal keyboard interrupt to be raised as soon as the VM resumes - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); return -2; } return buf[0]; diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c index 98adf1c398..ac2af7032e 100644 --- a/ports/cc3200/mods/pybuart.c +++ b/ports/cc3200/mods/pybuart.c @@ -250,7 +250,7 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) { int data = MAP_UARTCharGetNonBlocking(self->reg); if (MP_STATE_PORT(os_term_dup_obj) && MP_STATE_PORT(os_term_dup_obj)->stream_o == self && data == mp_interrupt_char) { // raise an exception when interrupts are finished - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else { // there's always a read buffer available uint16_t next_head = (self->read_buf_head + 1) % PYBUART_RX_BUFFER_LEN; if (next_head != self->read_buf_tail) { diff --git a/ports/cc3200/telnet/telnet.c b/ports/cc3200/telnet/telnet.c index 401e8a8cc9..9f51d4cd85 100644 --- a/ports/cc3200/telnet/telnet.c +++ b/ports/cc3200/telnet/telnet.c @@ -446,7 +446,7 @@ static void telnet_parse_input (uint8_t *str, int16_t *len) { if (*_str <= 127) { if (telnet_data.state == E_TELNET_STE_LOGGED_IN && *_str == mp_interrupt_char) { // raise a keyboard exception - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); (*len)--; _str++; } diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 0c7d42210e..a06c910470 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -265,7 +265,7 @@ void *esp_native_code_commit(void *, size_t, void *); // Functions that should go in IRAM #define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) IRAM_ATTR f -#define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) IRAM_ATTR f +#define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) IRAM_ATTR f #define UINT_FMT "%u" #define INT_FMT "%d" diff --git a/ports/esp32/uart.c b/ports/esp32/uart.c index bd3eea9f6b..c4fe41eaff 100644 --- a/ports/esp32/uart.c +++ b/ports/esp32/uart.c @@ -55,7 +55,7 @@ STATIC void IRAM_ATTR uart_irq_handler(void *arg) { uint8_t c = READ_PERI_REG(UART_FIFO_AHB_REG(0)); // UART0 #endif if (c == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else { // this is an inline function so will be in IRAM ringbuf_put(&stdin_ringbuf, c); diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index aa76321a7e..85a7a11c9e 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -50,7 +50,7 @@ static void usb_callback_rx(int itf, cdcacm_event_t *event) { } for (size_t i = 0; i < len; ++i) { if (usb_rx_buf[i] == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else { ringbuf_put(&stdin_ringbuf, usb_rx_buf[i]); } diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h index 89f4e0ff08..e9cf7e548d 100644 --- a/ports/esp8266/esp_mphal.h +++ b/ports/esp8266/esp_mphal.h @@ -29,7 +29,7 @@ #include "lib/utils/interrupt_char.h" #include "xtirq.h" -void mp_keyboard_interrupt(void); +void mp_sched_keyboard_interrupt(void); struct _mp_print_t; // Structure for UART-only output via mp_printf() diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 52028e833a..ac47f0aa29 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -196,7 +196,7 @@ extern const struct _mp_obj_module_t mp_module_onewire; #define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n #define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) MP_FASTCODE(f) -#define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) MP_FASTCODE(f) +#define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) MP_FASTCODE(f) #define MICROPY_WRAP_MP_SCHED_SCHEDULE(f) MP_FASTCODE(f) #define WDEV_HWRNG ((volatile uint32_t *)0x3ff20e44) diff --git a/ports/esp8266/uart.c b/ports/esp8266/uart.c index 7d88555c05..5ac71da07d 100644 --- a/ports/esp8266/uart.c +++ b/ports/esp8266/uart.c @@ -42,7 +42,7 @@ static ringbuf_t uart_ringbuf = {uart_ringbuf_array, sizeof(uart_ringbuf_array), static void uart0_rx_intr_handler(void *para); void soft_reset(void); -void mp_keyboard_interrupt(void); +void mp_sched_keyboard_interrupt(void); /****************************************************************************** * FunctionName : uart_config @@ -179,7 +179,7 @@ static void uart0_rx_intr_handler(void *para) { // directly on stdin_ringbuf, rather than going via uart_ringbuf if (uart_attached_to_dupterm) { if (RcvChar == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else { ringbuf_put(&stdin_ringbuf, RcvChar); } @@ -303,7 +303,7 @@ void ICACHE_FLASH_ATTR uart_task_handler(os_event_t *evt) { int c, ret = 0; while ((c = ringbuf_get(&stdin_ringbuf)) >= 0) { if (c == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } ret = pyexec_event_repl_process_char(c); if (ret & PYEXEC_FORCED_EXIT) { diff --git a/ports/javascript/Makefile b/ports/javascript/Makefile index 3962e93f5f..9723675546 100644 --- a/ports/javascript/Makefile +++ b/ports/javascript/Makefile @@ -51,7 +51,7 @@ OBJ = $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -JSFLAGS = -O0 -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_keyboard_interrupt']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s "BINARYEN_TRAP_MODE='clamp'" --memory-init-file 0 --js-library library.js +JSFLAGS = -O0 -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_sched_keyboard_interrupt']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s "BINARYEN_TRAP_MODE='clamp'" --memory-init-file 0 --js-library library.js all: $(BUILD)/micropython.js diff --git a/ports/javascript/library.js b/ports/javascript/library.js index 9aab3e4320..a8e54aaaca 100644 --- a/ports/javascript/library.js +++ b/ports/javascript/library.js @@ -55,7 +55,7 @@ mergeInto(LibraryManager.library, { var n = fs.readSync(process.stdin.fd, buf, 0, 1); if (n > 0) { if (buf[0] == mp_interrupt_char) { - Module.ccall('mp_keyboard_interrupt', 'null', ['null'], ['null']); + Module.ccall('mp_sched_keyboard_interrupt', 'null', ['null'], ['null']); } else { process.stdout.write(String.fromCharCode(buf[0])); } diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index 3032464d39..9fee3e85d0 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -37,7 +37,7 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; (void)wanted_char; tud_cdc_read_char(); // discard interrupt char - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } void mp_hal_set_interrupt_char(int c) { diff --git a/ports/nrf/drivers/bluetooth/ble_uart.c b/ports/nrf/drivers/bluetooth/ble_uart.c index 64e3a05f93..96c2025d0f 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.c +++ b/ports/nrf/drivers/bluetooth/ble_uart.c @@ -193,7 +193,7 @@ STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t at for (uint16_t i = 0; i < length; i++) { #if MICROPY_KBD_EXCEPTION if (data[i] == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); m_rx_ring_buffer.start = 0; m_rx_ring_buffer.end = 0; } else diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index 4f69bfc620..af95ae4b8d 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -128,7 +128,7 @@ STATIC void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context nrfx_uart_rx(self->p_uart, &self->buf->rx_buf[0], 1); #if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION if (chr == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else #endif { diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c index 1122afcef7..1d77bc8f5d 100644 --- a/ports/rp2/mphalport.c +++ b/ports/rp2/mphalport.c @@ -52,7 +52,7 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; (void)wanted_char; tud_cdc_read_char(); // discard interrupt char - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } void mp_hal_set_interrupt_char(int c) { diff --git a/ports/rp2/uart.c b/ports/rp2/uart.c index b7991563af..bcc41bfaf5 100644 --- a/ports/rp2/uart.c +++ b/ports/rp2/uart.c @@ -41,7 +41,7 @@ void uart_irq(void) { int c = uart_getc(uart_default); #if MICROPY_KBD_EXCEPTION if (c == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); return; } #endif diff --git a/ports/samd/mphalport.c b/ports/samd/mphalport.c index 357ec93a68..a87b7d2125 100644 --- a/ports/samd/mphalport.c +++ b/ports/samd/mphalport.c @@ -35,7 +35,7 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; (void)wanted_char; tud_cdc_read_char(); // discard interrupt char - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } void mp_hal_set_interrupt_char(int c) { diff --git a/ports/stm32/pendsv.c b/ports/stm32/pendsv.c index 60b8709be3..3181ba616a 100644 --- a/ports/stm32/pendsv.c +++ b/ports/stm32/pendsv.c @@ -61,7 +61,7 @@ void pendsv_init(void) { // thread. void pendsv_kbd_intr(void) { if (MP_STATE_VM(mp_pending_exception) == MP_OBJ_NULL) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); } else { MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; pendsv_object = &MP_STATE_VM(mp_kbd_exception); diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index ef66c4fb59..220666e381 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -483,7 +483,7 @@ STATIC mp_obj_t extra_coverage(void) { } // setting the keyboard interrupt and raising it during mp_handle_pending - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_handle_pending(true); @@ -493,13 +493,13 @@ STATIC mp_obj_t extra_coverage(void) { } // setting the keyboard interrupt (twice) and cancelling it during mp_handle_pending - mp_keyboard_interrupt(); - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); mp_handle_pending(false); // setting keyboard interrupt and a pending event (intr should be handled first) mp_sched_schedule(MP_OBJ_FROM_PTR(&mp_builtin_print_obj), MP_OBJ_NEW_SMALL_INT(10)); - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); if (nlr_push(&nlr) == 0) { mp_handle_pending(true); nlr_pop(); diff --git a/ports/unix/unix_mphal.c b/ports/unix/unix_mphal.c index 28a4ca2c4a..d62991d34d 100644 --- a/ports/unix/unix_mphal.c +++ b/ports/unix/unix_mphal.c @@ -58,7 +58,7 @@ STATIC void sighandler(int signum) { // this is the second time we are called, so die straight away exit(1); } - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); #endif } } diff --git a/ports/windows/windows_mphal.c b/ports/windows/windows_mphal.c index 49daa05428..dd196f67af 100644 --- a/ports/windows/windows_mphal.c +++ b/ports/windows/windows_mphal.c @@ -84,7 +84,7 @@ BOOL WINAPI console_sighandler(DWORD evt) { // this is the second time we are called, so die straight away exit(1); } - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); return TRUE; } return FALSE; diff --git a/ports/zephyr/src/zephyr_getchar.c b/ports/zephyr/src/zephyr_getchar.c index 40dc1c3201..d75a8a76e3 100644 --- a/ports/zephyr/src/zephyr_getchar.c +++ b/ports/zephyr/src/zephyr_getchar.c @@ -21,7 +21,7 @@ #include "zephyr_getchar.h" extern int mp_interrupt_char; -void mp_keyboard_interrupt(void); +void mp_sched_keyboard_interrupt(void); static struct k_sem uart_sem; #define UART_BUFSIZE 256 @@ -36,7 +36,7 @@ static int console_irq_input_hook(uint8_t ch) return 1; } if (ch == mp_interrupt_char) { - mp_keyboard_interrupt(); + mp_sched_keyboard_interrupt(); return 1; } else { uart_ringbuf[i_put] = ch; diff --git a/py/mpconfig.h b/py/mpconfig.h index 2934f8ec89..4445e9aee2 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1508,8 +1508,8 @@ typedef double mp_float_t; #define MICROPY_WRAP_MP_SCHED_EXCEPTION(f) f #endif -#ifndef MICROPY_WRAP_MP_KEYBOARD_INTERRUPT -#define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) f +#ifndef MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT +#define MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(f) f #endif #ifndef MICROPY_WRAP_MP_SCHED_SCHEDULE diff --git a/py/runtime.h b/py/runtime.h index 9ad4bc0242..7d2cb94e84 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -65,7 +65,7 @@ void mp_init(void); void mp_deinit(void); void mp_sched_exception(mp_obj_t exc); -void mp_keyboard_interrupt(void); +void mp_sched_keyboard_interrupt(void); void mp_handle_pending(bool raise_exc); void mp_handle_pending_tail(mp_uint_t atomic_state); diff --git a/py/scheduler.c b/py/scheduler.c index f37f8c3f86..9ff930007e 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -39,7 +39,7 @@ void mp_sched_exception(mp_obj_t exc) { #if MICROPY_KBD_EXCEPTION // This function may be called asynchronously at any time so only do the bare minimum. -void MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(mp_keyboard_interrupt)(void) { +void MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(mp_sched_keyboard_interrupt)(void) { MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; mp_sched_exception(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); } From 916c3fd23fc4b636a8007525c3bd6308d01509d0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 25 Apr 2021 22:24:49 +1000 Subject: [PATCH 048/349] py/scheduler: Add optional port hook for when something is scheduled. So that a port can "wake up" when there is work to do. Signed-off-by: Damien George --- py/mpconfig.h | 6 ++++++ py/scheduler.c | 1 + 2 files changed, 7 insertions(+) diff --git a/py/mpconfig.h b/py/mpconfig.h index 4445e9aee2..7337994a5e 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -550,6 +550,12 @@ #define MICROPY_VM_HOOK_RETURN #endif +// Hook for mp_sched_schedule when a function gets scheduled on sched_queue +// (this macro executes within an atomic section) +#ifndef MICROPY_SCHED_HOOK_SCHEDULED +#define MICROPY_SCHED_HOOK_SCHEDULED +#endif + // Whether to include the garbage collector #ifndef MICROPY_ENABLE_GC #define MICROPY_ENABLE_GC (0) diff --git a/py/scheduler.c b/py/scheduler.c index 9ff930007e..947510c68b 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -134,6 +134,7 @@ bool MICROPY_WRAP_MP_SCHED_SCHEDULE(mp_sched_schedule)(mp_obj_t function, mp_obj uint8_t iput = IDX_MASK(MP_STATE_VM(sched_idx) + MP_STATE_VM(sched_len)++); MP_STATE_VM(sched_queue)[iput].func = function; MP_STATE_VM(sched_queue)[iput].arg = arg; + MICROPY_SCHED_HOOK_SCHEDULED; ret = true; } else { // schedule queue is full From d120859857e9e34bded146977f18a2be8c53ce7b Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 25 Apr 2021 22:28:55 +1000 Subject: [PATCH 049/349] zephyr: Run scheduled callbacks at REPL and during mp_hal_delay_ms. And ctrl-C can now interrupt a time.sleep call. This uses Zephyr's k_poll API to wait efficiently for an event signal, and an optional semaphore. Signed-off-by: Damien George --- ports/zephyr/CMakeLists.txt | 1 + ports/zephyr/main.c | 2 + ports/zephyr/mpconfigport.h | 3 ++ ports/zephyr/mphalport.c | 74 +++++++++++++++++++++++++++++++ ports/zephyr/mphalport.h | 5 ++- ports/zephyr/prj.conf | 1 + ports/zephyr/prj_minimal.conf | 1 + ports/zephyr/src/zephyr_getchar.c | 4 ++ 8 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 ports/zephyr/mphalport.c diff --git a/ports/zephyr/CMakeLists.txt b/ports/zephyr/CMakeLists.txt index 716642979a..e30759e064 100644 --- a/ports/zephyr/CMakeLists.txt +++ b/ports/zephyr/CMakeLists.txt @@ -46,6 +46,7 @@ set(MICROPY_SOURCE_PORT modutime.c modzephyr.c modzsensor.c + mphalport.c uart_core.c zephyr_storage.c ) diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index 74785cc830..f8ec0a0d27 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -45,6 +45,7 @@ #include "py/runtime.h" #include "py/repl.h" #include "py/gc.h" +#include "py/mphal.h" #include "py/stackctrl.h" #include "lib/utils/pyexec.h" #include "lib/mp-readline/readline.h" @@ -123,6 +124,7 @@ int real_main(void) { mp_stack_set_limit(CONFIG_MAIN_STACK_SIZE - 512); init_zephyr(); + mp_hal_init(); #ifdef TEST static const char *argv[] = {"test"}; diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h index 966f7f7e94..162ac8a576 100644 --- a/ports/zephyr/mpconfigport.h +++ b/ports/zephyr/mpconfigport.h @@ -96,6 +96,9 @@ #define MICROPY_COMP_CONST (0) #define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0) +void mp_hal_signal_event(void); +#define MICROPY_SCHED_HOOK_SCHEDULED mp_hal_signal_event() + #define MICROPY_PY_SYS_PLATFORM "zephyr" #ifdef CONFIG_BOARD diff --git a/ports/zephyr/mphalport.c b/ports/zephyr/mphalport.c new file mode 100644 index 0000000000..4f00cbd26c --- /dev/null +++ b/ports/zephyr/mphalport.c @@ -0,0 +1,74 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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/runtime.h" +#include "py/mphal.h" + +static struct k_poll_signal wait_signal; +static struct k_poll_event wait_events[2] = { + K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, + K_POLL_MODE_NOTIFY_ONLY, + &wait_signal), + K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE, + K_POLL_MODE_NOTIFY_ONLY, + NULL, 0), +}; + +void mp_hal_init(void) { + k_poll_signal_init(&wait_signal); +} + +void mp_hal_signal_event(void) { + k_poll_signal_raise(&wait_signal, 0); +} + +void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) { + mp_uint_t t0 = mp_hal_ticks_ms(); + if (sem) { + k_poll_event_init(&wait_events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, sem); + } + for (;;) { + k_timeout_t wait; + if (timeout_ms == (uint32_t)-1) { + wait = K_FOREVER; + } else { + uint32_t dt = mp_hal_ticks_ms() - t0; + if (dt >= timeout_ms) { + return; + } + wait = K_MSEC(timeout_ms - dt); + } + k_poll(wait_events, sem ? 2 : 1, wait); + if (wait_events[0].state == K_POLL_STATE_SIGNALED) { + wait_events[0].signal->signaled = 0; + wait_events[0].state = K_POLL_STATE_NOT_READY; + mp_handle_pending(true); + } else if (sem && wait_events[1].state == K_POLL_STATE_SEM_AVAILABLE) { + wait_events[1].state = K_POLL_STATE_NOT_READY; + return; + } + } +} diff --git a/ports/zephyr/mphalport.h b/ports/zephyr/mphalport.h index b3154b649b..63a18e1388 100644 --- a/ports/zephyr/mphalport.h +++ b/ports/zephyr/mphalport.h @@ -1,6 +1,9 @@ #include #include "lib/utils/interrupt_char.h" +void mp_hal_init(void); +void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms); + static inline mp_uint_t mp_hal_ticks_us(void) { return k_cyc_to_ns_floor64(k_cycle_get_32()) / 1000; } @@ -21,7 +24,7 @@ static inline void mp_hal_delay_us(mp_uint_t delay) { } static inline void mp_hal_delay_ms(mp_uint_t delay) { - k_msleep(delay); + mp_hal_wait_sem(NULL, delay); } static inline uint64_t mp_hal_time_ns(void) { diff --git a/ports/zephyr/prj.conf b/ports/zephyr/prj.conf index c9c2e96da9..9e855036d2 100644 --- a/ports/zephyr/prj.conf +++ b/ports/zephyr/prj.conf @@ -13,6 +13,7 @@ CONFIG_CONSOLE_PUTCHAR_BUFSIZE=128 CONFIG_NEWLIB_LIBC=y CONFIG_FPU=y CONFIG_MAIN_STACK_SIZE=4736 +CONFIG_POLL=y # Enable sensor subsystem (doesn't add code if not used). # Specific sensors should be enabled per-board. diff --git a/ports/zephyr/prj_minimal.conf b/ports/zephyr/prj_minimal.conf index 8b2104925a..806e26af77 100644 --- a/ports/zephyr/prj_minimal.conf +++ b/ports/zephyr/prj_minimal.conf @@ -1,6 +1,7 @@ CONFIG_NEWLIB_LIBC=y CONFIG_FPU=y CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_POLL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_CONSOLE_SUBSYS=y diff --git a/ports/zephyr/src/zephyr_getchar.c b/ports/zephyr/src/zephyr_getchar.c index d75a8a76e3..95d0b49959 100644 --- a/ports/zephyr/src/zephyr_getchar.c +++ b/ports/zephyr/src/zephyr_getchar.c @@ -22,6 +22,8 @@ extern int mp_interrupt_char; void mp_sched_keyboard_interrupt(void); +void mp_hal_signal_event(void); +void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms); static struct k_sem uart_sem; #define UART_BUFSIZE 256 @@ -36,6 +38,7 @@ static int console_irq_input_hook(uint8_t ch) return 1; } if (ch == mp_interrupt_char) { + mp_hal_signal_event(); mp_sched_keyboard_interrupt(); return 1; } else { @@ -49,6 +52,7 @@ static int console_irq_input_hook(uint8_t ch) } uint8_t zephyr_getchar(void) { + mp_hal_wait_sem(&uart_sem, -1); k_sem_take(&uart_sem, K_FOREVER); unsigned int key = irq_lock(); uint8_t c = uart_ringbuf[i_get++]; From b46a033e25eef64b8ef52a8408f99b666d32daae Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 26 Apr 2021 00:36:27 +1000 Subject: [PATCH 050/349] zephyr/modmachine: Add machine.idle(). Signed-off-by: Damien George --- ports/zephyr/modmachine.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/zephyr/modmachine.c b/ports/zephyr/modmachine.c index 107895bea0..4353083eeb 100644 --- a/ports/zephyr/modmachine.c +++ b/ports/zephyr/modmachine.c @@ -53,12 +53,19 @@ STATIC mp_obj_t machine_reset_cause(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); +STATIC mp_obj_t machine_idle(void) { + k_yield(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle); + STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, #ifdef CONFIG_REBOOT { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, + { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) }, #if MICROPY_PY_MACHINE_I2C { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_hard_i2c_type) }, From 888664130c6605f333a6901e821589dee43f6ebb Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 11:12:14 +1000 Subject: [PATCH 051/349] zephyr/boards: Add config for nucleo_wb55rg board. This board does not work with CONFIG_NETWORKING enabled. And CONFIG_CONSOLE_SUBSYS is enabled so that ctrl-C works. Signed-off-by: Damien George --- ports/zephyr/boards/nucleo_wb55rg.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 ports/zephyr/boards/nucleo_wb55rg.conf diff --git a/ports/zephyr/boards/nucleo_wb55rg.conf b/ports/zephyr/boards/nucleo_wb55rg.conf new file mode 100644 index 0000000000..369dabddeb --- /dev/null +++ b/ports/zephyr/boards/nucleo_wb55rg.conf @@ -0,0 +1,2 @@ +CONFIG_CONSOLE_SUBSYS=n +CONFIG_NETWORKING=n From 76dab3bf31617e707a874a6c0dfc49af97640980 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 30 Apr 2021 10:12:04 +1000 Subject: [PATCH 052/349] tests/run-multitests.py: Provide some convenient serial device shorcuts. It's now possible to specify a device serial port using shorcuts like: $ ./run-multitests.py -i pyb:a0 -i pyb:u1 multi_bluetooth/*.py Signed-off-by: Damien George --- tests/run-multitests.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/run-multitests.py b/tests/run-multitests.py index cdb2730eda..3163a48e63 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -160,7 +160,17 @@ class PyInstanceSubProcess(PyInstance): class PyInstancePyboard(PyInstance): + @staticmethod + def map_device_shortcut(device): + if device[0] == "a" and device[1:].isdigit(): + return "/dev/ttyACM" + device[1:] + elif device[0] == "u" and device[1:].isdigit(): + return "/dev/ttyUSB" + device[1:] + else: + return device + def __init__(self, device): + device = self.map_device_shortcut(device) self.device = device self.pyb = pyboard.Pyboard(device) self.pyb.enter_raw_repl() From 1d9528210b8a29be7e799be37224706633f7a4d5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 10 Mar 2021 23:32:59 +1100 Subject: [PATCH 053/349] tests/multi_bluetooth: Add performance test for gatt char writes. Signed-off-by: Damien George --- tests/multi_bluetooth/perf_gatt_char_write.py | 151 ++++++++++++++++++ .../perf_gatt_char_write.py.exp | 24 +++ 2 files changed, 175 insertions(+) create mode 100644 tests/multi_bluetooth/perf_gatt_char_write.py create mode 100644 tests/multi_bluetooth/perf_gatt_char_write.py.exp diff --git a/tests/multi_bluetooth/perf_gatt_char_write.py b/tests/multi_bluetooth/perf_gatt_char_write.py new file mode 100644 index 0000000000..00607f0090 --- /dev/null +++ b/tests/multi_bluetooth/perf_gatt_char_write.py @@ -0,0 +1,151 @@ +# Write characteristic from central to peripheral and time data rate. + +from micropython import const +import time, machine, bluetooth + +TIMEOUT_MS = 2000 + +_IRQ_CENTRAL_CONNECT = const(1) +_IRQ_CENTRAL_DISCONNECT = const(2) +_IRQ_GATTS_WRITE = const(3) +_IRQ_PERIPHERAL_CONNECT = const(7) +_IRQ_PERIPHERAL_DISCONNECT = const(8) +_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11) +_IRQ_GATTC_CHARACTERISTIC_DONE = const(12) +_IRQ_GATTC_WRITE_DONE = const(17) +_IRQ_MTU_EXCHANGED = const(21) + +# How long to run the test for. +_NUM_NOTIFICATIONS = const(40) +_MTU_SIZE = const(131) +_CHAR_SIZE = const(_MTU_SIZE - 3) + +SERVICE_UUID = bluetooth.UUID("A5A5A5A5-FFFF-9999-1111-5A5A5A5A5A5A") +CHAR_UUID = bluetooth.UUID("00000000-1111-2222-3333-444444444444") +CHAR = (CHAR_UUID, bluetooth.FLAG_WRITE | bluetooth.FLAG_WRITE_NO_RESPONSE) +SERVICE = (SERVICE_UUID, (CHAR,)) +SERVICES = (SERVICE,) + +packet_sequence = 0 +waiting_events = {} + + +def irq(event, data): + if event == _IRQ_CENTRAL_CONNECT: + waiting_events[event] = data[0] + elif event == _IRQ_PERIPHERAL_CONNECT: + waiting_events[event] = data[0] + elif event == _IRQ_GATTS_WRITE: + global packet_sequence + conn_handle, attr_handle = data + data = ble.gatts_read(attr_handle) + if not (data[0] == packet_sequence and data[-1] == (256 - packet_sequence) & 0xFF): + print("_IRQ_GATTS_WRITE data invalid:", packet_sequence, data) + elif packet_sequence % 10 == 0: + print("_IRQ_GATTS_WRITE", packet_sequence) + packet_sequence += 1 + elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT: + # conn_handle, def_handle, value_handle, properties, uuid = data + if data[-1] == CHAR_UUID: + waiting_events[event] = data[2] + else: + return + elif event == _IRQ_MTU_EXCHANGED: + # ATT MTU exchange complete (either initiated by us or the remote device). + conn_handle, mtu = data + print("_IRQ_MTU_EXCHANGED:", mtu) + + if event not in waiting_events: + waiting_events[event] = None + + +def wait_for_event(event, timeout_ms): + t0 = time.ticks_ms() + while time.ticks_diff(time.ticks_ms(), t0) < timeout_ms: + if event in waiting_events: + return waiting_events.pop(event) + machine.idle() + raise ValueError("Timeout waiting for {}".format(event)) + + +# Acting in peripheral role. +def instance0(): + multitest.globals(BDADDR=ble.config("mac")) + ((char_handle,),) = ble.gatts_register_services(SERVICES) + ble.gatts_set_buffer(char_handle, _CHAR_SIZE) + print("gap_advertise") + ble.gap_advertise(20_000, b"\x02\x01\x06\x04\xffMPY") + multitest.next() + try: + # Wait for central to connect to us. + conn_handle = wait_for_event(_IRQ_CENTRAL_CONNECT, TIMEOUT_MS) + # Wait for central to disconnect us. + wait_for_event(_IRQ_CENTRAL_DISCONNECT, 30000) + print("final packet_sequence:", packet_sequence) + finally: + ble.active(0) + + +# Acting in central role. +def instance1(): + global packet_sequence + ((char_handle,),) = ble.gatts_register_services(SERVICES) + multitest.next() + try: + # Connect to peripheral and then disconnect. + print("gap_connect") + ble.config(mtu=_MTU_SIZE) + ble.gap_connect(*BDADDR) + conn_handle = wait_for_event(_IRQ_PERIPHERAL_CONNECT, TIMEOUT_MS) + ble.gattc_exchange_mtu(conn_handle) + + # Discover characteristics. + ble.gattc_discover_characteristics(conn_handle, 1, 65535) + value_handle = wait_for_event(_IRQ_GATTC_CHARACTERISTIC_RESULT, TIMEOUT_MS) + wait_for_event(_IRQ_GATTC_CHARACTERISTIC_DONE, TIMEOUT_MS) + + # Send data! + data = bytearray(ord("A") + (i % 64) for i in range(_CHAR_SIZE)) + for mode in (0, 1): + ticks_start = time.ticks_ms() + for i in range(_NUM_NOTIFICATIONS): + data[0] = packet_sequence + data[-1] = 256 - packet_sequence + if packet_sequence % 10 == 0: + print("gattc_write", packet_sequence) + if mode == 0: + while True: + try: + ble.gattc_write(conn_handle, value_handle, data, mode) + break + except OSError: + pass + else: + ble.gattc_write(conn_handle, value_handle, data, mode) + wait_for_event(_IRQ_GATTC_WRITE_DONE, TIMEOUT_MS) + packet_sequence += 1 + + ticks_end = time.ticks_ms() + ticks_total = time.ticks_diff(ticks_end, ticks_start) + + print( + "Did {} writes in {} ms. {} ms/write, {} bytes/sec".format( + _NUM_NOTIFICATIONS, + ticks_total, + ticks_total / _NUM_NOTIFICATIONS, + _NUM_NOTIFICATIONS * len(data) * 1000 // ticks_total, + ) + ) + + time.sleep_ms(100) + + # DIsconnect the peripheral. + print("gap_disconnect:", ble.gap_disconnect(conn_handle)) + wait_for_event(_IRQ_PERIPHERAL_DISCONNECT, 20000) + finally: + ble.active(0) + + +ble = bluetooth.BLE() +ble.active(1) +ble.irq(irq) diff --git a/tests/multi_bluetooth/perf_gatt_char_write.py.exp b/tests/multi_bluetooth/perf_gatt_char_write.py.exp new file mode 100644 index 0000000000..4dda5e04f0 --- /dev/null +++ b/tests/multi_bluetooth/perf_gatt_char_write.py.exp @@ -0,0 +1,24 @@ +--- instance0 --- +gap_advertise +_IRQ_MTU_EXCHANGED: 131 +_IRQ_GATTS_WRITE 0 +_IRQ_GATTS_WRITE 10 +_IRQ_GATTS_WRITE 20 +_IRQ_GATTS_WRITE 30 +_IRQ_GATTS_WRITE 40 +_IRQ_GATTS_WRITE 50 +_IRQ_GATTS_WRITE 60 +_IRQ_GATTS_WRITE 70 +final packet_sequence: 80 +--- instance1 --- +gap_connect +_IRQ_MTU_EXCHANGED: 131 +gattc_write 0 +gattc_write 10 +gattc_write 20 +gattc_write 30 +gattc_write 40 +gattc_write 50 +gattc_write 60 +gattc_write 70 +gap_disconnect: True From 6b7c8d3e7283a6c94687ba7dcb8beb94c2dc9eef Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 30 Apr 2021 16:26:42 +1000 Subject: [PATCH 054/349] py/runtime: Remove commented-out code from mp_deinit(). These commented-out lines of code have been unused for a long time, so remove them to avoid confusion as to why they are there. mp_obj_dict_free() never existed, this line was converted from mp_map_deinit() and commented out as soon as it was added. The call to mp_map_deinit(mp_loaded_modules_map) was commented in 1a1d11fa32ba043d22995d28cbc039cfa5f3cc46. Fixes issue #3507. Signed-off-by: Damien George --- py/runtime.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/py/runtime.c b/py/runtime.c index 18a7c8565d..1ca0702e19 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -155,9 +155,6 @@ void mp_deinit(void) { #ifdef MICROPY_PORT_DEINIT_FUNC MICROPY_PORT_DEINIT_FUNC; #endif - - // mp_obj_dict_free(&dict_main); - // mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map)); } mp_obj_t mp_load_name(qstr qst) { From 9e1b25a99e9107619c6ed607c730ea2869582799 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 30 Apr 2021 16:42:51 +1000 Subject: [PATCH 055/349] docs/library/machine: Specify initial machine.PWM class. This adds an initial specification of the machine.PWM class, to provide a way to generate PWM output that is portable across the different ports. Such functionality may already be available in one way or another (eg through a Timer object), but because configuring PWM via a Timer is very port-specific, and because it's a common thing to do, it's beneficial to have a top-level construct for it. The specification in this commit aims to provide core functionality in a minimal way. It also somewhat matches most existing ad-hoc implementations of machine.PWM. See discussion in #2283 and #4237. Signed-off-by: Damien George --- docs/library/machine.PWM.rst | 79 ++++++++++++++++++++++++++++++++++++ docs/library/machine.rst | 1 + 2 files changed, 80 insertions(+) create mode 100644 docs/library/machine.PWM.rst diff --git a/docs/library/machine.PWM.rst b/docs/library/machine.PWM.rst new file mode 100644 index 0000000000..f2273d8b45 --- /dev/null +++ b/docs/library/machine.PWM.rst @@ -0,0 +1,79 @@ +.. currentmodule:: machine +.. _machine.PWM: + +class PWM -- pulse width modulation +=================================== + +This class provides pulse width modulation output. + +Example usage:: + + from machine import PWM + + pwm = PWM(pin) # create a PWM object on a pin + pwm.duty_u16(32768) # set duty to 50% + + # reinitialise with a period of 200us, duty of 5us + pwm.init(freq=5000, duty_ns=5000) + + pwm.duty_ns(3000) # set pulse width to 3us + + pwm.deinit() + +Constructors +------------ + +.. class:: PWM(dest, \*, freq, duty_u16, duty_ns) + + Construct and return a new PWM object using the following parameters: + + - *dest* is the entity on which the PWM is output, which is usually a + :ref:`machine.Pin ` object, but a port may allow other values, + like integers. + - *freq* should be an integer which sets the frequency in Hz for the + PWM cycle. + - *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``. + - *duty_ns* sets the pulse width in nanoseconds. + + Setting *freq* may affect other PWM objects if the objects share the same + underlying PWM generator (this is hardware specific). + Only one of *duty_u16* and *duty_ns* should be specified at a time. + +Methods +------- + +.. method:: PWM.init(\*, freq, duty_u16, duty_ns) + + Modify settings for the PWM object. See the above constructor for details + about the parameters. + +.. method:: PWM.deinit() + + Disable the PWM output. + +.. method:: PWM.freq([value]) + + Get or set the current frequency of the PWM output. + + With no arguments the frequency in Hz is returned. + + With a single *value* argument the frequency is set to that value in Hz. The + method may raise a ``ValueError`` if the frequency is outside the valid range. + +.. method:: PWM.duty_u16([value]) + + Get or set the current duty cycle of the PWM output, as an unsigned 16-bit + value in the range 0 to 65535 inclusive. + + With no arguments the duty cycle is returned. + + With a single *value* argument the duty cycle is set to that value, measured + as the ratio ``value / 65535``. + +.. method:: PWM.duty_ns([value]) + + Get or set the current pulse width of the PWM output, as a value in nanoseconds. + + With no arguments the pulse width in nanoseconds is returned. + + With a single *value* argument the pulse width is set to that value. diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 18dc6f2afa..5076dc30e0 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -167,6 +167,7 @@ Classes machine.Pin.rst machine.Signal.rst machine.ADC.rst + machine.PWM.rst machine.UART.rst machine.SPI.rst machine.I2C.rst From dd5c831a0b0c960b638109f1886edc10178f51a1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 30 Apr 2021 16:55:55 +1000 Subject: [PATCH 056/349] docs/library/machine: Add machine.bootloader docs. This is provide by a few ports now, and is very useful. Signed-off-by: Damien George --- docs/library/machine.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 5076dc30e0..f831049f88 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -37,6 +37,14 @@ Reset related functions Get the reset cause. See :ref:`constants ` for the possible return values. +.. function:: bootloader([value]) + + Reset the device and enter its bootloader. This is typically used to put the + device into a state where it can be programmed with new firmware. + + Some ports support passing in an optional *value* argument which can control + which bootloader to enter, what to pass to it, or other things. + Interrupt related functions --------------------------- From aa061ae391f2a8fbb16ace31ae0e4ae35b6ad5e9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 30 Apr 2021 16:48:29 +1000 Subject: [PATCH 057/349] py/scheduler: Add missing MICROPY_WRAP_MP_SCHED_EXCEPTION usage. This was missed in commit 7cbf826a9575e18ce1b7fe11b0f0997509153260. Signed-off-by: Damien George --- py/scheduler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/scheduler.c b/py/scheduler.c index 947510c68b..0671a34a8c 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -28,7 +28,7 @@ #include "py/runtime.h" -void mp_sched_exception(mp_obj_t exc) { +void MICROPY_WRAP_MP_SCHED_EXCEPTION(mp_sched_exception)(mp_obj_t exc) { MP_STATE_VM(mp_pending_exception) = exc; #if MICROPY_ENABLE_SCHEDULER if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { From 1f1a54d0b1371efcfec6ca1b03d21b07a908c70d Mon Sep 17 00:00:00 2001 From: Kathryn Lingel Date: Mon, 6 May 2019 12:16:29 -0700 Subject: [PATCH 058/349] py/repl: Filter private methods from tab completion. Anything beginning with "_" will now only be tab-completed if there is already a partial match for such an entry. In other words, entering foo. will no longer complete/list anything beginning with "_". Originally at adafruit#1850 Signed-off-by: Kathryn Lingel --- py/repl.c | 5 +++++ tests/unix/extra_coverage.py.exp | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/py/repl.c b/py/repl.c index c758fc067b..3b1837031b 100644 --- a/py/repl.c +++ b/py/repl.c @@ -197,6 +197,11 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print for (qstr q = MP_QSTR_ + 1; q < nqstr; ++q) { size_t d_len; const char *d_str = (const char *)qstr_data(q, &d_len); + // special case; filter out words that begin with underscore + // unless there's already a partial match + if (s_len == 0 && d_str[0] == '_') { + continue; + } if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { mp_load_method_protected(obj, q, dest, true); if (dest[0] != MP_OBJ_NULL) { diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index d97de2c0ef..ab4d977741 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -28,11 +28,11 @@ RuntimeError: # repl ame__ -__class__ __name__ argv atexit -byteorder exc_info exit getsizeof -implementation maxsize modules path -platform print_exception stderr -stdin stdout version version_info +argv atexit byteorder exc_info +exit getsizeof implementation maxsize +modules path platform print_exception +stderr stdin stdout version +version_info ementation # attrtuple (start=1, stop=2, step=3) From befbff31b73d5373b5933a3762a3a3c6e871e8da Mon Sep 17 00:00:00 2001 From: scottbelden Date: Tue, 7 May 2019 13:55:20 -0400 Subject: [PATCH 059/349] py/repl: Enter four spaces when there are no matches. Originally at adafruit#1859 Signed-off-by: scottbelden --- py/repl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/repl.c b/py/repl.c index 3b1837031b..a8ae1d0695 100644 --- a/py/repl.c +++ b/py/repl.c @@ -228,6 +228,10 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print // nothing found if (q_first == 0) { + if (s_len == 0) { + *compl_str = " "; + return 4; + } // If there're no better alternatives, and if it's first word // in the line, try to complete "import". if (s_start == org_str) { From f85ea8d4fe12251100989287f1cfe14af8650217 Mon Sep 17 00:00:00 2001 From: Artyom Skrobov Date: Wed, 7 Apr 2021 13:09:39 -0400 Subject: [PATCH 060/349] py/repl: Refactor autocomplete to reduce nesting. Originally at adafruit#4548 Signed-off-by: Artyom Skrobov --- py/repl.c | 219 +++++++++++++++++++++++++++--------------------------- 1 file changed, 111 insertions(+), 108 deletions(-) diff --git a/py/repl.c b/py/repl.c index a8ae1d0695..b5ff145197 100644 --- a/py/repl.c +++ b/py/repl.c @@ -161,131 +161,134 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print mp_obj_t obj = MP_OBJ_FROM_PTR(&mp_module___main__); mp_obj_t dest[2]; + const char *s_start; + size_t s_len; + for (;;) { // get next word in string to complete - const char *s_start = str; + s_start = str; while (str < top && *str != '.') { ++str; } - size_t s_len = str - s_start; + s_len = str - s_start; - if (str < top) { - // a complete word, lookup in current object - qstr q = qstr_find_strn(s_start, s_len); - if (q == MP_QSTRnull) { - // lookup will fail - return 0; - } - mp_load_method_protected(obj, q, dest, true); - obj = dest[0]; // attribute, method, or MP_OBJ_NULL if nothing found - - if (obj == MP_OBJ_NULL) { - // lookup failed - return 0; - } - - // skip '.' to move to next word - ++str; - - } else { + if (str == top) { // end of string, do completion on this partial name + break; + } - // look for matches - const char *match_str = NULL; - size_t match_len = 0; - qstr q_first = 0, q_last = 0; - for (qstr q = MP_QSTR_ + 1; q < nqstr; ++q) { - size_t d_len; - const char *d_str = (const char *)qstr_data(q, &d_len); - // special case; filter out words that begin with underscore - // unless there's already a partial match - if (s_len == 0 && d_str[0] == '_') { - continue; - } - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { - mp_load_method_protected(obj, q, dest, true); - if (dest[0] != MP_OBJ_NULL) { - if (match_str == NULL) { - match_str = d_str; - match_len = d_len; - } else { - // search for longest common prefix of match_str and d_str - // (assumes these strings are null-terminated) - for (size_t j = s_len; j <= match_len && j <= d_len; ++j) { - if (match_str[j] != d_str[j]) { - match_len = j; - break; - } - } - } - if (q_first == 0) { - q_first = q; - } - q_last = q; - } - } - } + // a complete word, lookup in current object + qstr q = qstr_find_strn(s_start, s_len); + if (q == MP_QSTRnull) { + // lookup will fail + return 0; + } + mp_load_method_protected(obj, q, dest, true); + obj = dest[0]; // attribute, method, or MP_OBJ_NULL if nothing found - // nothing found - if (q_first == 0) { - if (s_len == 0) { - *compl_str = " "; - return 4; - } - // If there're no better alternatives, and if it's first word - // in the line, try to complete "import". - if (s_start == org_str) { - static const char import_str[] = "import "; - if (memcmp(s_start, import_str, s_len) == 0) { - *compl_str = import_str + s_len; - return sizeof(import_str) - 1 - s_len; - } - } + if (obj == MP_OBJ_NULL) { + // lookup failed + return 0; + } - return 0; - } + // skip '.' to move to next word + ++str; + } - // 1 match found, or multiple matches with a common prefix - if (q_first == q_last || match_len > s_len) { - *compl_str = match_str + s_len; - return match_len - s_len; - } - - // multiple matches found, print them out - - #define WORD_SLOT_LEN (16) - #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) - - int line_len = MAX_LINE_LEN; // force a newline for first word - for (qstr q = q_first; q <= q_last; ++q) { - size_t d_len; - const char *d_str = (const char *)qstr_data(q, &d_len); - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { - mp_load_method_protected(obj, q, dest, true); - if (dest[0] != MP_OBJ_NULL) { - int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; - if (gap < 2) { - gap += WORD_SLOT_LEN; - } - if (line_len + gap + d_len <= MAX_LINE_LEN) { - // TODO optimise printing of gap? - for (int j = 0; j < gap; ++j) { - mp_print_str(print, " "); - } - mp_print_str(print, d_str); - line_len += gap + d_len; - } else { - mp_printf(print, "\n%s", d_str); - line_len = d_len; + // look for matches + const char *match_str = NULL; + size_t match_len = 0; + qstr q_first = 0, q_last = 0; + for (qstr q = MP_QSTR_ + 1; q < nqstr; ++q) { + size_t d_len; + const char *d_str = (const char *)qstr_data(q, &d_len); + // special case; filter out words that begin with underscore + // unless there's already a partial match + if (s_len == 0 && d_str[0] == '_') { + continue; + } + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + mp_load_method_protected(obj, q, dest, true); + if (dest[0] != MP_OBJ_NULL) { + if (match_str == NULL) { + match_str = d_str; + match_len = d_len; + } else { + // search for longest common prefix of match_str and d_str + // (assumes these strings are null-terminated) + for (size_t j = s_len; j <= match_len && j <= d_len; ++j) { + if (match_str[j] != d_str[j]) { + match_len = j; + break; } } } + if (q_first == 0) { + q_first = q; + } + q_last = q; } - mp_print_str(print, "\n"); - - return (size_t)(-1); // indicate many matches } } + + // nothing found + if (q_first == 0) { + if (s_len == 0) { + *compl_str = " "; + return 4; + } + // If there're no better alternatives, and if it's first word + // in the line, try to complete "import". + if (s_start == org_str) { + static const char import_str[] = "import "; + if (memcmp(s_start, import_str, s_len) == 0) { + *compl_str = import_str + s_len; + return sizeof(import_str) - 1 - s_len; + } + } + + return 0; + } + + // 1 match found, or multiple matches with a common prefix + if (q_first == q_last || match_len > s_len) { + *compl_str = match_str + s_len; + return match_len - s_len; + } + + // multiple matches found, print them out + + #define WORD_SLOT_LEN (16) + #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) + + int line_len = MAX_LINE_LEN; // force a newline for first word + for (qstr q = q_first; q <= q_last; ++q) { + size_t d_len; + const char *d_str = (const char *)qstr_data(q, &d_len); + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + mp_load_method_protected(obj, q, dest, true); + if (dest[0] != MP_OBJ_NULL) { + int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; + if (gap < 2) { + gap += WORD_SLOT_LEN; + } + if (line_len + gap + d_len <= MAX_LINE_LEN) { + // TODO optimise printing of gap? + for (int j = 0; j < gap; ++j) { + mp_print_str(print, " "); + } + mp_print_str(print, d_str); + line_len += gap + d_len; + } else { + mp_printf(print, "\n%s", d_str); + line_len = d_len; + } + } + } + } + mp_print_str(print, "\n"); + + return (size_t)(-1); // indicate many matches } #endif // MICROPY_HELPER_REPL From 7556e01f14bb9f0ae32eff1d191985d302f1183e Mon Sep 17 00:00:00 2001 From: Artyom Skrobov Date: Sat, 3 Apr 2021 16:18:41 -0400 Subject: [PATCH 061/349] py/repl: Refactor autocomplete, extracting reusable parts. Originally at adafruit#4548 Signed-off-by: Artyom Skrobov --- py/repl.c | 152 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 66 deletions(-) diff --git a/py/repl.c b/py/repl.c index b5ff145197..c8bb715e90 100644 --- a/py/repl.c +++ b/py/repl.c @@ -143,6 +143,87 @@ bool mp_repl_continue_with_input(const char *input) { return false; } +STATIC bool test_qstr(mp_obj_t obj, qstr name) { + // try object member + mp_obj_t dest[2]; + mp_load_method_protected(obj, name, dest, true); + return dest[0] != MP_OBJ_NULL; +} + +STATIC const char *find_completions(const char *s_start, size_t s_len, + mp_obj_t obj, size_t *match_len, qstr *q_first, qstr *q_last) { + + const char *match_str = NULL; + *match_len = 0; + *q_first = *q_last = 0; + size_t nqstr = QSTR_TOTAL(); + for (qstr q = MP_QSTR_ + 1; q < nqstr; ++q) { + size_t d_len; + const char *d_str = (const char *)qstr_data(q, &d_len); + // special case; filter out words that begin with underscore + // unless there's already a partial match + if (s_len == 0 && d_str[0] == '_') { + continue; + } + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + if (test_qstr(obj, q)) { + if (match_str == NULL) { + match_str = d_str; + *match_len = d_len; + } else { + // search for longest common prefix of match_str and d_str + // (assumes these strings are null-terminated) + for (size_t j = s_len; j <= *match_len && j <= d_len; ++j) { + if (match_str[j] != d_str[j]) { + *match_len = j; + break; + } + } + } + if (*q_first == 0) { + *q_first = q; + } + *q_last = q; + } + } + } + return match_str; +} + +STATIC void print_completions(const mp_print_t *print, + const char *s_start, size_t s_len, + mp_obj_t obj, qstr q_first, qstr q_last) { + + #define WORD_SLOT_LEN (16) + #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) + + int line_len = MAX_LINE_LEN; // force a newline for first word + for (qstr q = q_first; q <= q_last; ++q) { + size_t d_len; + const char *d_str = (const char *)qstr_data(q, &d_len); + if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { + if (test_qstr(obj, q)) { + int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; + if (gap < 2) { + gap += WORD_SLOT_LEN; + } + if (line_len + gap + d_len <= MAX_LINE_LEN) { + // TODO optimise printing of gap? + for (int j = 0; j < gap; ++j) { + mp_print_str(print, " "); + } + mp_print_str(print, d_str); + line_len += gap + d_len; + } else { + mp_printf(print, "\n%s", d_str); + line_len = d_len; + } + } + } + } + mp_print_str(print, "\n"); +} + size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print, const char **compl_str) { // scan backwards to find start of "a.b.c" chain const char *org_str = str; @@ -155,8 +236,6 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } } - size_t nqstr = QSTR_TOTAL(); - // begin search in outer global dict which is accessed from __main__ mp_obj_t obj = MP_OBJ_FROM_PTR(&mp_module___main__); mp_obj_t dest[2]; @@ -196,40 +275,10 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } // look for matches - const char *match_str = NULL; - size_t match_len = 0; - qstr q_first = 0, q_last = 0; - for (qstr q = MP_QSTR_ + 1; q < nqstr; ++q) { - size_t d_len; - const char *d_str = (const char *)qstr_data(q, &d_len); - // special case; filter out words that begin with underscore - // unless there's already a partial match - if (s_len == 0 && d_str[0] == '_') { - continue; - } - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { - mp_load_method_protected(obj, q, dest, true); - if (dest[0] != MP_OBJ_NULL) { - if (match_str == NULL) { - match_str = d_str; - match_len = d_len; - } else { - // search for longest common prefix of match_str and d_str - // (assumes these strings are null-terminated) - for (size_t j = s_len; j <= match_len && j <= d_len; ++j) { - if (match_str[j] != d_str[j]) { - match_len = j; - break; - } - } - } - if (q_first == 0) { - q_first = q; - } - q_last = q; - } - } - } + size_t match_len; + qstr q_first, q_last; + const char *match_str = + find_completions(s_start, s_len, obj, &match_len, &q_first, &q_last); // nothing found if (q_first == 0) { @@ -257,36 +306,7 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print } // multiple matches found, print them out - - #define WORD_SLOT_LEN (16) - #define MAX_LINE_LEN (4 * WORD_SLOT_LEN) - - int line_len = MAX_LINE_LEN; // force a newline for first word - for (qstr q = q_first; q <= q_last; ++q) { - size_t d_len; - const char *d_str = (const char *)qstr_data(q, &d_len); - if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { - mp_load_method_protected(obj, q, dest, true); - if (dest[0] != MP_OBJ_NULL) { - int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; - if (gap < 2) { - gap += WORD_SLOT_LEN; - } - if (line_len + gap + d_len <= MAX_LINE_LEN) { - // TODO optimise printing of gap? - for (int j = 0; j < gap; ++j) { - mp_print_str(print, " "); - } - mp_print_str(print, d_str); - line_len += gap + d_len; - } else { - mp_printf(print, "\n%s", d_str); - line_len = d_len; - } - } - } - } - mp_print_str(print, "\n"); + print_completions(print, s_start, s_len, obj, q_first, q_last); return (size_t)(-1); // indicate many matches } From ca35c0059c8895839809f3e11873f96fc8cb4ab5 Mon Sep 17 00:00:00 2001 From: Artyom Skrobov Date: Sat, 3 Apr 2021 16:56:02 -0400 Subject: [PATCH 062/349] py/repl: Autocomplete builtin modules. Doing "import " will now complete/list built-in modules. Originally at adafruit#4548 and adafruit#4608 Signed-off-by: Artyom Skrobov --- ports/unix/coverage.c | 7 +++++++ py/repl.c | 34 +++++++++++++++++++++----------- tests/unix/extra_coverage.py.exp | 14 +++++++++++++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 220666e381..d5b5d8dd76 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -268,6 +268,13 @@ STATIC mp_obj_t extra_coverage(void) { size_t len = mp_repl_autocomplete("__n", 3, &mp_plat_print, &str); mp_printf(&mp_plat_print, "%.*s\n", (int)len, str); + len = mp_repl_autocomplete("i", 1, &mp_plat_print, &str); + mp_printf(&mp_plat_print, "%.*s\n", (int)len, str); + mp_repl_autocomplete("import ", 7, &mp_plat_print, &str); + len = mp_repl_autocomplete("import ut", 9, &mp_plat_print, &str); + mp_printf(&mp_plat_print, "%.*s\n", (int)len, str); + mp_repl_autocomplete("import utime", 12, &mp_plat_print, &str); + mp_store_global(MP_QSTR_sys, mp_import_name(MP_QSTR_sys, mp_const_none, MP_OBJ_NEW_SMALL_INT(0))); mp_repl_autocomplete("sys.", 4, &mp_plat_print, &str); len = mp_repl_autocomplete("sys.impl", 8, &mp_plat_print, &str); diff --git a/py/repl.c b/py/repl.c index c8bb715e90..57bc21eff0 100644 --- a/py/repl.c +++ b/py/repl.c @@ -26,6 +26,7 @@ #include #include "py/obj.h" +#include "py/objmodule.h" #include "py/runtime.h" #include "py/builtin.h" #include "py/repl.h" @@ -144,10 +145,16 @@ bool mp_repl_continue_with_input(const char *input) { } STATIC bool test_qstr(mp_obj_t obj, qstr name) { - // try object member - mp_obj_t dest[2]; - mp_load_method_protected(obj, name, dest, true); - return dest[0] != MP_OBJ_NULL; + if (obj) { + // try object member + mp_obj_t dest[2]; + mp_load_method_protected(obj, name, dest, true); + return dest[0] != MP_OBJ_NULL; + } else { + // try builtin module + return mp_map_lookup((mp_map_t *)&mp_builtin_module_map, + MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP); + } } STATIC const char *find_completions(const char *s_start, size_t s_len, @@ -274,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; @@ -282,21 +295,18 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print // nothing found if (q_first == 0) { - if (s_len == 0) { - *compl_str = " "; - return 4; - } // If there're no better alternatives, and if it's first word // in the line, try to complete "import". - if (s_start == org_str) { - 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; } } - - return 0; + if (q_first == 0) { + *compl_str = " "; + return s_len ? 0 : 4; + } } // 1 match found, or multiple matches with a common prefix diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index ab4d977741..ea91813fc6 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -27,6 +27,20 @@ RuntimeError: RuntimeError: # repl ame__ +mport + +builtins micropython _thread _uasyncio +btree cexample cmath cppexample +ffi framebuf gc math +termios uarray ubinascii ucollections +ucryptolib uctypes uerrno uhashlib +uheapq uio ujson umachine +uos urandom ure uselect +usocket ussl ustruct usys +utime utimeq uwebsocket uzlib +ime + +utime utimeq argv atexit byteorder exc_info exit getsizeof implementation maxsize From 3c918d0f5817a32acf28831017b0873771810f06 Mon Sep 17 00:00:00 2001 From: Jan Jurgen Griesfeller Date: Thu, 29 Apr 2021 09:26:38 +0200 Subject: [PATCH 063/349] rp2/boards: Add board definition for SparkFun Thing Plus RP2040. --- ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.cmake | 1 + ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.cmake create mode 100644 ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h diff --git a/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.cmake b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.cmake new file mode 100644 index 0000000000..b9090bbcec --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.cmake @@ -0,0 +1 @@ +# cmake file for SparkFun Thing Plus RP2040 diff --git a/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h new file mode 100644 index 0000000000..9749acd25a --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_THINGPLUS/mpconfigboard.h @@ -0,0 +1,3 @@ +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "SparkFun Thing Plus RP2040" +#define MICROPY_HW_FLASH_STORAGE_BYTES (15 * 1024 * 1024) From d80a037e6bdcc78fbda76ce04e9ded41f335c635 Mon Sep 17 00:00:00 2001 From: Jan Jurgen Griesfeller Date: Thu, 29 Apr 2021 11:26:38 +0200 Subject: [PATCH 064/349] rp2/boards: Add board definition for SparkFun Pro Micro board. --- ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.cmake | 1 + ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.cmake create mode 100644 ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h diff --git a/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.cmake b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.cmake new file mode 100644 index 0000000000..6ac8d7a446 --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.cmake @@ -0,0 +1 @@ +# cmake file for SparkFun Pro Micro RP2040 diff --git a/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h new file mode 100644 index 0000000000..d6c8007ba0 --- /dev/null +++ b/ports/rp2/boards/SPARKFUN_PROMICRO/mpconfigboard.h @@ -0,0 +1,3 @@ +// Board and hardware specific configuration +#define MICROPY_HW_BOARD_NAME "SparkFun Pro Micro RP2040" +#define MICROPY_HW_FLASH_STORAGE_BYTES (15 * 1024 * 1024) From 1e2f0d2809c5431c9baf1d6f447162013f58baac Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 29 Apr 2021 16:56:28 +0200 Subject: [PATCH 065/349] rp2/tusb_port: Add the device unique-id to the USB id. The number shown in the USB id is now the same as that returned by machine.unique_id(). All 8 bytes are inserted as hex into the USB id. A usb id at /dev/serial/by-id then looks like: usb-MicroPython_Board_in_FS_mode_e469b03567342f37-if00 --- ports/rp2/tusb_port.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/ports/rp2/tusb_port.c b/ports/rp2/tusb_port.c index 94856ab452..874d837b9b 100644 --- a/ports/rp2/tusb_port.c +++ b/ports/rp2/tusb_port.c @@ -25,6 +25,7 @@ */ #include "tusb.h" +#include "pico/unique_id.h" #define USBD_VID (0x2E8A) // Raspberry Pi #define USBD_PID (0x0005) // RP2 MicroPython @@ -77,7 +78,7 @@ static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = { static const char *const usbd_desc_str[] = { [USBD_STR_MANUF] = "MicroPython", [USBD_STR_PRODUCT] = "Board in FS mode", - [USBD_STR_SERIAL] = "000000000000", // TODO + [USBD_STR_SERIAL] = NULL, // generated dynamically [USBD_STR_CDC] = "Board CDC", }; @@ -102,9 +103,21 @@ const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) { return NULL; } - const char *str = usbd_desc_str[index]; - for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) { - desc_str[1 + len] = str[len]; + // check, if serial is requested + if (index == USBD_STR_SERIAL) { + pico_unique_board_id_t id; + pico_get_unique_board_id(&id); + // byte by byte conversion + for (len = 0; len < 16; len += 2) { + const char *hexdig = "0123456789abcdef"; + desc_str[1 + len] = hexdig[id.id[len >> 1] >> 4]; + desc_str[1 + len + 1] = hexdig[id.id[len >> 1] & 0x0f]; + } + } else { + const char *str = usbd_desc_str[index]; + for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) { + desc_str[1 + len] = str[len]; + } } } From 4154ffbcba48822338ece6bbdb42f4a0498f237e Mon Sep 17 00:00:00 2001 From: Chris Liechti Date: Tue, 8 Nov 2016 21:53:03 +0100 Subject: [PATCH 066/349] docs/esp8266: Add note about simultaneous use of STA_IF and AP_IF. See also https://github.com/esp8266/Arduino/issues/1624 --- docs/esp8266/general.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/esp8266/general.rst b/docs/esp8266/general.rst index fbe8fe1c3c..ce51f531b9 100644 --- a/docs/esp8266/general.rst +++ b/docs/esp8266/general.rst @@ -125,6 +125,16 @@ will overflow every 7:45h. If a long-term working RTC time is required then ``time()`` or ``localtime()`` must be called at least once within 7 hours. MicroPython will then handle the overflow. +Simultaneous operation of STA_IF and AP_IF +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Simultaneous operation of STA_IF and AP_IF interfaces is supported. + +However, due to restrictions of the hardware, there may be performance +issues in the AP_IF, if the STA_IF is not connected and searching. +An application should manage these interfaces and for example +deactivate the STA_IF in environments where only the AP_IF is used. + Sockets and WiFi buffers overflow ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 2bf1beef5ce2edde80ba7a24dde781fe1b1692a4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 May 2021 14:24:17 +1000 Subject: [PATCH 067/349] docs/esp8266: Add instructions on entering programming mode manually. This adds to the ESP8266 tutorial instructions explaining which pins to pull low to enter programming mode. Commit made originally by @ARF1 in #2910. Signed-off-by: Damien George --- docs/esp8266/tutorial/intro.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst index 711db3fceb..bbf0457fff 100644 --- a/docs/esp8266/tutorial/intro.rst +++ b/docs/esp8266/tutorial/intro.rst @@ -75,6 +75,10 @@ the DTR and RTS pins wired in a special way then deploying the firmware should be easy as all steps can be done automatically. Boards that have such features include the Adafruit Feather HUZZAH and NodeMCU boards. +If you do not have such a board, you need keep GPIO0 pulled to ground and reset +the device by pulling the reset pin to ground and releasing it again to enter +programming mode. + For best results it is recommended to first erase the entire flash of your device before putting on new MicroPython firmware. @@ -113,6 +117,10 @@ the firmware (note the ``-fm dio`` option):: If the above commands run without error then MicroPython should be installed on your board! +If you pulled GPIO0 manually to ground to enter programming mode, release it +now and reset the device by again pulling the reset pin to ground for a short +duration. + Serial prompt ------------- From d70ab87b2b108aa9d5321c272911f759ad3ee8a9 Mon Sep 17 00:00:00 2001 From: Mordy Ovits Date: Thu, 2 Nov 2017 14:31:17 -0400 Subject: [PATCH 068/349] docs/esp8266: Clarify limitations of SSL in esp8266 and fix typos. --- docs/esp8266/general.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/esp8266/general.rst b/docs/esp8266/general.rst index ce51f531b9..4999bc2e9b 100644 --- a/docs/esp8266/general.rst +++ b/docs/esp8266/general.rst @@ -163,25 +163,26 @@ SSL/TLS limitations ~~~~~~~~~~~~~~~~~~~ ESP8266 uses `axTLS `_ library, which is one -of the smallest TLS libraries with the compatible licensing. However, it +of the smallest TLS libraries with compatible licensing. However, it also has some known issues/limitations: 1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve - cryptography (ECC). This means it can't work with sites which force - the use of these features (it works ok with classic RSA certificates). + cryptography (ECC). This means it can't work with sites which require + the use of these features (it works ok with the typical sites that use + RSA certificates). 2. Half-duplex communication nature. axTLS uses a single buffer for both sending and receiving, which leads to considerable memory saving and works well with protocols like HTTP. But there may be problems with protocols which don't follow classic request-response model. -Besides axTLS own limitations, the configuration used for MicroPython is +Besides axTLS's own limitations, the configuration used for MicroPython is highly optimized for code size, which leads to additional limitations (these may be lifted in the future): 3. Optimized RSA algorithms are not enabled, which may lead to slow SSL handshakes. -4. Stored sessions are not supported (may allow faster repeated connections - to the same site in some circumstances). +4. Session Reuse is not enabled, which means every connection must undergo + the full, expensive SSL handshake. Besides axTLS specific limitations described above, there's another generic limitation with usage of TLS on the low-memory devices: @@ -195,13 +196,16 @@ limitation with usage of TLS on the low-memory devices: accessing various REST APIs, which usually require much smaller messages. The buffers size is on the order of 5KB, and is adjusted from time to time, taking as a reference being able to access https://google.com . - The smaller buffer hower means that some sites can't be accessed using - it, and it's not possible to stream large amounts of data. + The smaller buffer however means that some sites can't be accessed using + it, and it's not possible to stream large amounts of data. axTLS does + have support for TLS's Max Fragment Size extension, but no HTTPS website + does, so use of the extension is really only effective for local + communication with other devices. There are also some not implemented features specifically in MicroPython's ``ussl`` module based on axTLS: -6. Certificates are not validated (this may make connections susceptible +6. Certificates are not validated (this makes connections susceptible to man-in-the-middle attacks). 7. There is no support for client certificates (scheduled to be fixed in 1.9.4 release). From ca0c75f5042cdf602585b08184f132d7ab4713f3 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 30 Apr 2021 14:41:20 -0500 Subject: [PATCH 069/349] stm32/boards: Change default LSI_VALUE to 32000 for F4 MCUs. In the STM32 HAL libraries, the default value for LSI_VALUE for F4 MCUs is 32 kHz. Signed-off-by: David Lechner --- ports/stm32/boards/stm32f4xx_hal_conf_base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/boards/stm32f4xx_hal_conf_base.h b/ports/stm32/boards/stm32f4xx_hal_conf_base.h index 134a30018c..f09990fd95 100644 --- a/ports/stm32/boards/stm32f4xx_hal_conf_base.h +++ b/ports/stm32/boards/stm32f4xx_hal_conf_base.h @@ -88,7 +88,7 @@ // Oscillator values in Hz #define HSI_VALUE (16000000) -#define LSI_VALUE (40000) +#define LSI_VALUE (32000) // SysTick has the highest priority #define TICK_INT_PRIORITY (0x00) From 6e776a671061130d86a300fcd72173d9b93f521a Mon Sep 17 00:00:00 2001 From: Nicko van Someren Date: Sun, 2 May 2021 18:12:58 -0600 Subject: [PATCH 070/349] gitignore: Ignore macOS desktop metadata files. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c52f59eec7..7342489927 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,7 @@ user.props # Generated rst files ###################### genrst/ + +# MacOS desktop metadata files +###################### +.DS_Store From 31ac410a4fbf18b38b6f4557045959140026680e Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 16:53:36 +1000 Subject: [PATCH 071/349] docs: Fix some spelling mistakes. --- docs/develop/cmodules.rst | 2 +- docs/esp32/quickref.rst | 2 +- docs/esp8266/quickref.rst | 2 +- docs/library/esp32.rst | 2 +- docs/library/machine.Timer.rst | 2 +- docs/library/machine.TimerWiPy.rst | 4 ++-- docs/library/network.rst | 2 +- docs/library/uctypes.rst | 2 +- docs/library/uio.rst | 8 ++++---- docs/library/uselect.rst | 4 ++-- docs/library/usocket.rst | 2 +- docs/library/utime.rst | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/develop/cmodules.rst b/docs/develop/cmodules.rst index 346b3e0314..38225e8686 100644 --- a/docs/develop/cmodules.rst +++ b/docs/develop/cmodules.rst @@ -91,7 +91,7 @@ This simple module named ``cexample`` provides a single function ``cexample.add_ints(a, b)`` which adds the two integer args together and returns the result. It can be found in the MicroPython source tree `in the examples directory `_ -and has a source file and a Makefile fragment with content as descibed above:: +and has a source file and a Makefile fragment with content as described above:: micropython/ └──examples/ diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 30c9b3b95a..c29688f000 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -58,7 +58,7 @@ The :mod:`esp32` module:: import esp32 esp32.hall_sensor() # read the internal hall sensor - esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit + esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit esp32.ULP() # access to the Ultra-Low-Power Co-processor Note that the temperature sensor in the ESP32 will typically read higher than diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index a478b66581..b9a46ab112 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -58,7 +58,7 @@ The :mod:`network` module:: wlan.scan() # scan for access points wlan.isconnected() # check if the station is connected to an AP wlan.connect('essid', 'password') # connect to an AP - wlan.config('mac') # get the interface's MAC adddress + wlan.config('mac') # get the interface's MAC address wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses ap = network.WLAN(network.AP_IF) # create access-point interface diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index f179a31ef6..1cfb304c14 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -162,7 +162,7 @@ used to transmit or receive many other types of digital signals:: The input to the RMT module is an 80MHz clock (in the future it may be able to configure the input clock but, for now, it's fixed). ``clock_div`` *divides* the clock input which determines the resolution of the RMT channel. The -numbers specificed in ``write_pulses`` are multiplied by the resolution to +numbers specified in ``write_pulses`` are multiplied by the resolution to define the pulses. ``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index 9991d3aebc..77a549b40b 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -9,7 +9,7 @@ the most flexible and heterogeneous kind of hardware in MCUs and SoCs, differently greatly from a model to a model. MicroPython's Timer class defines a baseline operation of executing a callback with a given period (or once after some delay), and allow specific boards to define more -non-standard behavior (which thus won't be portable to other boards). +non-standard behaviour (which thus won't be portable to other boards). See discussion of :ref:`important constraints ` on Timer callbacks. diff --git a/docs/library/machine.TimerWiPy.rst b/docs/library/machine.TimerWiPy.rst index f5b748c62e..39afc23bc5 100644 --- a/docs/library/machine.TimerWiPy.rst +++ b/docs/library/machine.TimerWiPy.rst @@ -16,7 +16,7 @@ the most flexible and heterogeneous kind of hardware in MCUs and SoCs, differently greatly from a model to a model. MicroPython's Timer class defines a baseline operation of executing a callback with a given period (or once after some delay), and allow specific boards to define more -non-standard behavior (which thus won't be portable to other boards). +non-standard behaviour (which thus won't be portable to other boards). See discussion of :ref:`important constraints ` on Timer callbacks. @@ -115,7 +115,7 @@ Methods .. method:: timerchannel.irq(*, trigger, priority=1, handler=None) - The behavior of this callback is heavily dependent on the operating + The behaviour of this callback is heavily dependent on the operating mode of the timer channel: - If mode is ``TimerWiPy.PERIODIC`` the callback is executed periodically diff --git a/docs/library/network.rst b/docs/library/network.rst index bd3bc6f34b..a20eb2ebf5 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -55,7 +55,7 @@ parameter should be `id`. Activate ("up") or deactivate ("down") the network interface, if a boolean argument is passed. Otherwise, query current state if no argument is provided. Most other methods require an active - interface (behavior of calling them on inactive interface is + interface (behaviour of calling them on inactive interface is undefined). .. method:: AbstractNIC.connect([service_id, key=None, *, ...]) diff --git a/docs/library/uctypes.rst b/docs/library/uctypes.rst index 0fdc40e484..b3343beb7e 100644 --- a/docs/library/uctypes.rst +++ b/docs/library/uctypes.rst @@ -245,7 +245,7 @@ Module contents .. data:: VOID - ``VOID`` is an alias for ``UINT8``, and is provided to conviniently define + ``VOID`` is an alias for ``UINT8``, and is provided to conveniently define C's void pointers: ``(uctypes.PTR, uctypes.VOID)``. .. data:: PTR diff --git a/docs/library/uio.rst b/docs/library/uio.rst index dddb83a170..adbeef08b7 100644 --- a/docs/library/uio.rst +++ b/docs/library/uio.rst @@ -18,7 +18,7 @@ Conceptual hierarchy Conceptual hierarchy of stream base classes is simplified in MicroPython, as described in this section. -(Abstract) base stream classes, which serve as a foundation for behavior +(Abstract) base stream classes, which serve as a foundation for behaviour of all the concrete classes, adhere to few dichotomies (pair-wise classifications) in CPython. In MicroPython, they are somewhat simplified and made implicit to achieve higher efficiencies and save resources. @@ -41,15 +41,15 @@ more concise and efficient programs - something which is highly desirable for MicroPython. So, while MicroPython doesn't support buffered streams, it still provides for no-short-operations streams. Whether there will be short operations or not depends on each particular class' needs, but -developers are strongly advised to favor no-short-operations behavior +developers are strongly advised to favour no-short-operations behaviour for the reasons stated above. For example, MicroPython sockets are guaranteed to avoid short read/writes. Actually, at this time, there is no example of a short-operations stream class in the core, and one would be a port-specific class, where such a need is governed by hardware peculiarities. -The no-short-operations behavior gets tricky in case of non-blocking -streams, blocking vs non-blocking behavior being another CPython dichotomy, +The no-short-operations behaviour gets tricky in case of non-blocking +streams, blocking vs non-blocking behaviour being another CPython dichotomy, fully supported by MicroPython. Non-blocking streams never wait for data either to arrive or be written - they read/write whatever possible, or signal lack of data (or ability to write data). Clearly, this conflicts diff --git a/docs/library/uselect.rst b/docs/library/uselect.rst index 0c3bdfdfd9..76202739c8 100644 --- a/docs/library/uselect.rst +++ b/docs/library/uselect.rst @@ -87,11 +87,11 @@ Methods `callee-owned tuple`. This function provides an efficient, allocation-free way to poll on streams. - If *flags* is 1, one-shot behavior for events is employed: streams for + If *flags* is 1, one-shot behaviour for events is employed: streams for which events happened will have their event masks automatically reset (equivalent to ``poll.modify(obj, 0)``), so new events for such a stream won't be processed until new mask is set with `poll.modify()`. This - behavior is useful for asynchronous I/O schedulers. + behaviour is useful for asynchronous I/O schedulers. .. admonition:: Difference to CPython :class: attention diff --git a/docs/library/usocket.rst b/docs/library/usocket.rst index bc4b4b6d5a..39b848e593 100644 --- a/docs/library/usocket.rst +++ b/docs/library/usocket.rst @@ -222,7 +222,7 @@ Methods Unlike `send()`, this method will try to send all of data, by sending data chunk by chunk consecutively. - The behavior of this method on non-blocking sockets is undefined. Due to this, + The behaviour of this method on non-blocking sockets is undefined. Due to this, on MicroPython, it's recommended to use `write()` method instead, which has the same "no short writes" policy for blocking sockets, and will return number of bytes sent on non-blocking sockets. diff --git a/docs/library/utime.rst b/docs/library/utime.rst index 86fd27b3a5..b7c604dc7b 100644 --- a/docs/library/utime.rst +++ b/docs/library/utime.rst @@ -173,7 +173,7 @@ Functions long sleep), then once you finally look again, it may seem to you that only 1 hour has passed. To avoid this mistake, just look at the clock regularly. Your application should do the same. "Too long sleep" metaphor also maps directly to application - behavior: don't let your application run any single task for too long. Run tasks + behaviour: don't let your application run any single task for too long. Run tasks in steps, and do time-keeping inbetween. `ticks_diff()` is designed to accommodate various usage patterns, among them: From 0054fff840dfda50a32c653774e91b3e19464675 Mon Sep 17 00:00:00 2001 From: Gabriel M Schuyler Date: Sun, 7 Feb 2021 12:35:47 -0600 Subject: [PATCH 072/349] docs/pyboard: Fix typo in pyb.Switch tutorial. --- docs/pyboard/tutorial/switch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pyboard/tutorial/switch.rst b/docs/pyboard/tutorial/switch.rst index 96bb3784e9..059b04d94a 100644 --- a/docs/pyboard/tutorial/switch.rst +++ b/docs/pyboard/tutorial/switch.rst @@ -93,7 +93,7 @@ on the pin for any changes, and the following will occur: running Python script. 3. The microcontroller starts executing the special interrupt handler associated with the switch's external trigger. This interrupt handler - get the function that you registered with ``sw.callback()`` and executes + gets the function that you registered with ``sw.callback()`` and executes it. 4. Your callback function is executed until it finishes, returning control to the switch interrupt handler. From 8172c2e9c5d5eec9a6b0a3f6cc4a2383b3d96d26 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 May 2021 23:36:05 +1000 Subject: [PATCH 073/349] rp2: Move manifest.py to boards directory. To match other ports. Signed-off-by: Damien George --- ports/rp2/CMakeLists.txt | 2 +- ports/rp2/{ => boards}/manifest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename ports/rp2/{ => boards}/manifest.py (74%) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index bd3eb74384..699520b240 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -159,7 +159,7 @@ set(PICO_SDK_COMPONENTS # Define mpy-cross flags and frozen manifest set(MICROPY_CROSS_FLAGS -march=armv7m) -set(MICROPY_FROZEN_MANIFEST ${PROJECT_SOURCE_DIR}/manifest.py) +set(MICROPY_FROZEN_MANIFEST ${PROJECT_SOURCE_DIR}/boards/manifest.py) target_sources(${MICROPY_TARGET} PRIVATE ${MICROPY_SOURCE_PY} diff --git a/ports/rp2/manifest.py b/ports/rp2/boards/manifest.py similarity index 74% rename from ports/rp2/manifest.py rename to ports/rp2/boards/manifest.py index a56d4b1b09..9df589f126 100644 --- a/ports/rp2/manifest.py +++ b/ports/rp2/boards/manifest.py @@ -1,3 +1,3 @@ -freeze("modules") +freeze("$(PORT_DIR)/modules") freeze("$(MPY_DIR)/drivers/onewire") include("$(MPY_DIR)/extmod/uasyncio/manifest.py") From 9e29217c73f36802de616c05bee9bf7f9090f722 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 14 Apr 2021 15:37:33 +1000 Subject: [PATCH 074/349] unix/modffi: Use a union for passing/returning FFI values. This fixes a bug where double arguments on a 32-bit architecture would not be passed correctly because they only had 4 bytes of storage (not 8). It also fixes a compiler warning/error in return_ffi_value on certian architectures: array subscript 'double[0]' is partly outside array bounds of 'ffi_arg[1]' {aka 'long unsigned int[1]'}. Fixes issue #7064. Signed-off-by: Damien George --- ports/unix/modffi.c | 62 +++++++++++++++---------------------- tests/unix/ffi_float.py | 13 ++++++-- tests/unix/ffi_float.py.exp | 20 ++++++++---- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index 598a28cd54..5c2595ec5e 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -56,6 +56,13 @@ * but may be later. */ +// This union is large enough to hold any supported argument/return value. +typedef union _ffi_union_t { + ffi_arg ffi; + float flt; + double dbl; +} ffi_union_t; + typedef struct _mp_obj_opaque_t { mp_obj_base_t base; void *val; @@ -151,10 +158,10 @@ STATIC ffi_type *get_ffi_type(mp_obj_t o_in) { mp_raise_TypeError(MP_ERROR_TEXT("unknown type")); } -STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) { +STATIC mp_obj_t return_ffi_value(ffi_union_t *val, char type) { switch (type) { case 's': { - const char *s = (const char *)(intptr_t)val; + const char *s = (const char *)(intptr_t)val->ffi; if (!s) { return mp_const_none; } @@ -164,20 +171,16 @@ STATIC mp_obj_t return_ffi_value(ffi_arg val, char type) { return mp_const_none; #if MICROPY_PY_BUILTINS_FLOAT case 'f': { - union { ffi_arg ffi; - float flt; - } val_union = { .ffi = val }; - return mp_obj_new_float_from_f(val_union.flt); + return mp_obj_new_float_from_f(val->flt); } case 'd': { - double *p = (double *)&val; - return mp_obj_new_float_from_d(*p); + return mp_obj_new_float_from_d(val->dbl); } #endif case 'O': - return (mp_obj_t)(intptr_t)val; + return (mp_obj_t)(intptr_t)val->ffi; default: - return mp_obj_new_int(val); + return mp_obj_new_int(val->ffi); } } @@ -368,28 +371,26 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const assert(n_kw == 0); assert(n_args == self->cif.nargs); - ffi_arg values[n_args]; + ffi_union_t values[n_args]; void *valueptrs[n_args]; const char *argtype = self->argtypes; for (uint i = 0; i < n_args; i++, argtype++) { mp_obj_t a = args[i]; if (*argtype == 'O') { - values[i] = (ffi_arg)(intptr_t)a; + values[i].ffi = (ffi_arg)(intptr_t)a; #if MICROPY_PY_BUILTINS_FLOAT } else if (*argtype == 'f') { - float *p = (float *)&values[i]; - *p = mp_obj_get_float_to_f(a); + values[i].flt = mp_obj_get_float_to_f(a); } else if (*argtype == 'd') { - double *p = (double *)&values[i]; - *p = mp_obj_get_float_to_d(a); + values[i].dbl = mp_obj_get_float_to_d(a); #endif } else if (a == mp_const_none) { - values[i] = 0; + values[i].ffi = 0; } else if (mp_obj_is_int(a)) { - values[i] = mp_obj_int_get_truncated(a); + values[i].ffi = mp_obj_int_get_truncated(a); } else if (mp_obj_is_str(a)) { const char *s = mp_obj_str_get_str(a); - values[i] = (ffi_arg)(intptr_t)s; + values[i].ffi = (ffi_arg)(intptr_t)s; } else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) { mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a); mp_buffer_info_t bufinfo; @@ -397,32 +398,19 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const if (ret != 0) { goto error; } - values[i] = (ffi_arg)(intptr_t)bufinfo.buf; + values[i].ffi = (ffi_arg)(intptr_t)bufinfo.buf; } 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; + values[i].ffi = (ffi_arg)(intptr_t)p->func; } else { goto error; } valueptrs[i] = &values[i]; } - // If ffi_arg is not big enough to hold a double, then we must pass along a - // pointer to a memory location of the correct size. - // TODO check if this needs to be done for other types which don't fit into - // ffi_arg. - #if MICROPY_PY_BUILTINS_FLOAT - if (sizeof(ffi_arg) == 4 && self->rettype == 'd') { - double retval; - ffi_call(&self->cif, self->func, &retval, valueptrs); - return mp_obj_new_float_from_d(retval); - } else - #endif - { - ffi_arg retval; - ffi_call(&self->cif, self->func, &retval, valueptrs); - return return_ffi_value(retval, self->rettype); - } + ffi_union_t retval; + ffi_call(&self->cif, self->func, &retval, valueptrs); + return return_ffi_value(&retval, self->rettype); error: mp_raise_TypeError(MP_ERROR_TEXT("don't know how to pass object to native function")); diff --git a/tests/unix/ffi_float.py b/tests/unix/ffi_float.py index d039398965..03bd9f7f17 100644 --- a/tests/unix/ffi_float.py +++ b/tests/unix/ffi_float.py @@ -35,6 +35,15 @@ print("%.6f" % strtod("1.23", None)) # test passing double and float args libm = ffi_open(("libm.so", "libm.so.6", "libc.so.0", "libc.so.6", "libc.dylib")) tgamma = libm.func("d", "tgamma", "d") -for fun in (tgamma,): +for fun_name in ("tgamma",): + fun = globals()[fun_name] for val in (0.5, 1, 1.0, 1.5, 4, 4.0): - print("%.6f" % fun(val)) + print(fun_name, "%.5f" % fun(val)) + +# test passing 2x float/double args +powf = libm.func("f", "powf", "ff") +pow = libm.func("d", "pow", "dd") +for fun_name in ("powf", "pow"): + fun = globals()[fun_name] + for args in ((0, 1), (1, 0), (2, 0.5), (3, 4)): + print(fun_name, "%.5f" % fun(*args)) diff --git a/tests/unix/ffi_float.py.exp b/tests/unix/ffi_float.py.exp index b9d7da2bdb..3d90914315 100644 --- a/tests/unix/ffi_float.py.exp +++ b/tests/unix/ffi_float.py.exp @@ -1,8 +1,16 @@ 1.230000 1.230000 -1.772454 -1.000000 -1.000000 -0.886227 -6.000000 -6.000000 +tgamma 1.77245 +tgamma 1.00000 +tgamma 1.00000 +tgamma 0.88623 +tgamma 6.00000 +tgamma 6.00000 +powf 0.00000 +powf 1.00000 +powf 1.41421 +powf 81.00000 +pow 0.00000 +pow 1.00000 +pow 1.41421 +pow 81.00000 From 4791d290c61e2cc5bcd006b35ef60470920279d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 12:11:51 +1000 Subject: [PATCH 075/349] extmod: Remove old comments used for auto-doc generation. They are no longer used, and the text in the docs is more up to date. Signed-off-by: Damien George --- extmod/moductypes.c | 70 +++++++-------------------------------------- extmod/moduselect.c | 16 ++++------- extmod/vfs_fat.c | 7 ++--- 3 files changed, 18 insertions(+), 75 deletions(-) diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 79a49d5c32..51626600cc 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -34,38 +34,10 @@ #if MICROPY_PY_UCTYPES -/// \module uctypes - Access data structures in memory -/// -/// The module allows to define layout of raw data structure (using terms -/// of C language), and then access memory buffers using this definition. -/// The module also provides convenience functions to access memory buffers -/// contained in Python objects or wrap memory buffers in Python objects. -/// \constant UINT8_1 - uint8_t value type - -/// \class struct - C-like structure -/// -/// Encapsulalation of in-memory data structure. This class doesn't define -/// any methods, only attribute access (for structure fields) and -/// indexing (for pointer and array fields). -/// -/// Usage: -/// -/// # Define layout of a structure with 2 fields -/// # 0 and 4 are byte offsets of fields from the beginning of struct -/// # they are logically ORed with field type -/// FOO_STRUCT = {"a": 0 | uctypes.UINT32, "b": 4 | uctypes.UINT8} -/// -/// # Example memory buffer to access (contained in bytes object) -/// buf = b"\x64\0\0\0\0x14" -/// -/// # Create structure object referring to address of -/// # the data in the buffer above -/// s = uctypes.struct(FOO_STRUCT, uctypes.addressof(buf)) -/// -/// # Access fields -/// print(s.a, s.b) -/// # Result: -/// # 100, 20 +// The uctypes module allows defining the layout of a raw data structure (using +// terms of the C language), and then access memory buffers using this definition. +// The module also provides convenience functions to access memory buffers +// contained in Python objects or wrap memory buffers in Python objects. #define LAYOUT_LITTLE_ENDIAN (0) #define LAYOUT_BIG_ENDIAN (1) @@ -647,9 +619,8 @@ STATIC mp_int_t uctypes_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, return 0; } -/// \function addressof() -/// Return address of object's data (applies to object providing buffer -/// interface). +// addressof() +// Return address of object's data (applies to objects providing the buffer interface). STATIC mp_obj_t uctypes_struct_addressof(mp_obj_t buf) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); @@ -657,19 +628,15 @@ STATIC mp_obj_t uctypes_struct_addressof(mp_obj_t buf) { } MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_addressof_obj, uctypes_struct_addressof); -/// \function bytearray_at() -/// Capture memory at given address of given size as bytearray. Memory is -/// captured by reference (and thus memory pointed by bytearray may change -/// or become invalid at later time). Use bytes_at() to capture by value. +// bytearray_at() +// Capture memory at given address of given size as bytearray. STATIC mp_obj_t uctypes_struct_bytearray_at(mp_obj_t ptr, mp_obj_t size) { return mp_obj_new_bytearray_by_ref(mp_obj_int_get_truncated(size), (void *)(uintptr_t)mp_obj_int_get_truncated(ptr)); } MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytearray_at_obj, uctypes_struct_bytearray_at); -/// \function bytes_at() -/// Capture memory at given address of given size as bytes. Memory is -/// captured by value, i.e. copied. Use bytearray_at() to capture by reference -/// ("zero copy"). +// bytes_at() +// Capture memory at given address of given size as bytes. STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) { return mp_obj_new_bytes((void *)(uintptr_t)mp_obj_int_get_truncated(ptr), mp_obj_int_get_truncated(size)); } @@ -695,36 +662,19 @@ STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_bytes_at), MP_ROM_PTR(&uctypes_struct_bytes_at_obj) }, { MP_ROM_QSTR(MP_QSTR_bytearray_at), MP_ROM_PTR(&uctypes_struct_bytearray_at_obj) }, - /// \moduleref uctypes - - /// \constant NATIVE - Native structure layout - native endianness, - /// platform-specific field alignment { MP_ROM_QSTR(MP_QSTR_NATIVE), MP_ROM_INT(LAYOUT_NATIVE) }, - /// \constant LITTLE_ENDIAN - Little-endian structure layout, tightly packed - /// (no alignment constraints) { MP_ROM_QSTR(MP_QSTR_LITTLE_ENDIAN), MP_ROM_INT(LAYOUT_LITTLE_ENDIAN) }, - /// \constant BIG_ENDIAN - Big-endian structure layout, tightly packed - /// (no alignment constraints) { MP_ROM_QSTR(MP_QSTR_BIG_ENDIAN), MP_ROM_INT(LAYOUT_BIG_ENDIAN) }, - /// \constant VOID - void value type, may be used only as pointer target type. { MP_ROM_QSTR(MP_QSTR_VOID), MP_ROM_INT(TYPE2SMALLINT(UINT8, VAL_TYPE_BITS)) }, - /// \constant UINT8 - uint8_t value type { MP_ROM_QSTR(MP_QSTR_UINT8), MP_ROM_INT(TYPE2SMALLINT(UINT8, 4)) }, - /// \constant INT8 - int8_t value type { MP_ROM_QSTR(MP_QSTR_INT8), MP_ROM_INT(TYPE2SMALLINT(INT8, 4)) }, - /// \constant UINT16 - uint16_t value type { MP_ROM_QSTR(MP_QSTR_UINT16), MP_ROM_INT(TYPE2SMALLINT(UINT16, 4)) }, - /// \constant INT16 - int16_t value type { MP_ROM_QSTR(MP_QSTR_INT16), MP_ROM_INT(TYPE2SMALLINT(INT16, 4)) }, - /// \constant UINT32 - uint32_t value type { MP_ROM_QSTR(MP_QSTR_UINT32), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) }, - /// \constant INT32 - int32_t value type { MP_ROM_QSTR(MP_QSTR_INT32), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) }, - /// \constant UINT64 - uint64_t value type { MP_ROM_QSTR(MP_QSTR_UINT64), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) }, - /// \constant INT64 - int64_t value type { MP_ROM_QSTR(MP_QSTR_INT64), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) }, { MP_ROM_QSTR(MP_QSTR_BFUINT8), MP_ROM_INT(TYPE2SMALLINT(BFUINT8, 4)) }, diff --git a/extmod/moduselect.c b/extmod/moduselect.c index 6d8249f427..fbd51960d5 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -40,10 +40,6 @@ // Flags for poll() #define FLAG_ONESHOT (1) -/// \module select - Provides select function to wait for events on a stream -/// -/// This module provides the select function. - typedef struct _poll_obj_t { mp_obj_t obj; mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode); @@ -111,7 +107,7 @@ STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) { return n_ready; } -/// \function select(rlist, wlist, xlist[, timeout]) +// select(rlist, wlist, xlist[, timeout]) 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]; @@ -178,8 +174,6 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_select_select_obj, 3, 4, select_select); -/// \class Poll - poll class - typedef struct _mp_obj_poll_t { mp_obj_base_t base; mp_map_t poll_map; @@ -190,7 +184,7 @@ typedef struct _mp_obj_poll_t { mp_obj_t ret_tuple; } mp_obj_poll_t; -/// \method register(obj[, eventmask]) +// 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]); mp_uint_t flags; @@ -204,7 +198,7 @@ STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(poll_register_obj, 2, 3, poll_register); -/// \method unregister(obj) +// unregister(obj) STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) { mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP_REMOVE_IF_FOUND); @@ -213,7 +207,7 @@ STATIC mp_obj_t poll_unregister(mp_obj_t self_in, mp_obj_t obj_in) { } MP_DEFINE_CONST_FUN_OBJ_2(poll_unregister_obj, poll_unregister); -/// \method modify(obj, eventmask) +// modify(obj, eventmask) STATIC mp_obj_t poll_modify(mp_obj_t self_in, mp_obj_t obj_in, mp_obj_t eventmask_in) { mp_obj_poll_t *self = MP_OBJ_TO_PTR(self_in); mp_map_elem_t *elem = mp_map_lookup(&self->poll_map, mp_obj_id(obj_in), MP_MAP_LOOKUP); @@ -348,7 +342,7 @@ STATIC const mp_obj_type_t mp_type_poll = { .locals_dict = (void *)&poll_locals_dict, }; -/// \function poll() +// poll() STATIC mp_obj_t select_poll(void) { mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t); poll->base.type = &mp_type_poll; diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 95b7ad9944..644be57ae7 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -256,7 +256,7 @@ STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir); -/// Change current directory. +// Change current directory. STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); const char *path; @@ -272,7 +272,7 @@ STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_chdir_obj, fat_vfs_chdir); -/// Get the current directory. +// Get the current directory. STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); char buf[MICROPY_ALLOC_PATH_MAX + 1]; @@ -284,8 +284,7 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd); -/// \function stat(path) -/// Get the status of a file or directory. +// Get the status of a file or directory. STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) { mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in); const char *path = mp_obj_str_get_str(path_in); From 02dc1644b6ebf1bfd5bfa2dde4d68d7272526f51 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 12:31:32 +1000 Subject: [PATCH 076/349] extmod/moductypes: Remove double blank lines and debugging printf's. Signed-off-by: Damien George --- extmod/moductypes.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 51626600cc..f1108649aa 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -391,10 +391,8 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set 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); -// printf("scalar type=%d offset=%x\n", val_type, offset); if (val_type <= INT64 || val_type == FLOAT32 || val_type == FLOAT64) { -// printf("size=%d\n", GET_SCALAR_SIZE(val_type)); if (self->flags == LAYOUT_NATIVE) { if (set_val == MP_OBJ_NULL) { return get_aligned(val_type, self->addr + offset, 0); @@ -461,7 +459,6 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(sub->items[0]); mp_uint_t agg_type = GET_TYPE(offset, AGG_TYPE_BITS); offset &= VALUE_MASK(AGG_TYPE_BITS); -// printf("agg type=%d offset=%x\n", agg_type, offset); switch (agg_type) { case STRUCT: { @@ -486,7 +483,6 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set o->desc = MP_OBJ_FROM_PTR(sub); o->addr = self->addr + offset; o->flags = self->flags; -// printf("PTR/ARR base addr=%p\n", o->addr); return MP_OBJ_FROM_PTR(o); } } @@ -642,7 +638,6 @@ STATIC mp_obj_t uctypes_struct_bytes_at(mp_obj_t ptr, mp_obj_t size) { } MP_DEFINE_CONST_FUN_OBJ_2(uctypes_struct_bytes_at_obj, uctypes_struct_bytes_at); - STATIC const mp_obj_type_t uctypes_struct_type = { { &mp_type_type }, .name = MP_QSTR_struct, @@ -719,7 +714,6 @@ STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PTR), MP_ROM_INT(TYPE2SMALLINT(PTR, AGG_TYPE_BITS)) }, { MP_ROM_QSTR(MP_QSTR_ARRAY), MP_ROM_INT(TYPE2SMALLINT(ARRAY, AGG_TYPE_BITS)) }, }; - STATIC MP_DEFINE_CONST_DICT(mp_module_uctypes_globals, mp_module_uctypes_globals_table); const mp_obj_module_t mp_module_uctypes = { From 350a66a86339a66bfad29e0e8a5a40a34151bfe4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 12:40:53 +1000 Subject: [PATCH 077/349] extmod/moductypes: Replace numbers with macro constants. Signed-off-by: Damien George --- extmod/moductypes.c | 63 +++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/extmod/moductypes.c b/extmod/moductypes.c index f1108649aa..97e8d7a787 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -47,6 +47,7 @@ #define BITF_LEN_BITS 5 #define BITF_OFF_BITS 5 #define OFFSET_BITS 17 +#define LEN_BITS (OFFSET_BITS + BITF_OFF_BITS) #if VAL_TYPE_BITS + BITF_LEN_BITS + BITF_OFF_BITS + OFFSET_BITS != 31 #error Invalid encoding field length #endif @@ -409,9 +410,9 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set } } } else if (val_type >= BFUINT8 && val_type <= BFINT32) { - uint bit_offset = (offset >> 17) & 31; - uint bit_len = (offset >> 22) & 31; - offset &= (1 << 17) - 1; + uint bit_offset = (offset >> OFFSET_BITS) & 31; + uint bit_len = (offset >> LEN_BITS) & 31; + offset &= (1 << OFFSET_BITS) - 1; mp_uint_t val; if (self->flags == LAYOUT_NATIVE) { val = get_aligned_basic(val_type & 6, self->addr + offset); @@ -663,51 +664,51 @@ STATIC const mp_rom_map_elem_t mp_module_uctypes_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_VOID), MP_ROM_INT(TYPE2SMALLINT(UINT8, VAL_TYPE_BITS)) }, - { MP_ROM_QSTR(MP_QSTR_UINT8), MP_ROM_INT(TYPE2SMALLINT(UINT8, 4)) }, - { MP_ROM_QSTR(MP_QSTR_INT8), MP_ROM_INT(TYPE2SMALLINT(INT8, 4)) }, - { MP_ROM_QSTR(MP_QSTR_UINT16), MP_ROM_INT(TYPE2SMALLINT(UINT16, 4)) }, - { MP_ROM_QSTR(MP_QSTR_INT16), MP_ROM_INT(TYPE2SMALLINT(INT16, 4)) }, - { MP_ROM_QSTR(MP_QSTR_UINT32), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_INT32), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_UINT64), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) }, - { MP_ROM_QSTR(MP_QSTR_INT64), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) }, + { MP_ROM_QSTR(MP_QSTR_UINT8), MP_ROM_INT(TYPE2SMALLINT(UINT8, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_INT8), MP_ROM_INT(TYPE2SMALLINT(INT8, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_UINT16), MP_ROM_INT(TYPE2SMALLINT(UINT16, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_INT16), MP_ROM_INT(TYPE2SMALLINT(INT16, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_UINT32), MP_ROM_INT(TYPE2SMALLINT(UINT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_INT32), MP_ROM_INT(TYPE2SMALLINT(INT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_UINT64), MP_ROM_INT(TYPE2SMALLINT(UINT64, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_INT64), MP_ROM_INT(TYPE2SMALLINT(INT64, VAL_TYPE_BITS)) }, - { MP_ROM_QSTR(MP_QSTR_BFUINT8), MP_ROM_INT(TYPE2SMALLINT(BFUINT8, 4)) }, - { MP_ROM_QSTR(MP_QSTR_BFINT8), MP_ROM_INT(TYPE2SMALLINT(BFINT8, 4)) }, - { MP_ROM_QSTR(MP_QSTR_BFUINT16), MP_ROM_INT(TYPE2SMALLINT(BFUINT16, 4)) }, - { MP_ROM_QSTR(MP_QSTR_BFINT16), MP_ROM_INT(TYPE2SMALLINT(BFINT16, 4)) }, - { MP_ROM_QSTR(MP_QSTR_BFUINT32), MP_ROM_INT(TYPE2SMALLINT(BFUINT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_BFINT32), MP_ROM_INT(TYPE2SMALLINT(BFINT32, 4)) }, + { MP_ROM_QSTR(MP_QSTR_BFUINT8), MP_ROM_INT(TYPE2SMALLINT(BFUINT8, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_BFINT8), MP_ROM_INT(TYPE2SMALLINT(BFINT8, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_BFUINT16), MP_ROM_INT(TYPE2SMALLINT(BFUINT16, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_BFINT16), MP_ROM_INT(TYPE2SMALLINT(BFINT16, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_BFUINT32), MP_ROM_INT(TYPE2SMALLINT(BFUINT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_BFINT32), MP_ROM_INT(TYPE2SMALLINT(BFINT32, VAL_TYPE_BITS)) }, - { MP_ROM_QSTR(MP_QSTR_BF_POS), MP_ROM_INT(17) }, - { MP_ROM_QSTR(MP_QSTR_BF_LEN), MP_ROM_INT(22) }, + { MP_ROM_QSTR(MP_QSTR_BF_POS), MP_ROM_INT(OFFSET_BITS) }, + { MP_ROM_QSTR(MP_QSTR_BF_LEN), MP_ROM_INT(LEN_BITS) }, #if MICROPY_PY_BUILTINS_FLOAT - { MP_ROM_QSTR(MP_QSTR_FLOAT32), MP_ROM_INT(TYPE2SMALLINT(FLOAT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_FLOAT64), MP_ROM_INT(TYPE2SMALLINT(FLOAT64, 4)) }, + { MP_ROM_QSTR(MP_QSTR_FLOAT32), MP_ROM_INT(TYPE2SMALLINT(FLOAT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_FLOAT64), MP_ROM_INT(TYPE2SMALLINT(FLOAT64, VAL_TYPE_BITS)) }, #endif #if MICROPY_PY_UCTYPES_NATIVE_C_TYPES // C native type aliases. These depend on GCC-compatible predefined // preprocessor macros. #if __SIZEOF_SHORT__ == 2 - { MP_ROM_QSTR(MP_QSTR_SHORT), MP_ROM_INT(TYPE2SMALLINT(INT16, 4)) }, - { MP_ROM_QSTR(MP_QSTR_USHORT), MP_ROM_INT(TYPE2SMALLINT(UINT16, 4)) }, + { MP_ROM_QSTR(MP_QSTR_SHORT), MP_ROM_INT(TYPE2SMALLINT(INT16, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_USHORT), MP_ROM_INT(TYPE2SMALLINT(UINT16, VAL_TYPE_BITS)) }, #endif #if __SIZEOF_INT__ == 4 - { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_UINT), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) }, + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_INT(TYPE2SMALLINT(INT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_UINT), MP_ROM_INT(TYPE2SMALLINT(UINT32, VAL_TYPE_BITS)) }, #endif #if __SIZEOF_LONG__ == 4 - { MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT32, 4)) }, - { MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT32, 4)) }, + { MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT32, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT32, VAL_TYPE_BITS)) }, #elif __SIZEOF_LONG__ == 8 - { MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) }, - { MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) }, + { MP_ROM_QSTR(MP_QSTR_LONG), MP_ROM_INT(TYPE2SMALLINT(INT64, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_ULONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, VAL_TYPE_BITS)) }, #endif #if __SIZEOF_LONG_LONG__ == 8 - { MP_ROM_QSTR(MP_QSTR_LONGLONG), MP_ROM_INT(TYPE2SMALLINT(INT64, 4)) }, - { MP_ROM_QSTR(MP_QSTR_ULONGLONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, 4)) }, + { MP_ROM_QSTR(MP_QSTR_LONGLONG), MP_ROM_INT(TYPE2SMALLINT(INT64, VAL_TYPE_BITS)) }, + { MP_ROM_QSTR(MP_QSTR_ULONGLONG), MP_ROM_INT(TYPE2SMALLINT(UINT64, VAL_TYPE_BITS)) }, #endif #endif // MICROPY_PY_UCTYPES_NATIVE_C_TYPES From 47583d8cbd251d9cb3b0f4a70c5594d1329ad930 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 13:11:33 +1000 Subject: [PATCH 078/349] extmod/moductypes: Fix size and offset calculation for ARRAY of FLOAT32. uctypes.FLOAT32 has a special value representation and uctypes_struct_scalar_size() should be used instead of GET_SCALAR_SIZE(). Signed-off-by: Damien George --- extmod/moductypes.c | 4 ++-- tests/extmod/uctypes_le_float.py | 16 ++++++++++++++++ tests/extmod/uctypes_le_float.py.exp | 2 ++ tests/extmod/uctypes_sizeof_float.py | 2 ++ tests/extmod/uctypes_sizeof_float.py.exp | 2 ++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 97e8d7a787..58f0adfa4b 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -164,7 +164,7 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_ mp_uint_t item_s; if (t->len == 2) { // Elements of array are scalar - item_s = GET_SCALAR_SIZE(val_type); + item_s = uctypes_struct_scalar_size(val_type); if (item_s > *max_field_size) { *max_field_size = item_s; } @@ -541,7 +541,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob return value; // just !MP_OBJ_NULL } } else { - byte *p = self->addr + GET_SCALAR_SIZE(val_type) * index; + byte *p = self->addr + uctypes_struct_scalar_size(val_type) * index; if (value == MP_OBJ_SENTINEL) { return get_unaligned(val_type, p, self->flags); } else { diff --git a/tests/extmod/uctypes_le_float.py b/tests/extmod/uctypes_le_float.py index 89e9a9e0ab..5255632c91 100644 --- a/tests/extmod/uctypes_le_float.py +++ b/tests/extmod/uctypes_le_float.py @@ -22,3 +22,19 @@ print("%.4f" % S.f64) S.uf64 = 12.34 print("%.4f" % S.uf64) + +# array of float/double +desc = { + "af32": (uctypes.ARRAY | 0, uctypes.FLOAT32 | 2), + "af64": (uctypes.ARRAY | 0, uctypes.FLOAT64 | 2), +} +data = bytearray(16) +S = uctypes.struct(uctypes.addressof(data), desc, uctypes.LITTLE_ENDIAN) + +S.af32[0] = 1 +S.af32[1] = 2 +print("%.4f %.4f" % (S.af32[0], S.af32[1]), data) + +S.af64[0] = 1 +S.af64[1] = 2 +print("%.4f %.4f" % (S.af64[0], S.af64[1]), data) diff --git a/tests/extmod/uctypes_le_float.py.exp b/tests/extmod/uctypes_le_float.py.exp index a35a1da2dc..e93fcb0d97 100644 --- a/tests/extmod/uctypes_le_float.py.exp +++ b/tests/extmod/uctypes_le_float.py.exp @@ -1,3 +1,5 @@ 12.3400 12.3400 12.3400 +1.0000 2.0000 bytearray(b'\x00\x00\x80?\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00') +1.0000 2.0000 bytearray(b'\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@') diff --git a/tests/extmod/uctypes_sizeof_float.py b/tests/extmod/uctypes_sizeof_float.py index 351632d76b..f1a4c88e2d 100644 --- a/tests/extmod/uctypes_sizeof_float.py +++ b/tests/extmod/uctypes_sizeof_float.py @@ -6,3 +6,5 @@ except ImportError: print(uctypes.sizeof({"f": uctypes.FLOAT32})) print(uctypes.sizeof({"f": uctypes.FLOAT64})) +print(uctypes.sizeof({"f": (uctypes.ARRAY | 0, uctypes.FLOAT32 | 2)})) +print(uctypes.sizeof({"f": (uctypes.ARRAY | 0, uctypes.FLOAT64 | 2)})) diff --git a/tests/extmod/uctypes_sizeof_float.py.exp b/tests/extmod/uctypes_sizeof_float.py.exp index de78180725..82776b54ab 100644 --- a/tests/extmod/uctypes_sizeof_float.py.exp +++ b/tests/extmod/uctypes_sizeof_float.py.exp @@ -1,2 +1,4 @@ 4 8 +8 +16 From b98197f950b572aff2a34934e64d094e5cea6cd5 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:05:33 +1000 Subject: [PATCH 079/349] docs/esp32: Add UART to quickref. --- docs/esp32/quickref.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index c29688f000..2a9c8397c8 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -171,6 +171,33 @@ Notes: * The pull value of some pins can be set to ``Pin.PULL_HOLD`` to reduce power consumption during deepsleep. +UART (serial bus) +----------------- + +See :ref:`machine.UART `. :: + + from machine import UART + + uart1 = UART(1, baudrate=9600, tx=33, rx=32) + uart1.write('hello') # write 5 bytes + uart1.read(5) # read up to 5 bytes + +The ESP32 has three hardware UARTs: UART0, UART1 and UART2. +They each have default GPIO assigned to them, however depending on your +ESP32 variant and board, these pins may conflict with embedded flash, +onboard PSRAM or peripherals. + +Any GPIO can be used for hardware UARTs using the GPIO matrix, so to avoid +conflicts simply provide ``tx`` and ``rx`` pins when constructing. The default +pins listed below. + +===== ===== ===== ===== +\ UART0 UART1 UART2 +===== ===== ===== ===== +tx 1 10 17 +rx 3 9 16 +===== ===== ===== ===== + PWM (pulse width modulation) ---------------------------- From a65942a41d5bedd80b0098b1578680e72bef384b Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:03:16 +1000 Subject: [PATCH 080/349] docs/esp32: Add WDT to quickref. --- docs/esp32/quickref.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 2a9c8397c8..5e70275830 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -384,6 +384,17 @@ See :ref:`machine.RTC ` :: rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time rtc.datetime() # get date and time +WDT (Watchdog timer) +-------------------- + +See :ref:`machine.WDT `. :: + + from machine import WDT + + # enable the WDT with a timeout of 5s (1s is the minimum) + wdt = WDT(timeout=5000) + wdt.feed() + Deep-sleep mode --------------- From a111889705649465b2fd57a1f10bd34aae9b4435 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:04:37 +1000 Subject: [PATCH 081/349] docs/esp32: Add SDCard to quickref. --- docs/esp32/quickref.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 5e70275830..a569ff0a4e 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -424,6 +424,21 @@ Notes: p1 = Pin(4, Pin.OUT, None) +SD card +------- + +See :ref:`machine.SDCard `. :: + + import machine, uos + + # Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23 + sd = machine.SDCard(slot=2) + uos.mount(sd, "/sd") # mount + + uos.listdir('/sd') # list directory contents + + uos.umount('/sd') # eject + RMT --- From 64aebed70e58ecc9623231d887d9818475174081 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:02:17 +1000 Subject: [PATCH 082/349] docs/esp8266: Add WDT to quickref. --- docs/esp8266/quickref.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index b9a46ab112..af2ef1ca1a 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -293,6 +293,17 @@ See :ref:`machine.RTC ` :: (using a custom handler), `RTC.init()` and `RTC.deinit()` are currently not supported. +WDT (Watchdog timer) +-------------------- + +See :ref:`machine.WDT `. :: + + from machine import WDT + + # enable the WDT + wdt = WDT() + wdt.feed() + Deep-sleep mode --------------- From 8ff3520f67bb8f7e5509129f9f561a1217ababa4 Mon Sep 17 00:00:00 2001 From: mishafarms Date: Tue, 4 May 2021 10:50:20 -0700 Subject: [PATCH 083/349] esp32/esp32_rmt: Clear config struct before filling it out. Or unset entries will have garbage in them. Signed-off-by: mishafarms --- ports/esp32/esp32_rmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index b547af5539..9619b1dd5b 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -96,7 +96,7 @@ STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, siz self->carrier_freq = carrier_freq; self->loop_en = false; - rmt_config_t config; + rmt_config_t config = {0}; config.rmt_mode = RMT_MODE_TX; config.channel = (rmt_channel_t)self->channel_id; config.gpio_num = self->pin; From 9eea51b730532cb33fe2531a3aade734d0a0a121 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Tue, 20 Apr 2021 17:07:43 +1000 Subject: [PATCH 084/349] drivers/display/ssd1306.py: Add rotate method. And clean up (make more efficient) display set-up commands. --- drivers/display/ssd1306.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/display/ssd1306.py b/drivers/display/ssd1306.py index 6359c85eaa..85e2bf0cb5 100644 --- a/drivers/display/ssd1306.py +++ b/drivers/display/ssd1306.py @@ -37,12 +37,12 @@ class SSD1306(framebuf.FrameBuffer): def init_display(self): for cmd in ( - SET_DISP | 0x00, # off + SET_DISP, # display off # address setting SET_MEM_ADDR, 0x00, # horizontal # resolution and layout - SET_DISP_START_LINE | 0x00, + SET_DISP_START_LINE, # start at line 0 SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 SET_MUX_RATIO, self.height - 1, @@ -66,14 +66,14 @@ class SSD1306(framebuf.FrameBuffer): # charge pump SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, - SET_DISP | 0x01, + SET_DISP | 0x01, # display on ): # on self.write_cmd(cmd) self.fill(0) self.show() def poweroff(self): - self.write_cmd(SET_DISP | 0x00) + self.write_cmd(SET_DISP) def poweron(self): self.write_cmd(SET_DISP | 0x01) @@ -85,6 +85,10 @@ class SSD1306(framebuf.FrameBuffer): def invert(self, invert): self.write_cmd(SET_NORM_INV | (invert & 1)) + def rotate(self, rotate): + self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3)) + self.write_cmd(SET_SEG_REMAP | (rotate & 1)) + def show(self): x0 = 0 x1 = self.width - 1 From fd24e649fde26bcd484b30025527768d37f5c562 Mon Sep 17 00:00:00 2001 From: Tim Radvan Date: Fri, 16 Apr 2021 12:18:04 +0100 Subject: [PATCH 085/349] docs/library: Add initial API reference for rp2 module and its classes. All the method signatures from rp2_pio.c and friends have been taken and converted to RST format, then explanatory notes added for each signature. Signed-off-by: Tim Radvan --- docs/library/index.rst | 11 +++ docs/library/machine.rst | 6 +- docs/library/rp2.Flash.rst | 36 ++++++++ docs/library/rp2.PIO.rst | 94 +++++++++++++++++++++ docs/library/rp2.StateMachine.rst | 131 ++++++++++++++++++++++++++++++ docs/library/rp2.rst | 83 +++++++++++++++++++ 6 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 docs/library/rp2.Flash.rst create mode 100644 docs/library/rp2.PIO.rst create mode 100644 docs/library/rp2.StateMachine.rst create mode 100644 docs/library/rp2.rst diff --git a/docs/library/index.rst b/docs/library/index.rst index 43d9e87f3c..2536e8dc96 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -165,3 +165,14 @@ The following libraries are specific to the ESP8266 and ESP32. esp.rst esp32.rst + + +Libraries specific to the RP2040 +-------------------------------- + +The following libraries are specific to the RP2040, as used in the Raspberry Pi Pico. + +.. toctree:: + :maxdepth: 2 + + rp2.rst diff --git a/docs/library/machine.rst b/docs/library/machine.rst index f831049f88..0a1c1c9530 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -64,9 +64,11 @@ Interrupt related functions Power related functions ----------------------- -.. function:: freq() +.. function:: freq([hz]) - Returns CPU frequency in hertz. + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. .. function:: idle() diff --git a/docs/library/rp2.Flash.rst b/docs/library/rp2.Flash.rst new file mode 100644 index 0000000000..3b423adfdd --- /dev/null +++ b/docs/library/rp2.Flash.rst @@ -0,0 +1,36 @@ +.. currentmodule:: rp2 +.. _rp2.Flash: + +class Flash -- access to built-in flash storage +=============================================== + +This class gives access to the SPI flash memory. + +In most cases, to store persistent data on the device, you'll want to use a +higher-level abstraction, for example the filesystem via Python's standard file +API, but this interface is useful to :ref:`customise the filesystem +configuration ` or implement a low-level storage system for your +application. + + +Constructors +------------ + +.. class:: Flash() + + Gets the singleton object for accessing the SPI flash memory. + + +Methods +------- + +.. method:: Flash.readblocks(block_num, buf) + Flash.readblocks(block_num, buf, offset) +.. method:: Flash.writeblocks(block_num, buf) + Flash.writeblocks(block_num, buf, offset) +.. method:: Flash.ioctl(cmd, arg) + + These methods implement the simple and extended + :ref:`block protocol ` defined by + :class:`uos.AbstractBlockDev`. + diff --git a/docs/library/rp2.PIO.rst b/docs/library/rp2.PIO.rst new file mode 100644 index 0000000000..e0675af1e9 --- /dev/null +++ b/docs/library/rp2.PIO.rst @@ -0,0 +1,94 @@ +.. currentmodule:: rp2 +.. _rp2.PIO: + +class PIO -- advanced PIO usage +=============================== + +The :class:`PIO` class gives access to an instance of the RP2040's PIO +(programmable I/O) interface. + +The preferred way to interact with PIO is using :class:`rp2.StateMachine`, the +PIO class is for advanced use. + +For assembling PIO programs, see :func:`rp2.asm_pio`. + + +Constructors +------------ + +.. class:: PIO(id) + + Gets the PIO instance numbered *id*. The RP2040 has two PIO instances, + numbered 0 and 1. + + Raises a ``ValueError`` if any other argument is provided. + + +Methods +------- + +.. method:: PIO.add_program(program) + + Add the *program* to the instruction memory of this PIO instance. + + The amount of memory available for programs on each PIO instance is + limited. If there isn't enough space left in the PIO's program memory + this method will raise ``OSError(ENOMEM)``. + +.. method:: PIO.remove_program([program]) + + Remove *program* from the instruction memory of this PIO instance. + + If no program is provided, it removes all programs. + + It is not an error to remove a program which has already been removed. + +.. method:: PIO.state_machine(id, [program, ...]) + + Gets the state machine numbered *id*. On the RP2040, each PIO instance has + four state machines, numbered 0 to 3. + + Optionally initialize it with a *program*: see `StateMachine.init`. + + >>> rp2.PIO(1).state_machine(3) + StateMachine(7) + +.. method:: PIO.irq(handler=None, trigger=IRQ_SM0|IRQ_SM1|IRQ_SM2|IRQ_SM3, hard=False) + + Returns the IRQ object for this PIO instance. + + MicroPython only uses IRQ 0 on each PIO instance. IRQ 1 is not available. + + Optionally configure it. + + +Constants +--------- + +.. data:: PIO.IN_LOW + PIO.IN_HIGH + PIO.OUT_LOW + PIO.OUT_HIGH + + These constants are used for the *out_init*, *set_init*, and *sideset_init* + arguments to `asm_pio`. + +.. data:: PIO.SHIFT_LEFT + PIO.SHIFT_RIGHT + + These constants are used for the *in_shiftdir* and *out_shiftdir* arguments + to `asm_pio` or `StateMachine.init`. + +.. data:: PIO.JOIN_NONE + PIO.JOIN_TX + PIO.JOIN_RX + + These constants are used for the *fifo_join* argument to `asm_pio`. + +.. data:: PIO.IRQ_SM0 + PIO.IRQ_SM1 + PIO.IRQ_SM2 + PIO.IRQ_SM3 + + These constants are used for the *trigger* argument to `PIO.irq`. + diff --git a/docs/library/rp2.StateMachine.rst b/docs/library/rp2.StateMachine.rst new file mode 100644 index 0000000000..8d73ccf772 --- /dev/null +++ b/docs/library/rp2.StateMachine.rst @@ -0,0 +1,131 @@ +.. currentmodule:: rp2 +.. _rp2.StateMachine: + +class StateMachine -- access to the RP2040's programmable I/O interface +======================================================================= + +The :class:`StateMachine` class gives access to the RP2040's PIO (programmable +I/O) interface. + +For assembling PIO programs, see :func:`rp2.asm_pio`. + + +Constructors +------------ + +.. class:: StateMachine(id, [program, ...]) + + Get the state machine numbered *id*. The RP2040 has two identical PIO + instances, each with 4 state machines: so there are 8 state machines in + total, numbered 0 to 7. + + Optionally initialize it with the given program *program*: see + `StateMachine.init`. + + +Methods +------- + +.. method:: StateMachine.init(program, freq=-1, *, in_base=None, out_base=None, set_base=None, jmp_pin=None, sideset_base=None, in_shiftdir=None, out_shiftdir=None, push_thresh=None, pull_thresh=None) + + Configure the state machine instance to run the given *program*. + + The program is added to the instruction memory of this PIO instance. If the + instruction memory already contains this program, then its offset is + re-used so as to save on instruction memory. + + - *freq* is the frequency in Hz to run the state machine at. Defaults to + the system clock frequency. + + The clock divider is computed as ``system clock frequency / freq``, so + there can be slight rounding errors. + + The minimum possible clock divider is one 65536th of the system clock: so + at the default system clock frequency of 125MHz, the minimum value of + *freq* is ``1908``. To run state machines at slower frequencies, you'll + need to reduce the system clock speed with `machine.freq()`. + - *in_base* is the first pin to use for ``in()`` instructions. + - *out_base* is the first pin to use for ``out()`` instructions. + - *set_base* is the first pin to use for ``set()`` instructions. + - *jmp_pin* is the first pin to use for ``jmp(pin, ...)`` instructions. + - *sideset_base* is the first pin to use for side-setting. + - *in_shiftdir* is the direction the ISR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *out_shiftdir* is the direction the OSR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *push_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + +.. method:: StateMachine.active([value]) + + Gets or sets whether the state machine is currently running. + + >>> sm.active() + True + >>> sm.active(0) + False + +.. method:: StateMachine.restart() + + Restarts the state machine and jumps to the beginning of the program. + + This method clears the state machine's internal state using the RP2040's + ``SM_RESTART`` register. This includes: + + - input and output shift counters + - the contents of the input shift register + - the delay counter + - the waiting-on-IRQ state + - a stalled instruction run using `StateMachine.exec()` + +.. method:: StateMachine.exec(instr) + + Execute a single PIO instruction. Uses `asm_pio_encode` to encode the + instruction from the given string *instr*. + + >>> sm.exec("set(0, 1)") + +.. method:: StateMachine.get(buf=None, shift=0) + + Pull a word from the state machine's RX FIFO. + + If the FIFO is empty, it blocks until data arrives (i.e. the state machine + pushes a word). + + The value is shifted right by *shift* bits before returning, i.e. the + return value is ``word >> shift``. + +.. method:: StateMachine.put(value, shift=0) + + Push a word onto the state machine's TX FIFO. + + If the FIFO is full, it blocks until there is space (i.e. the state machine + pulls a word). + + The value is first shifted left by *shift* bits, i.e. the state machine + receives ``value << shift``. + +.. method:: StateMachine.rx_fifo() + + Returns the number of words in the state machine's RX FIFO. A value of 0 + indicates the FIFO is empty. + + Useful for checking if data is waiting to be read, before calling + `StateMachine.get()`. + +.. method:: StateMachine.tx_fifo() + + Returns the number of words in the state machine's TX FIFO. A value of 0 + indicates the FIFO is empty. + + Useful for checking if there is space to push another word using + `StateMachine.put()`. + +.. method:: StateMachine.irq(handler=None, trigger=0|1, hard=False) + + Returns the IRQ object for the given StateMachine. + + Optionally configure it. + diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst new file mode 100644 index 0000000000..b6e7fcf429 --- /dev/null +++ b/docs/library/rp2.rst @@ -0,0 +1,83 @@ +.. currentmodule:: rp2 + +:mod:`rp2` --- functionality specific to the RP2040 +=================================================== + +.. module:: rp2 + :synopsis: functionality specific to the RP2 + +The ``rp2`` module contains functions and classes specific to the RP2040, as +used in the Raspberry Pi Pico. + +See the `RP2040 Python datasheet +`_ +for more information, and `pico-micropython-examples +`_ +for example code. + + +PIO related functions +--------------------- + +The ``rp2`` module includes functions for assembling PIO programs. + +For running PIO programs, see :class:`rp2.StateMachine`. + +.. function:: asm_pio(*, out_init=None, set_init=None, sideset_init=None, in_shiftdir=0, out_shiftdir=0, autopush=False, autopull=False, push_thresh=32, pull_thresh=32, fifo_join=PIO.JOIN_NONE) + + Assemble a PIO program. + + The following parameters control the initial state of the GPIO pins, as one + of `PIO.IN_LOW`, `PIO.IN_HIGH`, `PIO.OUT_LOW` or `PIO.OUT_HIGH`. If the + program uses more than one pin, provide a tuple, e.g. + ``out_init=(PIO.OUT_LOW, PIO.OUT_LOW)``. + + - *out_init* configures the pins used for ``out()`` instructions. + - *set_init* configures the pins used for ``set()`` instructions. There can + be at most 5. + - *sideset_init* configures the pins used side-setting. There can be at + most 5. + + The following parameters are used by default, but can be overriden in + `StateMachine.init()`: + + - *in_shiftdir* is the default direction the ISR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *out_shiftdir* is the default direction the OSR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *push_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + + The remaining parameters are: + + - *autopush* configures whether auto-push is enabled. + - *autopull* configures whether auto-pull is enabled. + - *fifo_join* configures whether the 4-word TX and RX FIFOs should be + combined into a single 8-word FIFO for one direction only. The options + are `PIO.JOIN_NONE`, `PIO.JOIN_RX` and `PIO.JOIN_TX`. + +.. function:: asm_pio_encode(instr, sideset_count) + + Assemble a single PIO instruction. You usually want to use `asm_pio()` + instead. + + >>> rp2.asm_pio_encode("set(0, 1)", 0) + 57345 + +.. class:: PIOASMError + + This exception is raised from `asm_pio()` or `asm_pio_encode()` if there is + an error assembling a PIO program. + + +Classes +------- + +.. toctree:: + :maxdepth: 1 + + rp2.Flash.rst + rp2.PIO.rst + rp2.StateMachine.rst From 31e0b8c71c6e9bed7388439e2441465c58311393 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 8 May 2021 18:14:13 +1000 Subject: [PATCH 086/349] esp32/mpthreadport: Don't explicitly free thread struct in TCB cleanup. Because vPortCleanUpTCB runs on the FreeRTOS idle task and cannot execute any VM or runtime related code like freeing memory. Signed-off-by: Damien George --- ports/esp32/mpthreadport.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c index 140a76464f..bbfc53d3f5 100644 --- a/ports/esp32/mpthreadport.c +++ b/ports/esp32/mpthreadport.c @@ -166,6 +166,8 @@ void mp_thread_finish(void) { mp_thread_mutex_unlock(&thread_mutex); } +// This is called from the FreeRTOS idle task and is not within Python context, +// so MP_STATE_THREAD is not valid and it does not have the GIL. void vPortCleanUpTCB(void *tcb) { if (thread == NULL) { // threading not yet initialised @@ -182,8 +184,7 @@ void vPortCleanUpTCB(void *tcb) { // move the start pointer thread = th->next; } - // explicitly release all its memory - m_del(thread_t, th, 1); + // The "th" memory will eventually be reclaimed by the GC. break; } } From 864e4ecc47f204e6ca6fbe8342e268932c89acdf Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 8 May 2021 18:17:27 +1000 Subject: [PATCH 087/349] esp32/mpthreadport: Use binary semaphore instead of mutex. So a lock can be acquired on one Python thread and then released on another. A test for this is added. Signed-off-by: Damien George --- ports/esp32/mpthreadport.c | 5 ++++- tests/thread/thread_lock5.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/thread/thread_lock5.py diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c index bbfc53d3f5..f575d99e6e 100644 --- a/ports/esp32/mpthreadport.c +++ b/ports/esp32/mpthreadport.c @@ -192,7 +192,10 @@ void vPortCleanUpTCB(void *tcb) { } void mp_thread_mutex_init(mp_thread_mutex_t *mutex) { - mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer); + // Need a binary semaphore so a lock can be acquired on one Python thread + // and then released on another. + mutex->handle = xSemaphoreCreateBinaryStatic(&mutex->buffer); + xSemaphoreGive(mutex->handle); } int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) { diff --git a/tests/thread/thread_lock5.py b/tests/thread/thread_lock5.py new file mode 100644 index 0000000000..830b5efa82 --- /dev/null +++ b/tests/thread/thread_lock5.py @@ -0,0 +1,16 @@ +# test _thread lock objects where a lock is acquired/released by a different thread + +import _thread + + +def thread_entry(): + print("thread about to release lock") + lock.release() + + +lock = _thread.allocate_lock() +lock.acquire() +_thread.start_new_thread(thread_entry, ()) +lock.acquire() +print("main has lock") +lock.release() From 9340cfe77432b548fc6ace6e2959a07a08e8eadc Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 8 May 2021 18:20:05 +1000 Subject: [PATCH 088/349] tests/thread: Make stress_create.py test run on esp32. The esp32 port needs to be idle for finished threads and their resources to be freed up. Signed-off-by: Damien George --- tests/thread/stress_create.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/thread/stress_create.py b/tests/thread/stress_create.py index eda768fa7b..877424cdf5 100644 --- a/tests/thread/stress_create.py +++ b/tests/thread/stress_create.py @@ -1,9 +1,13 @@ # stress test for creating many threads try: - import utime as time + import utime + + sleep_ms = utime.sleep_ms except ImportError: import time + + sleep_ms = lambda t: time.sleep(t / 1000) import _thread @@ -16,9 +20,11 @@ while thread_num < 500: try: _thread.start_new_thread(thread_entry, (thread_num,)) thread_num += 1 - except MemoryError: - pass + except (MemoryError, OSError) as er: + # Cannot create a new thead at this stage, yield for a bit to + # let existing threads run to completion and free up resources. + sleep_ms(50) # wait for the last threads to terminate -time.sleep(1) +sleep_ms(500) print("done") From 7b923d6c72be29e2fe57740c9ea3a2135e7db6f7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 8 May 2021 18:36:27 +1000 Subject: [PATCH 089/349] tests/thread: Make stress_aes.py test run on bare-metal ports. This is a long-running test, so make it run in reasonable time on slower, bare-metal ports. Signed-off-by: Damien George --- tests/thread/stress_aes.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/thread/stress_aes.py b/tests/thread/stress_aes.py index f73da557cb..1bf252a807 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -235,7 +235,7 @@ class LockedCounter: count = LockedCounter() -def thread_entry(): +def thread_entry(n_loop): global count aes = AES(256) @@ -244,7 +244,7 @@ def thread_entry(): data = bytearray(128) # from now on we don't use the heap - for loop in range(5): + for loop in range(n_loop): # encrypt aes.set_key(key) aes.set_iv(iv) @@ -265,8 +265,20 @@ def thread_entry(): if __name__ == "__main__": - n_thread = 20 + import sys + + if sys.platform == "rp2": + n_thread = 1 + n_loop = 2 + elif sys.platform in ("esp32", "pyboard"): + n_thread = 2 + n_loop = 2 + else: + n_thread = 20 + n_loop = 5 for i in range(n_thread): - _thread.start_new_thread(thread_entry, ()) + _thread.start_new_thread(thread_entry, (n_loop,)) + thread_entry(n_loop) while count.value < n_thread: time.sleep(1) + print("done") From d0de16266f92de180bd34f03aa43f1c489cd883a Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 9 May 2021 00:08:30 +1000 Subject: [PATCH 090/349] rp2/mpthreadport: Add mp_thread_deinit to reset core1 on soft reset. Any code running on core1 should be stopped on soft-reset (the GC heap is reset so if code continues to run on core1 it will see corrupt memory). Signed-off-by: Damien George --- ports/rp2/main.c | 3 +++ ports/rp2/mpthreadport.c | 5 +++++ ports/rp2/mpthreadport.h | 1 + 3 files changed, 9 insertions(+) diff --git a/ports/rp2/main.c b/ports/rp2/main.c index 8fddeaa560..7709a478bc 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -138,6 +138,9 @@ int main(int argc, char **argv) { mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); rp2_pio_deinit(); machine_pin_deinit(); + #if MICROPY_PY_THREAD + mp_thread_deinit(); + #endif gc_sweep_all(); mp_deinit(); } diff --git a/ports/rp2/mpthreadport.c b/ports/rp2/mpthreadport.c index fb4428772a..8a36cfca75 100644 --- a/ports/rp2/mpthreadport.c +++ b/ports/rp2/mpthreadport.c @@ -46,6 +46,11 @@ void mp_thread_init(void) { core1_entry = NULL; } +void mp_thread_deinit(void) { + multicore_reset_core1(); + core1_entry = NULL; +} + void mp_thread_gc_others(void) { if (get_core_num() == 0) { // GC running on core0, trace core1's stack, if it's running. diff --git a/ports/rp2/mpthreadport.h b/ports/rp2/mpthreadport.h index 5eb0bff396..868f8d1411 100644 --- a/ports/rp2/mpthreadport.h +++ b/ports/rp2/mpthreadport.h @@ -34,6 +34,7 @@ typedef struct mutex mp_thread_mutex_t; extern void *core_state[2]; void mp_thread_init(void); +void mp_thread_deinit(void); void mp_thread_gc_others(void); static inline void mp_thread_set_state(struct _mp_state_thread_t *state) { From b6b39bff47b5ff1ffc322a6e795d57451d4215a8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 May 2021 23:56:43 +1000 Subject: [PATCH 091/349] py/gc: Make gc_lock_depth have a count per thread. This commit makes gc_lock_depth have one counter per thread, instead of one global counter. This makes threads properly independent with respect to the GC, in particular threads can now independently lock the GC for themselves without locking it for other threads. It also means a given thread can run a hard IRQ without temporarily locking the GC for all other threads and potentially making them have MemoryError exceptions at random locations (this really only occurs on MCUs with multiple cores and no GIL, eg on the rp2 port). The commit also removes protection of the GC lock/unlock functions, which is no longer needed when the counter is per thread (and this also fixes the cas where a hard IRQ calling gc_lock() may stall waiting for the mutex). It also puts the check for `gc_lock_depth > 0` outside the GC mutex in gc_alloc, gc_realloc and gc_free, to potentially prevent a hard IRQ from waiting on a mutex if it does attempt to allocate heap memory (and putting the check outside the GC mutex is now safe now that there is a gc_lock_depth per thread). Signed-off-by: Damien George --- lib/utils/pyexec.c | 4 +-- py/gc.c | 45 ++++++++++++++-------------- py/modmicropython.c | 4 +-- py/modthread.c | 3 ++ py/mpstate.h | 4 ++- tests/thread/thread_heap_lock.py | 26 ++++++++++++++++ tests/thread/thread_heap_lock.py.exp | 1 + 7 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 tests/thread/thread_heap_lock.py create mode 100644 tests/thread/thread_heap_lock.py.exp diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index d1e955d65b..4446b36b61 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -588,8 +588,8 @@ friendly_repl_reset: // If the GC is locked at this point there is no way out except a reset, // so force the GC to be unlocked to help the user debug what went wrong. - if (MP_STATE_MEM(gc_lock_depth) != 0) { - MP_STATE_MEM(gc_lock_depth) = 0; + if (MP_STATE_THREAD(gc_lock_depth) != 0) { + MP_STATE_THREAD(gc_lock_depth) = 0; } vstr_reset(&line); diff --git a/py/gc.c b/py/gc.c index 53a0d9da4a..88adf2045e 100644 --- a/py/gc.c +++ b/py/gc.c @@ -150,7 +150,7 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_last_free_atb_index) = 0; // unlock the GC - MP_STATE_MEM(gc_lock_depth) = 0; + MP_STATE_THREAD(gc_lock_depth) = 0; // allow auto collection MP_STATE_MEM(gc_auto_collect_enabled) = 1; @@ -174,19 +174,20 @@ void gc_init(void *start, void *end) { } void gc_lock(void) { - GC_ENTER(); - MP_STATE_MEM(gc_lock_depth)++; - GC_EXIT(); + // This does not need to be atomic or have the GC mutex because: + // - each thread has its own gc_lock_depth so there are no races between threads; + // - a hard interrupt will only change gc_lock_depth during its execution, and + // upon return will restore the value of gc_lock_depth. + MP_STATE_THREAD(gc_lock_depth)++; } void gc_unlock(void) { - GC_ENTER(); - MP_STATE_MEM(gc_lock_depth)--; - GC_EXIT(); + // This does not need to be atomic, See comment above in gc_lock. + MP_STATE_THREAD(gc_lock_depth)--; } bool gc_is_locked(void) { - return MP_STATE_MEM(gc_lock_depth) != 0; + return MP_STATE_THREAD(gc_lock_depth) != 0; } // ptr should be of type void* @@ -320,7 +321,7 @@ STATIC void gc_sweep(void) { void gc_collect_start(void) { GC_ENTER(); - MP_STATE_MEM(gc_lock_depth)++; + MP_STATE_THREAD(gc_lock_depth)++; #if MICROPY_GC_ALLOC_THRESHOLD MP_STATE_MEM(gc_alloc_amount) = 0; #endif @@ -360,13 +361,13 @@ void gc_collect_end(void) { gc_deal_with_stack_overflow(); gc_sweep(); MP_STATE_MEM(gc_last_free_atb_index) = 0; - MP_STATE_MEM(gc_lock_depth)--; + MP_STATE_THREAD(gc_lock_depth)--; GC_EXIT(); } void gc_sweep_all(void) { GC_ENTER(); - MP_STATE_MEM(gc_lock_depth)++; + MP_STATE_THREAD(gc_lock_depth)++; MP_STATE_MEM(gc_stack_overflow) = 0; gc_collect_end(); } @@ -445,14 +446,13 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) { return NULL; } - GC_ENTER(); - // check if GC is locked - if (MP_STATE_MEM(gc_lock_depth) > 0) { - GC_EXIT(); + if (MP_STATE_THREAD(gc_lock_depth) > 0) { return NULL; } + GC_ENTER(); + size_t i; size_t end_block; size_t start_block; @@ -573,13 +573,13 @@ void *gc_alloc_with_finaliser(mp_uint_t n_bytes) { // force the freeing of a piece of memory // TODO: freeing here does not call finaliser void gc_free(void *ptr) { - GC_ENTER(); - if (MP_STATE_MEM(gc_lock_depth) > 0) { + if (MP_STATE_THREAD(gc_lock_depth) > 0) { // TODO how to deal with this error? - GC_EXIT(); return; } + GC_ENTER(); + DEBUG_printf("gc_free(%p)\n", ptr); if (ptr == NULL) { @@ -674,15 +674,14 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { return NULL; } + if (MP_STATE_THREAD(gc_lock_depth) > 0) { + return NULL; + } + void *ptr = ptr_in; GC_ENTER(); - if (MP_STATE_MEM(gc_lock_depth) > 0) { - GC_EXIT(); - return NULL; - } - // get the GC block number corresponding to this pointer assert(VERIFY_PTR(ptr)); size_t block = BLOCK_FROM_PTR(ptr); diff --git a/py/modmicropython.c b/py/modmicropython.c index f7eadf79bd..180f7f186c 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -130,13 +130,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_lock_obj, mp_micropython_he STATIC mp_obj_t mp_micropython_heap_unlock(void) { gc_unlock(); - return MP_OBJ_NEW_SMALL_INT(MP_STATE_MEM(gc_lock_depth)); + return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth)); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_unlock_obj, mp_micropython_heap_unlock); #if MICROPY_PY_MICROPYTHON_HEAP_LOCKED STATIC mp_obj_t mp_micropython_heap_locked(void) { - return MP_OBJ_NEW_SMALL_INT(MP_STATE_MEM(gc_lock_depth)); + return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth)); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_locked_obj, mp_micropython_heap_locked); #endif diff --git a/py/modthread.c b/py/modthread.c index 1306dc642b..64fbb3f198 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -171,6 +171,9 @@ STATIC void *thread_entry(void *args_in) { mp_pystack_init(mini_pystack, &mini_pystack[128]); #endif + // The GC starts off unlocked on this thread. + ts.gc_lock_depth = 0; + // set locals and globals from the calling context mp_locals_set(args->dict_locals); mp_globals_set(args->dict_globals); diff --git a/py/mpstate.h b/py/mpstate.h index 2519c77e2d..a0e3d4f143 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -80,7 +80,6 @@ typedef struct _mp_state_mem_t { int gc_stack_overflow; MICROPY_GC_STACK_ENTRY_TYPE gc_stack[MICROPY_ALLOC_GC_STACK_SIZE]; - uint16_t gc_lock_depth; // This variable controls auto garbage collection. If set to 0 then the // GC won't automatically run when gc_alloc can't find enough blocks. But @@ -253,6 +252,9 @@ typedef struct _mp_state_thread_t { uint8_t *pystack_cur; #endif + // Locking of the GC is done per thread. + uint16_t gc_lock_depth; + //////////////////////////////////////////////////////////// // START ROOT POINTER SECTION // Everything that needs GC scanning must start here, and diff --git a/tests/thread/thread_heap_lock.py b/tests/thread/thread_heap_lock.py new file mode 100644 index 0000000000..2837e0f366 --- /dev/null +++ b/tests/thread/thread_heap_lock.py @@ -0,0 +1,26 @@ +# test interaction of micropython.heap_lock with threads + +import _thread, micropython + +lock1 = _thread.allocate_lock() +lock2 = _thread.allocate_lock() + + +def thread_entry(): + lock1.acquire() + print([1, 2, 3]) + lock2.release() + + +lock1.acquire() +lock2.acquire() + +_thread.start_new_thread(thread_entry, ()) + +micropython.heap_lock() +lock1.release() +lock2.acquire() +micropython.heap_unlock() + +lock1.release() +lock2.release() diff --git a/tests/thread/thread_heap_lock.py.exp b/tests/thread/thread_heap_lock.py.exp new file mode 100644 index 0000000000..b5d8bb58d9 --- /dev/null +++ b/tests/thread/thread_heap_lock.py.exp @@ -0,0 +1 @@ +[1, 2, 3] From 4cdcbdb7531b98b2dc9a85737b760f509957e31e Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 10 May 2021 12:44:47 +1000 Subject: [PATCH 092/349] tests/thread: Make exc1,exit1,exit2,stacksize1,start1 tests run on rp2. The RP2040 has 2 cores and supports running at most 2 Python threads (the main one plus another), and will raise OSError if a thread cannot be created because core1 is already in use. This commit adjusts some thread tests to be robust against such OSError's. These tests now pass on rp2 boards. Signed-off-by: Damien George --- tests/thread/thread_exc1.py | 7 ++++++- tests/thread/thread_exit1.py | 9 +++++++-- tests/thread/thread_exit2.py | 9 +++++++-- tests/thread/thread_stacksize1.py | 7 ++++++- tests/thread/thread_start1.py | 9 +++++++-- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/tests/thread/thread_exc1.py b/tests/thread/thread_exc1.py index 16483d7778..cd87740929 100644 --- a/tests/thread/thread_exc1.py +++ b/tests/thread/thread_exc1.py @@ -25,7 +25,12 @@ n_finished = 0 # spawn threads for i in range(n_thread): - _thread.start_new_thread(thread_entry, ()) + while True: + try: + _thread.start_new_thread(thread_entry, ()) + break + except OSError: + pass # busy wait for threads to finish while n_finished < n_thread: diff --git a/tests/thread/thread_exit1.py b/tests/thread/thread_exit1.py index c4a93c45a3..186a9be340 100644 --- a/tests/thread/thread_exit1.py +++ b/tests/thread/thread_exit1.py @@ -13,8 +13,13 @@ def thread_entry(): _thread.exit() -_thread.start_new_thread(thread_entry, ()) -_thread.start_new_thread(thread_entry, ()) +for i in range(2): + while True: + try: + _thread.start_new_thread(thread_entry, ()) + break + except OSError: + pass # wait for threads to finish time.sleep(1) diff --git a/tests/thread/thread_exit2.py b/tests/thread/thread_exit2.py index 0cd80e6909..5be7945db2 100644 --- a/tests/thread/thread_exit2.py +++ b/tests/thread/thread_exit2.py @@ -13,8 +13,13 @@ def thread_entry(): raise SystemExit -_thread.start_new_thread(thread_entry, ()) -_thread.start_new_thread(thread_entry, ()) +for i in range(2): + while True: + try: + _thread.start_new_thread(thread_entry, ()) + break + except OSError: + pass # wait for threads to finish time.sleep(1) diff --git a/tests/thread/thread_stacksize1.py b/tests/thread/thread_stacksize1.py index 5d25509b76..cf46b73b77 100644 --- a/tests/thread/thread_stacksize1.py +++ b/tests/thread/thread_stacksize1.py @@ -41,7 +41,12 @@ n_finished = 0 # set stack size and spawn a few threads _thread.stack_size(sz) for i in range(n_thread): - _thread.start_new_thread(thread_entry, ()) + while True: + try: + _thread.start_new_thread(thread_entry, ()) + break + except OSError: + pass # reset stack size to default (for subsequent scripts on baremetal) _thread.stack_size() diff --git a/tests/thread/thread_start1.py b/tests/thread/thread_start1.py index f0e696840e..7274633245 100644 --- a/tests/thread/thread_start1.py +++ b/tests/thread/thread_start1.py @@ -18,8 +18,13 @@ def thread_entry(n): foo() -_thread.start_new_thread(thread_entry, (10,)) -_thread.start_new_thread(thread_entry, (20,)) +for i in range(2): + while True: + try: + _thread.start_new_thread(thread_entry, ((i + 1) * 10,)) + break + except OSError: + pass # wait for threads to finish time.sleep(1) From 5093d49fae5b59d6440d34b4c05f2950f40a6b9f Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 10:58:12 +1000 Subject: [PATCH 093/349] esp32: Extend support for S2 series, and S3 where applicable. Improvements made: - PSRAM support for S2 - partition definition for 16MiB flash - correct ADC and DAC pins - correct GPIO and IRQ pins - S3 components in CMakeLists Based on original commit made by Seon Rozenblum aka @UnexpectedMaker. Signed-off-by: Damien George --- ports/esp32/boards/sdkconfig.spiram_sx | 11 +++ ports/esp32/machine_adc.c | 17 +++- ports/esp32/machine_pin.c | 131 ++++++++++++++++++++++--- ports/esp32/machine_touchpad.c | 23 +++++ ports/esp32/main.c | 14 +++ ports/esp32/main/CMakeLists.txt | 3 + ports/esp32/modmachine.c | 3 + ports/esp32/mphalport.c | 7 ++ ports/esp32/partitions-16MiB.csv | 8 ++ 9 files changed, 201 insertions(+), 16 deletions(-) create mode 100644 ports/esp32/boards/sdkconfig.spiram_sx create mode 100644 ports/esp32/partitions-16MiB.csv diff --git a/ports/esp32/boards/sdkconfig.spiram_sx b/ports/esp32/boards/sdkconfig.spiram_sx new file mode 100644 index 0000000000..18a0712cbf --- /dev/null +++ b/ports/esp32/boards/sdkconfig.spiram_sx @@ -0,0 +1,11 @@ +# MicroPython on ESP32-S2 and ESP32-PAD1_subscript_3, ESP IDF configuration with SPIRAM support +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MEMTEST=y diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c index 4c19d5992b..739d47da50 100644 --- a/ports/esp32/machine_adc.c +++ b/ports/esp32/machine_adc.c @@ -43,6 +43,7 @@ typedef struct _madc_obj_t { } madc_obj_t; STATIC const madc_obj_t madc_obj[] = { + #if CONFIG_IDF_TARGET_ESP32 {{&machine_adc_type}, GPIO_NUM_36, ADC1_CHANNEL_0}, {{&machine_adc_type}, GPIO_NUM_37, ADC1_CHANNEL_1}, {{&machine_adc_type}, GPIO_NUM_38, ADC1_CHANNEL_2}, @@ -51,6 +52,18 @@ STATIC const madc_obj_t madc_obj[] = { {{&machine_adc_type}, GPIO_NUM_33, ADC1_CHANNEL_5}, {{&machine_adc_type}, GPIO_NUM_34, ADC1_CHANNEL_6}, {{&machine_adc_type}, GPIO_NUM_35, ADC1_CHANNEL_7}, + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + {{&machine_adc_type}, GPIO_NUM_1, ADC1_CHANNEL_0}, + {{&machine_adc_type}, GPIO_NUM_2, ADC1_CHANNEL_1}, + {{&machine_adc_type}, GPIO_NUM_3, ADC1_CHANNEL_2}, + {{&machine_adc_type}, GPIO_NUM_4, ADC1_CHANNEL_3}, + {{&machine_adc_type}, GPIO_NUM_5, ADC1_CHANNEL_4}, + {{&machine_adc_type}, GPIO_NUM_6, ADC1_CHANNEL_5}, + {{&machine_adc_type}, GPIO_NUM_7, ADC1_CHANNEL_6}, + {{&machine_adc_type}, GPIO_NUM_8, ADC1_CHANNEL_7}, + {{&machine_adc_type}, GPIO_NUM_9, ADC1_CHANNEL_8}, + {{&machine_adc_type}, GPIO_NUM_10, ADC1_CHANNEL_9}, + #endif }; STATIC uint8_t adc_bit_width; @@ -145,7 +158,7 @@ STATIC mp_obj_t madc_width(mp_obj_t cls_in, mp_obj_t width_in) { case ADC_WIDTH_12Bit: adc_bit_width = 12; break; - #elif CONFIG_IDF_TARGET_ESP32S2 + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 case ADC_WIDTH_BIT_13: adc_bit_width = 13; break; @@ -175,7 +188,7 @@ STATIC const mp_rom_map_elem_t madc_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_WIDTH_10BIT), MP_ROM_INT(ADC_WIDTH_10Bit) }, { MP_ROM_QSTR(MP_QSTR_WIDTH_11BIT), MP_ROM_INT(ADC_WIDTH_11Bit) }, { MP_ROM_QSTR(MP_QSTR_WIDTH_12BIT), MP_ROM_INT(ADC_WIDTH_12Bit) }, - #elif CONFIG_IDF_TARGET_ESP32S2 + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 { MP_ROM_QSTR(MP_QSTR_WIDTH_13BIT), MP_ROM_INT(ADC_WIDTH_BIT_13) }, #endif }; diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 8dbdd19849..bd623d0413 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -56,6 +56,8 @@ typedef struct _machine_pin_irq_obj_t { } machine_pin_irq_obj_t; STATIC const machine_pin_obj_t machine_pin_obj[] = { + #if CONFIG_IDF_TARGET_ESP32 + {{&machine_pin_type}, GPIO_NUM_0}, {{&machine_pin_type}, GPIO_NUM_1}, {{&machine_pin_type}, GPIO_NUM_2}, @@ -78,17 +80,10 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{&machine_pin_type}, GPIO_NUM_19}, {{NULL}, -1}, {{&machine_pin_type}, GPIO_NUM_21}, - #if CONFIG_IDF_TARGET_ESP32 {{&machine_pin_type}, GPIO_NUM_22}, {{&machine_pin_type}, GPIO_NUM_23}, {{NULL}, -1}, {{&machine_pin_type}, GPIO_NUM_25}, - #else - {{NULL}, -1}, - {{NULL}, -1}, - {{NULL}, -1}, - {{NULL}, -1}, - #endif {{&machine_pin_type}, GPIO_NUM_26}, {{&machine_pin_type}, GPIO_NUM_27}, {{NULL}, -1}, @@ -103,6 +98,63 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{&machine_pin_type}, GPIO_NUM_37}, {{&machine_pin_type}, GPIO_NUM_38}, {{&machine_pin_type}, GPIO_NUM_39}, + + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + + {{&machine_pin_type}, GPIO_NUM_0}, + {{&machine_pin_type}, GPIO_NUM_1}, + {{&machine_pin_type}, GPIO_NUM_2}, + {{&machine_pin_type}, GPIO_NUM_3}, + {{&machine_pin_type}, GPIO_NUM_4}, + {{&machine_pin_type}, GPIO_NUM_5}, + {{&machine_pin_type}, GPIO_NUM_6}, + {{&machine_pin_type}, GPIO_NUM_7}, + {{&machine_pin_type}, GPIO_NUM_8}, + {{&machine_pin_type}, GPIO_NUM_9}, + {{&machine_pin_type}, GPIO_NUM_10}, + {{&machine_pin_type}, GPIO_NUM_11}, + {{&machine_pin_type}, GPIO_NUM_12}, + {{&machine_pin_type}, GPIO_NUM_13}, + {{&machine_pin_type}, GPIO_NUM_14}, + {{&machine_pin_type}, GPIO_NUM_15}, + {{&machine_pin_type}, GPIO_NUM_16}, + {{&machine_pin_type}, GPIO_NUM_17}, + {{&machine_pin_type}, GPIO_NUM_18}, + #if CONFIG_USB_CDC_ENABLED + {{NULL}, -1}, // 19 is for native USB D- + {{NULL}, -1}, // 20 is for native USB D- + #else + {{&machine_pin_type}, GPIO_NUM_19}, + {{&machine_pin_type}, GPIO_NUM_20}, + #endif + {{&machine_pin_type}, GPIO_NUM_21}, + {{NULL}, -1}, // 22 not a pin + {{NULL}, -1}, // 23 not a pin + {{NULL}, -1}, // 24 not a pin + {{NULL}, -1}, // 25 not a pin + {{NULL}, -1}, // 26 FLASH/PSRAM + {{NULL}, -1}, // 27 FLASH/PSRAM + {{NULL}, -1}, // 28 FLASH/PSRAM + {{NULL}, -1}, // 29 FLASH/PSRAM + {{NULL}, -1}, // 30 FLASH/PSRAM + {{NULL}, -1}, // 31 FLASH/PSRAM + {{NULL}, -1}, // 32 FLASH/PSRAM + {{&machine_pin_type}, GPIO_NUM_33}, + {{&machine_pin_type}, GPIO_NUM_34}, + {{&machine_pin_type}, GPIO_NUM_35}, + {{&machine_pin_type}, GPIO_NUM_36}, + {{&machine_pin_type}, GPIO_NUM_37}, + {{&machine_pin_type}, GPIO_NUM_38}, + {{&machine_pin_type}, GPIO_NUM_39}, // MTCLK + {{&machine_pin_type}, GPIO_NUM_40}, // MTDO + {{&machine_pin_type}, GPIO_NUM_41}, // MTDI + {{&machine_pin_type}, GPIO_NUM_42}, // MTMS + {{&machine_pin_type}, GPIO_NUM_43}, // U0TXD + {{&machine_pin_type}, GPIO_NUM_44}, // U0RXD + {{&machine_pin_type}, GPIO_NUM_45}, + {{&machine_pin_type}, GPIO_NUM_46}, + + #endif }; // forward declaration @@ -399,6 +451,8 @@ const mp_obj_type_t machine_pin_type = { STATIC const mp_obj_type_t machine_pin_irq_type; STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { + #if CONFIG_IDF_TARGET_ESP32 + {{&machine_pin_irq_type}, GPIO_NUM_0}, {{&machine_pin_irq_type}, GPIO_NUM_1}, {{&machine_pin_irq_type}, GPIO_NUM_2}, @@ -421,17 +475,10 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { {{&machine_pin_irq_type}, GPIO_NUM_19}, {{NULL}, -1}, {{&machine_pin_irq_type}, GPIO_NUM_21}, - #if CONFIG_IDF_TARGET_ESP32 {{&machine_pin_irq_type}, GPIO_NUM_22}, {{&machine_pin_irq_type}, GPIO_NUM_23}, {{NULL}, -1}, {{&machine_pin_irq_type}, GPIO_NUM_25}, - #else - {{NULL}, -1}, - {{NULL}, -1}, - {{NULL}, -1}, - {{NULL}, -1}, - #endif {{&machine_pin_irq_type}, GPIO_NUM_26}, {{&machine_pin_irq_type}, GPIO_NUM_27}, {{NULL}, -1}, @@ -446,6 +493,62 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[] = { {{&machine_pin_irq_type}, GPIO_NUM_37}, {{&machine_pin_irq_type}, GPIO_NUM_38}, {{&machine_pin_irq_type}, GPIO_NUM_39}, + + #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + + {{&machine_pin_irq_type}, GPIO_NUM_0}, + {{&machine_pin_irq_type}, GPIO_NUM_1}, + {{&machine_pin_irq_type}, GPIO_NUM_2}, + {{&machine_pin_irq_type}, GPIO_NUM_3}, + {{&machine_pin_irq_type}, GPIO_NUM_4}, + {{&machine_pin_irq_type}, GPIO_NUM_5}, + {{&machine_pin_irq_type}, GPIO_NUM_6}, + {{&machine_pin_irq_type}, GPIO_NUM_7}, + {{&machine_pin_irq_type}, GPIO_NUM_8}, + {{&machine_pin_irq_type}, GPIO_NUM_9}, + {{&machine_pin_irq_type}, GPIO_NUM_10}, + {{&machine_pin_irq_type}, GPIO_NUM_11}, + {{&machine_pin_irq_type}, GPIO_NUM_12}, + {{&machine_pin_irq_type}, GPIO_NUM_13}, + {{&machine_pin_irq_type}, GPIO_NUM_14}, + {{&machine_pin_irq_type}, GPIO_NUM_15}, + {{&machine_pin_irq_type}, GPIO_NUM_16}, + {{&machine_pin_irq_type}, GPIO_NUM_17}, + {{&machine_pin_irq_type}, GPIO_NUM_18}, + #if CONFIG_USB_CDC_ENABLED + {{NULL}, -1}, // 19 is for native USB D- + {{NULL}, -1}, // 20 is for native USB D- + #else + {{&machine_pin_irq_type}, GPIO_NUM_19}, + {{&machine_pin_irq_type}, GPIO_NUM_20}, + #endif + {{&machine_pin_irq_type}, GPIO_NUM_21}, + {{NULL}, -1}, // 22 not a pin + {{NULL}, -1}, // 23 not a pin + {{NULL}, -1}, // 24 not a pin + {{NULL}, -1}, // 25 not a pin + {{NULL}, -1}, // 26 FLASH/PSRAM + {{NULL}, -1}, // 27 FLASH/PSRAM + {{NULL}, -1}, // 28 FLASH/PSRAM + {{NULL}, -1}, // 29 FLASH/PSRAM + {{NULL}, -1}, // 30 FLASH/PSRAM + {{NULL}, -1}, // 31 FLASH/PSRAM + {{NULL}, -1}, // 32 FLASH/PSRAM + {{&machine_pin_irq_type}, GPIO_NUM_33}, + {{&machine_pin_irq_type}, GPIO_NUM_34}, + {{&machine_pin_irq_type}, GPIO_NUM_35}, + {{&machine_pin_irq_type}, GPIO_NUM_36}, + {{&machine_pin_irq_type}, GPIO_NUM_37}, + {{&machine_pin_irq_type}, GPIO_NUM_38}, + {{&machine_pin_irq_type}, GPIO_NUM_39}, + {{&machine_pin_irq_type}, GPIO_NUM_40}, + {{&machine_pin_irq_type}, GPIO_NUM_41}, + {{&machine_pin_irq_type}, GPIO_NUM_42}, + {{&machine_pin_irq_type}, GPIO_NUM_43}, + {{&machine_pin_irq_type}, GPIO_NUM_44}, + {{&machine_pin_irq_type}, GPIO_NUM_45}, + + #endif }; STATIC mp_obj_t machine_pin_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { diff --git a/ports/esp32/machine_touchpad.c b/ports/esp32/machine_touchpad.c index 335157b154..168ac16d0e 100644 --- a/ports/esp32/machine_touchpad.c +++ b/ports/esp32/machine_touchpad.c @@ -31,7 +31,11 @@ #if CONFIG_IDF_TARGET_ESP32 #include "driver/gpio.h" +#if CONFIG_IDF_TARGET_ESP32 #include "driver/touch_pad.h" +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#include "driver/touch_sensor.h" +#endif typedef struct _mtp_obj_t { mp_obj_base_t base; @@ -39,6 +43,7 @@ typedef struct _mtp_obj_t { touch_pad_t touchpad_id; } mtp_obj_t; +#if CONFIG_IDF_TARGET_ESP32 STATIC const mtp_obj_t touchpad_obj[] = { {{&machine_touchpad_type}, GPIO_NUM_4, TOUCH_PAD_NUM0}, {{&machine_touchpad_type}, GPIO_NUM_0, TOUCH_PAD_NUM1}, @@ -51,6 +56,24 @@ STATIC const mtp_obj_t touchpad_obj[] = { {{&machine_touchpad_type}, GPIO_NUM_33, TOUCH_PAD_NUM8}, {{&machine_touchpad_type}, GPIO_NUM_32, TOUCH_PAD_NUM9}, }; +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +STATIC const mtp_obj_t touchpad_obj[] = { + {{&machine_touchpad_type}, GPIO_NUM_1, TOUCH_PAD_NUM1}, + {{&machine_touchpad_type}, GPIO_NUM_2, TOUCH_PAD_NUM2}, + {{&machine_touchpad_type}, GPIO_NUM_3, TOUCH_PAD_NUM3}, + {{&machine_touchpad_type}, GPIO_NUM_4, TOUCH_PAD_NUM4}, + {{&machine_touchpad_type}, GPIO_NUM_5, TOUCH_PAD_NUM5}, + {{&machine_touchpad_type}, GPIO_NUM_6, TOUCH_PAD_NUM6}, + {{&machine_touchpad_type}, GPIO_NUM_7, TOUCH_PAD_NUM7}, + {{&machine_touchpad_type}, GPIO_NUM_8, TOUCH_PAD_NUM8}, + {{&machine_touchpad_type}, GPIO_NUM_9, TOUCH_PAD_NUM9}, + {{&machine_touchpad_type}, GPIO_NUM_10, TOUCH_PAD_NUM10}, + {{&machine_touchpad_type}, GPIO_NUM_11, TOUCH_PAD_NUM11}, + {{&machine_touchpad_type}, GPIO_NUM_12, TOUCH_PAD_NUM12}, + {{&machine_touchpad_type}, GPIO_NUM_13, TOUCH_PAD_NUM13}, + {{&machine_touchpad_type}, GPIO_NUM_14, TOUCH_PAD_NUM14}, +}; +#endif STATIC mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 7ca3d84140..ff6dd69574 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -42,6 +42,8 @@ #include "esp32/spiram.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/spiram.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/spiram.h" #endif #include "py/stackctrl.h" @@ -104,6 +106,18 @@ void mp_task(void *pvParameter) { mp_task_heap = malloc(mp_task_heap_size); break; } + #elif CONFIG_ESP32S2_SPIRAM_SUPPORT || CONFIG_ESP32S3_SPIRAM_SUPPORT + // Try to use the entire external SPIRAM directly for the heap + size_t mp_task_heap_size; + size_t esp_spiram_size = esp_spiram_get_size(); + void *mp_task_heap = (void *)0x3ff80000 - esp_spiram_size; + if (esp_spiram_size > 0) { + mp_task_heap_size = esp_spiram_size; + } else { + // No SPIRAM, fallback to normal allocation + mp_task_heap_size = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT); + mp_task_heap = malloc(mp_task_heap_size); + } #else // Allocate the uPy heap using malloc and get the largest available region size_t mp_task_heap_size = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT); diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 656045da90..1cc30b71ec 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -128,6 +128,9 @@ if(IDF_TARGET STREQUAL "esp32") elseif(IDF_TARGET STREQUAL "esp32s2") list(APPEND IDF_COMPONENTS esp32s2) list(APPEND IDF_COMPONENTS tinyusb) +elseif(IDF_TARGET STREQUAL "esp32s3") + list(APPEND IDF_COMPONENTS esp32s3) + list(APPEND IDF_COMPONENTS tinyusb) endif() # Register the main IDF component. diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 2eb5cd2fee..bbe7fae033 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -42,6 +42,9 @@ #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/rtc.h" #include "esp32s2/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/rtc.h" +#include "esp32s3/clk.h" #endif #include "py/obj.h" diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index cf668216df..a0bafb755e 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -32,7 +32,14 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" + +#if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/uart.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/uart.h" +#endif #include "py/obj.h" #include "py/objstr.h" diff --git a/ports/esp32/partitions-16MiB.csv b/ports/esp32/partitions-16MiB.csv new file mode 100644 index 0000000000..5133185c78 --- /dev/null +++ b/ports/esp32/partitions-16MiB.csv @@ -0,0 +1,8 @@ +# Notes: the offset of the partition table itself is set in +# $ESPIDF/components/partition_table/Kconfig.projbuild and the +# offset of the factory/ota_0 partition is set in makeimg.py +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x180000, +vfs, data, fat, 0x200000, 0xD59F80, From 32ec07a3504d6dcbfc53997197a3c53e8c03497f Mon Sep 17 00:00:00 2001 From: Seon Rozenblum Date: Fri, 19 Mar 2021 18:48:34 +1100 Subject: [PATCH 094/349] esp32/boards: Rename TINYPICO board to UM_TINYPICO. And add default hardware SPI 0 pins in mpconfigboard.h, and CONFIG_LWIP_LOCAL_HOSTNAME in sdkconfig.board. --- ports/esp32/boards/TINYPICO/mpconfigboard.h | 2 -- ports/esp32/boards/{TINYPICO => UM_TINYPICO}/manifest.py | 0 .../boards/{TINYPICO => UM_TINYPICO}/modules/dotstar.py | 0 .../boards/{TINYPICO => UM_TINYPICO}/modules/tinypico.py | 0 .../boards/{TINYPICO => UM_TINYPICO}/mpconfigboard.cmake | 0 ports/esp32/boards/UM_TINYPICO/mpconfigboard.h | 6 ++++++ .../esp32/boards/{TINYPICO => UM_TINYPICO}/sdkconfig.board | 1 + 7 files changed, 7 insertions(+), 2 deletions(-) delete mode 100644 ports/esp32/boards/TINYPICO/mpconfigboard.h rename ports/esp32/boards/{TINYPICO => UM_TINYPICO}/manifest.py (100%) rename ports/esp32/boards/{TINYPICO => UM_TINYPICO}/modules/dotstar.py (100%) rename ports/esp32/boards/{TINYPICO => UM_TINYPICO}/modules/tinypico.py (100%) rename ports/esp32/boards/{TINYPICO => UM_TINYPICO}/mpconfigboard.cmake (100%) create mode 100644 ports/esp32/boards/UM_TINYPICO/mpconfigboard.h rename ports/esp32/boards/{TINYPICO => UM_TINYPICO}/sdkconfig.board (72%) diff --git a/ports/esp32/boards/TINYPICO/mpconfigboard.h b/ports/esp32/boards/TINYPICO/mpconfigboard.h deleted file mode 100644 index e63f43ed25..0000000000 --- a/ports/esp32/boards/TINYPICO/mpconfigboard.h +++ /dev/null @@ -1,2 +0,0 @@ -#define MICROPY_HW_BOARD_NAME "TinyPICO" -#define MICROPY_HW_MCU_NAME "ESP32-PICO-D4" diff --git a/ports/esp32/boards/TINYPICO/manifest.py b/ports/esp32/boards/UM_TINYPICO/manifest.py similarity index 100% rename from ports/esp32/boards/TINYPICO/manifest.py rename to ports/esp32/boards/UM_TINYPICO/manifest.py diff --git a/ports/esp32/boards/TINYPICO/modules/dotstar.py b/ports/esp32/boards/UM_TINYPICO/modules/dotstar.py similarity index 100% rename from ports/esp32/boards/TINYPICO/modules/dotstar.py rename to ports/esp32/boards/UM_TINYPICO/modules/dotstar.py diff --git a/ports/esp32/boards/TINYPICO/modules/tinypico.py b/ports/esp32/boards/UM_TINYPICO/modules/tinypico.py similarity index 100% rename from ports/esp32/boards/TINYPICO/modules/tinypico.py rename to ports/esp32/boards/UM_TINYPICO/modules/tinypico.py diff --git a/ports/esp32/boards/TINYPICO/mpconfigboard.cmake b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake similarity index 100% rename from ports/esp32/boards/TINYPICO/mpconfigboard.cmake rename to ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake diff --git a/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h new file mode 100644 index 0000000000..05ee5eaf72 --- /dev/null +++ b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h @@ -0,0 +1,6 @@ +#define MICROPY_HW_BOARD_NAME "TinyPICO" +#define MICROPY_HW_MCU_NAME "ESP32-PICO-D4" + +#define MICROPY_HW_SPI1_SCK (18) +#define MICROPY_HW_SPI1_MOSI (23) +#define MICROPY_HW_SPI1_MISO (19) diff --git a/ports/esp32/boards/TINYPICO/sdkconfig.board b/ports/esp32/boards/UM_TINYPICO/sdkconfig.board similarity index 72% rename from ports/esp32/boards/TINYPICO/sdkconfig.board rename to ports/esp32/boards/UM_TINYPICO/sdkconfig.board index dc2c23f674..766419c7f8 100644 --- a/ports/esp32/boards/TINYPICO/sdkconfig.board +++ b/ports/esp32/boards/UM_TINYPICO/sdkconfig.board @@ -2,3 +2,4 @@ CONFIG_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_SPIRAM_SPEED_80M=y CONFIG_ESP32_REV_MIN_1=y +CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyPICO" From 0e87459e2bfd073a084fe4af00c2f75d4c815639 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 11:08:00 +1000 Subject: [PATCH 095/349] esp32/boards: Add UM_FEATHERS2 and UM_TINYS2 board definitions. Based on original commit made by Seon Rozenblum aka @UnexpectedMaker. Signed-off-by: Damien George --- ports/esp32/boards/UM_FEATHERS2/manifest.py | 3 + .../boards/UM_FEATHERS2/modules/feathers2.py | 101 ++++++++++++++++++ .../boards/UM_FEATHERS2/mpconfigboard.cmake | 9 ++ .../esp32/boards/UM_FEATHERS2/mpconfigboard.h | 5 + .../esp32/boards/UM_FEATHERS2/sdkconfig.board | 16 +++ ports/esp32/boards/UM_TINYS2/manifest.py | 2 + .../esp32/boards/UM_TINYS2/modules/tinys2.py | 82 ++++++++++++++ .../boards/UM_TINYS2/mpconfigboard.cmake | 8 ++ ports/esp32/boards/UM_TINYS2/mpconfigboard.h | 9 ++ ports/esp32/boards/UM_TINYS2/sdkconfig.board | 6 ++ 10 files changed, 241 insertions(+) create mode 100644 ports/esp32/boards/UM_FEATHERS2/manifest.py create mode 100644 ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py create mode 100644 ports/esp32/boards/UM_FEATHERS2/mpconfigboard.cmake create mode 100644 ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h create mode 100644 ports/esp32/boards/UM_FEATHERS2/sdkconfig.board create mode 100644 ports/esp32/boards/UM_TINYS2/manifest.py create mode 100644 ports/esp32/boards/UM_TINYS2/modules/tinys2.py create mode 100644 ports/esp32/boards/UM_TINYS2/mpconfigboard.cmake create mode 100644 ports/esp32/boards/UM_TINYS2/mpconfigboard.h create mode 100644 ports/esp32/boards/UM_TINYS2/sdkconfig.board diff --git a/ports/esp32/boards/UM_FEATHERS2/manifest.py b/ports/esp32/boards/UM_FEATHERS2/manifest.py new file mode 100644 index 0000000000..82ad0c7e49 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/manifest.py @@ -0,0 +1,3 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("$(PORT_DIR)/boards/UM_TINYPICO/modules", "dotstar.py") +freeze("modules") diff --git a/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py new file mode 100644 index 0000000000..32126fc9c9 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py @@ -0,0 +1,101 @@ +# FeatherS2 MicroPython Helper Library +# 2021 Seon Rozenblum - Unexpected Maker +# +# Project home: +# https://feathers2.io +# +# 2021-Mar-21 - v0.1 - Initial implementation + +# Import required libraries +from micropython import const +from machine import Pin, SPI, ADC +import machine, time + +# FeatherS2 Hardware Pin Assignments + +# LDO +LDO2 = const(21) + +# APA102 Dotstar pins +DOTSTAR_CLK = const(45) +DOTSTAR_DATA = const(40) + +# SPI +SPI_MOSI = const(35) +SPI_MISO = const(36) +SPI_CLK = const(37) + +# I2C +I2C_SDA = const(38) +I2C_SCL = const(33) + +# DAC +DAC1 = const(17) +DAC2 = const(18) + +# LED & Ambient Light Sensor +LED = const(13) +AMB_LIGHT = const(4) + +# Helper functions + +# LED & Ambient Light Sensor control +def set_led(state): + l = Pin(LED, Pin.OUT) + l.value(state) + + +def toggle_led(state): + l = Pin(LED, Pin.OUT) + l.value(not l.value()) + + +# Create ADC and set attenuation and return teh ambient light value from the onboard sensor +def get_amb_light(): + adc = ADC(Pin(AMB_LIGHT)) + adc.atten(ADC.ATTN_11DB) + return adc.read() + + +# LDO2 power control +# When we manually turn off the second LDO we also set the DotStar DATA and CLK pins to input to +# prevent parasitic power from lighting the LED even with the LDO off, causing current use. +# The DotStar is a beautiful LED, but parasitic power makes it a terrible choice for battery use :( +def set_ldo2_power(state): + """Set the power for the on-board Dostar to allow no current draw when not needed.""" + # Set the power pin to the inverse of state + ldo2 = Pin(LDO2, Pin.OUT) + ldo2.value(state) + + if state: + Pin(DOTSTAR_CLK, Pin.OUT) + Pin(DOTSTAR_DATA, Pin.OUT) # If power is on, set CLK to be output, otherwise input + else: + Pin(DOTSTAR_CLK, Pin.IN) + Pin(DOTSTAR_DATA, Pin.IN) # If power is on, set CLK to be output, otherwise input + + # A small delay to let the IO change state + time.sleep(0.035) + + +# Dotstar rainbow colour wheel +def dotstar_color_wheel(wheel_pos): + """Color wheel to allow for cycling through the rainbow of RGB colors.""" + wheel_pos = wheel_pos % 255 + + if wheel_pos < 85: + return 255 - wheel_pos * 3, 0, wheel_pos * 3 + elif wheel_pos < 170: + wheel_pos -= 85 + return 0, wheel_pos * 3, 255 - wheel_pos * 3 + else: + wheel_pos -= 170 + return wheel_pos * 3, 255 - wheel_pos * 3, 0 + + +# Go into deep sleep but shut down the APA first to save power +# Use this if you want lowest deep sleep current +def go_deepsleep(t): + """Deep sleep helper that also powers down the on-board Dotstar.""" + set_ldo2_power(False) + machine.deepsleep(t) diff --git a/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.cmake b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.cmake new file mode 100644 index 0000000000..5e570d513b --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.cmake @@ -0,0 +1,9 @@ +set(IDF_TARGET esp32s2) +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb + boards/UM_FEATHERS2/sdkconfig.board +) + +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) \ No newline at end of file diff --git a/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h new file mode 100644 index 0000000000..c045adccd9 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h @@ -0,0 +1,5 @@ +#define MICROPY_HW_BOARD_NAME "FeatherS2" +#define MICROPY_HW_MCU_NAME "ESP32-S2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) \ No newline at end of file diff --git a/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board b/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board new file mode 100644 index 0000000000..ccda7bff68 --- /dev/null +++ b/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board @@ -0,0 +1,16 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_SPIRAM_MEMTEST= + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB= +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16MiB.csv" +#CONFIG_USB_AND_UART=y + +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2" +# end of LWIP diff --git a/ports/esp32/boards/UM_TINYS2/manifest.py b/ports/esp32/boards/UM_TINYS2/manifest.py new file mode 100644 index 0000000000..7ae2ed15d9 --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/manifest.py @@ -0,0 +1,2 @@ +include("$(PORT_DIR)/boards/manifest.py") +freeze("modules") diff --git a/ports/esp32/boards/UM_TINYS2/modules/tinys2.py b/ports/esp32/boards/UM_TINYS2/modules/tinys2.py new file mode 100644 index 0000000000..ca59cb1235 --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/modules/tinys2.py @@ -0,0 +1,82 @@ +# TinyS2 MicroPython Helper Library +# 2021 Seon Rozenblum - Unexpected Maker +# +# Project home: +# https://tinys2.io +# +# 2021-Apr-10 - v0.1 - Initial implementation + +# Import required libraries +from micropython import const +from machine import Pin, SPI, ADC +import machine, time + +# TinyS2 Hardware Pin Assignments + +# Sense Pins +VBUS_SENSE = const(21) +VBAT_SENSE = const(3) + + +# RGB LED Pins +RGB_DATA = const(1) +RGB_PWR = const(2) + +# SPI +SPI_MOSI = const(35) +SPI_MISO = const(36) +SPI_CLK = const(37) + +# I2C +I2C_SDA = const(8) +I2C_SCL = const(9) + +# DAC +DAC1 = const(17) +DAC2 = const(18) + + +# Helper functions +def set_pixel_power(state): + """Enable or Disable power to the onboard NeoPixel to either show colour, or to reduce power fro deep sleep.""" + Pin(RGB_PWR, Pin.OUT).value(state) + + +def get_battery_voltage(): + """ + Returns the current battery voltage. If no battery is connected, returns 4.2V which is the charge voltage + This is an approximation only, but useful to detect if the charge state of the battery is getting low. + """ + adc = ADC(Pin(VBAT_SENSE)) # Assign the ADC pin to read + measuredvbat = adc.read() # Read the value + measuredvbat /= 8192 # divide by 8192 as we are using the default ADC voltage range of 0-1V + measuredvbat *= 4.2 # Multiply by 4.2V, our reference voltage + return round(measuredvbat, 2) + + +def get_vbus_present(): + """Detect if VBUS (5V) power source is present""" + return Pin(VBUS_SENSE, Pin.IN).value() == 1 + + +# Dotstar rainbow colour wheel +def rgb_color_wheel(wheel_pos): + """Color wheel to allow for cycling through the rainbow of RGB colors.""" + wheel_pos = wheel_pos % 255 + + if wheel_pos < 85: + return 255 - wheel_pos * 3, 0, wheel_pos * 3 + elif wheel_pos < 170: + wheel_pos -= 85 + return 0, wheel_pos * 3, 255 - wheel_pos * 3 + else: + wheel_pos -= 170 + return wheel_pos * 3, 255 - wheel_pos * 3, 0 + + +# Go into deep sleep but shut down the APA first to save power +# Use this if you want lowest deep sleep current +def go_deepsleep(t): + """Deep sleep helper that also powers down the on-board Dotstar.""" + set_pixel_power(False) + machine.deepsleep(t) diff --git a/ports/esp32/boards/UM_TINYS2/mpconfigboard.cmake b/ports/esp32/boards/UM_TINYS2/mpconfigboard.cmake new file mode 100644 index 0000000000..928f9f8fc3 --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/mpconfigboard.cmake @@ -0,0 +1,8 @@ +set(IDF_TARGET esp32s2) +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.spiram_sx + boards/sdkconfig.usb +) + +set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) diff --git a/ports/esp32/boards/UM_TINYS2/mpconfigboard.h b/ports/esp32/boards/UM_TINYS2/mpconfigboard.h new file mode 100644 index 0000000000..87d266e58c --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/mpconfigboard.h @@ -0,0 +1,9 @@ +#define MICROPY_HW_BOARD_NAME "TinyS2" +#define MICROPY_HW_MCU_NAME "ESP32-S2FN4R2" + +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_SPI1_MOSI (35) +#define MICROPY_HW_SPI1_MISO (36) +#define MICROPY_HW_SPI1_SCK (37) diff --git a/ports/esp32/boards/UM_TINYS2/sdkconfig.board b/ports/esp32/boards/UM_TINYS2/sdkconfig.board new file mode 100644 index 0000000000..48b6749c72 --- /dev/null +++ b/ports/esp32/boards/UM_TINYS2/sdkconfig.board @@ -0,0 +1,6 @@ +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_USB_AND_UART=y +# LWIP +CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS2" +# end of LWIP From cce7096d1a031f43f72c2ea87513301c3db118dc Mon Sep 17 00:00:00 2001 From: Chris Greening Date: Mon, 10 May 2021 18:17:31 +0100 Subject: [PATCH 096/349] esp32/boards/UM_TINYPICO: Fix include of sdkconfig fragment. This was broken by 32ec07a3504d6dcbfc53997197a3c53e8c03497f --- ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake index 0c65103a85..bc2541c699 100644 --- a/ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake +++ b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.cmake @@ -3,7 +3,7 @@ set(SDKCONFIG_DEFAULTS boards/sdkconfig.ble boards/sdkconfig.240mhz boards/sdkconfig.spiram - boards/TINYPICO/sdkconfig.board + boards/UM_TINYPICO/sdkconfig.board ) if(NOT MICROPY_FROZEN_MANIFEST) From 4404dababb715916262ca9aa45a5732d8454eda0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 May 2021 12:46:18 +1000 Subject: [PATCH 097/349] rp2/CMakeLists.txt: Include tinyusb_common in PICO_SDK_COMPONENTS. So the TinyUSB headers can be found during qstr processing. Fixes issue #7236. Signed-off-by: Damien George --- ports/rp2/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 699520b240..50cdba4ba0 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -154,6 +154,7 @@ set(PICO_SDK_COMPONENTS pico_sync pico_time pico_unique_id + tinyusb_common tinyusb_device ) From 70f50c46cc8ae0cd6802c7998874b5ea7c410119 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 9 Apr 2018 01:00:01 +0200 Subject: [PATCH 098/349] lib/utils: Add ARM semihosting utility functions. This can be a replacement for a UART in custom ports. --- lib/utils/semihosting.c | 132 ++++++++++++++++++++++++++++++++++++++++ lib/utils/semihosting.h | 51 ++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 lib/utils/semihosting.c create mode 100644 lib/utils/semihosting.h diff --git a/lib/utils/semihosting.c b/lib/utils/semihosting.c new file mode 100644 index 0000000000..18c7f5d57a --- /dev/null +++ b/lib/utils/semihosting.c @@ -0,0 +1,132 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Ayke van Laethem + * + * 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 "semihosting.h" + +// Resources: +// http://embed.rs/articles/2016/semi-hosting-rust/ +// https://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22 +// https://github.com/arduino/OpenOCD/blob/master/src/target/arm_semihosting.c + +#define SYS_OPEN 0x01 +#define SYS_WRITEC 0x03 +#define SYS_WRITE 0x05 +#define SYS_READC 0x07 + +// Constants: +#define OPEN_MODE_READ (0) // mode "r" +#define OPEN_MODE_WRITE (4) // mode "w" + +#ifndef __thumb__ +#error Semihosting is only implemented for ARM microcontrollers. +#endif + +static int mp_semihosting_stdout; + +static uint32_t mp_semihosting_call(uint32_t num, const void *arg) { + // A semihosting call works as follows, similar to a SVCall: + // * the call is invoked by a special breakpoint: 0xAB + // * the command is placed in r0 + // * a pointer to the arguments is placed in r1 + // * the return value is placed in r0 + // Note that because it uses the breakpoint instruction, applications + // will hang if they're not connected to a debugger. And they'll be + // stuck in a breakpoint if semihosting is not specifically enabled in + // the debugger. + // Also note that semihosting is extremely slow (sometimes >100ms per + // call). + register uint32_t num_reg __asm__ ("r0") = num; + register const void *args_reg __asm__ ("r1") = arg; + __asm__ __volatile__ ( + "bkpt 0xAB\n" // invoke semihosting call + : "+r" (num_reg) // call number and result + : "r" (args_reg) // arguments + : "memory"); // make sure args aren't optimized away + return num_reg; // r0, which became the result +} + +static int mp_semihosting_open_console(uint32_t mode) { + struct { + char *name; + uint32_t mode; + uint32_t name_len; + } args = { + .name = ":tt", // magic path to console + .mode = mode, // e.g. "r", "w" (see OPEN_MODE_* constants) + .name_len = 3, // strlen(":tt") + }; + return mp_semihosting_call(SYS_OPEN, &args); +} + +void mp_semihosting_init() { + mp_semihosting_stdout = mp_semihosting_open_console(OPEN_MODE_WRITE); +} + +int mp_semihosting_rx_char() { + return mp_semihosting_call(SYS_READC, NULL); +} + +static void mp_semihosting_tx_char(char c) { + mp_semihosting_call(SYS_WRITEC, &c); +} + +uint32_t mp_semihosting_tx_strn(const char *str, size_t len) { + if (len == 0) { + return 0; // nothing to do + } + if (len == 1) { + mp_semihosting_tx_char(*str); // maybe faster? + return 0; + } + + struct { + uint32_t fd; + const char *str; + uint32_t len; + } args = { + .fd = mp_semihosting_stdout, + .str = str, + .len = len, + }; + return mp_semihosting_call(SYS_WRITE, &args); +} + +uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len) { + // Write chunks of data until (excluding) the first '\n' character, + // insert a '\r' character, and then continue with the next chunk + // (starting with '\n'). + // Doing byte-by-byte writes would be easier to implement but is far + // too slow. + size_t start = 0; + for (size_t i = 0; i < len; i++) { + if (str[i] == '\n') { + mp_semihosting_tx_strn(str + start, i - start); + mp_semihosting_tx_char('\r'); + start = i; + } + } + return mp_semihosting_tx_strn(str + start, len - start); +} diff --git a/lib/utils/semihosting.h b/lib/utils/semihosting.h new file mode 100644 index 0000000000..d053a03eda --- /dev/null +++ b/lib/utils/semihosting.h @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Ayke van Laethem + * + * 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_SEMIHOSTING_H +#define MICROPY_INCLUDED_LIB_UTILS_SEMIHOSTING_H + +/* + +To use semi-hosting for a replacement UART: +- Add lib/semihosting/semihosting.c to the Makefile sources. +- Call mp_semihosting_init() in main(), around the time UART is initialized. +- Replace mp_hal_stdin_rx_chr and similar in mphalport.c with the semihosting equivalent. +- Include lib/semihosting/semihosting.h in the relevant files. + +Then make sure the debugger is attached and enables semihosting. In OpenOCD this is +done with ARM semihosting enable followed by reset. The terminal will need further +configuration to work with MicroPython (bash: stty raw -echo). + +*/ + +#include +#include + +void mp_semihosting_init(); +int mp_semihosting_rx_char(); +uint32_t mp_semihosting_tx_strn(const char *str, size_t len); +uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len); + +#endif // MICROPY_INCLUDED_LIB_UTILS_SEMIHOSTING_H From 18d984c8b2053ddc17f02816cb037f13afee685a Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 May 2021 23:45:36 +1000 Subject: [PATCH 099/349] tests/run-perfbench.py: Fix native feature check. This was broken by 8459f538eb45fd8e1e4d614298449cf18de84d75 Signed-off-by: Damien George --- tests/run-perfbench.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index 8b71ae64ce..bcdbe69abb 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -85,7 +85,7 @@ def run_benchmark_on_target(target, script): def run_benchmarks(target, param_n, param_m, n_average, test_list): skip_complex = run_feature_test(target, "complex") != "complex" - skip_native = run_feature_test(target, "native_check") != "" + skip_native = run_feature_test(target, "native_check") != "native" for test_file in sorted(test_list): print(test_file + ": ", end="") From 87e38b3cc83be7297957b5ec9b701769ffe2d6e3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 May 2021 00:05:55 +1000 Subject: [PATCH 100/349] docs/library/rp2.rst: Fix typo overriden->overridden. Signed-off-by: Damien George --- docs/library/rp2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst index b6e7fcf429..5d168bce20 100644 --- a/docs/library/rp2.rst +++ b/docs/library/rp2.rst @@ -38,7 +38,7 @@ For running PIO programs, see :class:`rp2.StateMachine`. - *sideset_init* configures the pins used side-setting. There can be at most 5. - The following parameters are used by default, but can be overriden in + The following parameters are used by default, but can be overridden in `StateMachine.init()`: - *in_shiftdir* is the default direction the ISR will shift, either From 300fc842cec1d1ef71df95c917374808ae2cafe9 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 May 2021 11:18:16 +1000 Subject: [PATCH 101/349] py/mkenv.mk: Don't emit info about BUILD_VERBOSE if it's set. If the user sets V or BUILD_VERBOSE then they don't need to see this message. Signed-off-by: Damien George --- py/mkenv.mk | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/py/mkenv.mk b/py/mkenv.mk index 371d320462..d54f0a0d31 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -20,6 +20,7 @@ ifeq ("$(origin V)", "command line") BUILD_VERBOSE=$(V) endif ifndef BUILD_VERBOSE +$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) BUILD_VERBOSE = 0 endif ifeq ($(BUILD_VERBOSE),0) @@ -27,10 +28,6 @@ Q = @ else Q = endif -# Since this is a new feature, advertise it -ifeq ($(BUILD_VERBOSE),0) -$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) -endif # default settings; can be overridden in main Makefile From ee4ffc1804cc39c80128185e7ea96365fa381d7e Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Apr 2021 16:52:01 +1000 Subject: [PATCH 102/349] stm32/powerctrl: Add MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET option. When disabled the bootloader is entered via a direct jump. When enabled the bootloader is entered via a system reset then a jump. It's enabled by default to retain the existing behaviour, which is the recommended way. Signed-off-by: Damien George --- ports/stm32/mpconfigboard_common.h | 5 +++++ ports/stm32/powerctrl.c | 36 ++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 0df35918be..ce9dbdb0af 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -47,6 +47,11 @@ #define MICROPY_PY_PYB_LEGACY (1) #endif +// Whether machine.bootloader() will enter the bootloader via reset, or direct jump. +#ifndef MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (1) +#endif + // Whether to enable storage on the internal flash of the MCU #ifndef MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE #define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index 573844063b..253f1056ca 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -66,9 +66,11 @@ #define HAVE_PLL48 0 #endif +#if MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET // Location in RAM of bootloader state (just after the top of the stack) extern uint32_t _estack[]; #define BL_STATE ((uint32_t *)&_estack) +#endif static inline void powerctrl_disable_hsi_if_unused(void) { #if !MICROPY_HW_CLK_USE_HSI && (defined(STM32F4) || defined(STM32F7) || defined(STM32H7)) @@ -78,32 +80,47 @@ static inline void powerctrl_disable_hsi_if_unused(void) { } NORETURN void powerctrl_mcu_reset(void) { + #if MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET BL_STATE[1] = 1; // invalidate bootloader address #if __DCACHE_PRESENT == 1 SCB_CleanDCache(); #endif - NVIC_SystemReset(); -} - -NORETURN void powerctrl_enter_bootloader(uint32_t r0, uint32_t bl_addr) { - BL_STATE[0] = r0; - BL_STATE[1] = bl_addr; - #if __DCACHE_PRESENT == 1 - SCB_CleanDCache(); #endif NVIC_SystemReset(); } -static __attribute__((naked)) void branch_to_bootloader(uint32_t r0, uint32_t bl_addr) { +NORETURN static __attribute__((naked)) void branch_to_bootloader(uint32_t r0, uint32_t bl_addr) { __asm volatile ( "ldr r2, [r1, #0]\n" // get address of stack pointer "msr msp, r2\n" // get stack pointer "ldr r2, [r1, #4]\n" // get address of destination "bx r2\n" // branch to bootloader ); + MP_UNREACHABLE; +} + +NORETURN void powerctrl_enter_bootloader(uint32_t r0, uint32_t bl_addr) { + #if MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET + + // Enter the bootloader via a reset, so everything is reset (including WDT). + // Upon reset powerctrl_check_enter_bootloader() will jump to the bootloader. + BL_STATE[0] = r0; + BL_STATE[1] = bl_addr; + #if __DCACHE_PRESENT == 1 + SCB_CleanDCache(); + #endif + NVIC_SystemReset(); + + #else + + // Enter the bootloader via a direct jump. + branch_to_bootloader(r0, bl_addr); + + #endif } void powerctrl_check_enter_bootloader(void) { + #if MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET uint32_t bl_addr = BL_STATE[1]; BL_STATE[1] = 1; // invalidate bootloader address if ((bl_addr & 0xfff) == 0 && (RCC->RCC_SR & RCC_SR_SFTRSTF)) { @@ -115,6 +132,7 @@ void powerctrl_check_enter_bootloader(void) { uint32_t r0 = BL_STATE[0]; branch_to_bootloader(r0, bl_addr); } + #endif } #if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32WB) From 9ee116c452e6569d70cdebaade5dd25a1555b82b Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 May 2021 10:49:43 +1000 Subject: [PATCH 103/349] stm32/boardctrl: Adjust logic for running boot.py, main.py. This new logic is equivalent to the old logic when the only possibilities for reset_mode are NORMAL, SAFE_MODE and FILESYSTEM, which is the standard case. But the new logic also allows other reset_mode values (eg BOOTLOADER) to run boot.py and main.py. Signed-off-by: Damien George --- ports/stm32/boardctrl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ports/stm32/boardctrl.c b/ports/stm32/boardctrl.c index 8cc519d8e9..f1b7a4e81c 100644 --- a/ports/stm32/boardctrl.c +++ b/ports/stm32/boardctrl.c @@ -143,8 +143,7 @@ void boardctrl_top_soft_reset_loop(boardctrl_state_t *state) { } int boardctrl_run_boot_py(boardctrl_state_t *state) { - bool run_boot_py = state->reset_mode == BOARDCTRL_RESET_MODE_NORMAL - || state->reset_mode == BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM; + bool run_boot_py = state->reset_mode != BOARDCTRL_RESET_MODE_SAFE_MODE; if (run_boot_py) { // Run boot.py, if it exists. @@ -176,8 +175,7 @@ int boardctrl_run_boot_py(boardctrl_state_t *state) { } int boardctrl_run_main_py(boardctrl_state_t *state) { - bool run_main_py = (state->reset_mode == BOARDCTRL_RESET_MODE_NORMAL - || state->reset_mode == BOARDCTRL_RESET_MODE_FACTORY_FILESYSTEM) + bool run_main_py = state->reset_mode != BOARDCTRL_RESET_MODE_SAFE_MODE && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL; if (run_main_py) { From 6639e282c762b1f878c2c66a1e0153ee8cb61e1a Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 May 2021 13:29:01 +1000 Subject: [PATCH 104/349] stm32/mboot: Add MBOOT_LEAVE_BOOTLOADER_VIA_RESET option. It is enabled by default to get the standard behaviour of doing a reset after it is finished, but can be disabled by a board to jump straight to the application (likely the board needs to use MBOOT_BOARD_CLEANUP to make this work). The application is passed a reset mode of BOARDCTRL_RESET_MODE_BOOTLOADER if the bootloader was active and entered via a jump. Signed-off-by: Damien George --- ports/stm32/mboot/main.c | 64 ++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 36b6890361..2bee5a666f 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -40,6 +40,11 @@ #include "dfu.h" #include "pack.h" +// Whether the bootloader will leave via reset, or direct jump to the application. +#ifndef MBOOT_LEAVE_BOOTLOADER_VIA_RESET +#define MBOOT_LEAVE_BOOTLOADER_VIA_RESET (1) +#endif + // This option selects whether to use explicit polling or IRQs for USB events. // In some test cases polling mode can run slightly faster, but it uses more power. // Polling mode will also cause failures with the mass-erase command because USB @@ -1329,6 +1334,45 @@ static int get_reset_mode(void) { return reset_mode; } +NORETURN static __attribute__((naked)) void branch_to_application(uint32_t r0, uint32_t bl_addr) { + __asm volatile ( + "ldr r2, [r1, #0]\n" // get address of stack pointer + "msr msp, r2\n" // set stack pointer + "ldr r2, [r1, #4]\n" // get address of destination + "bx r2\n" // branch to application + ); + MP_UNREACHABLE; +} + +static void try_enter_application(int reset_mode) { + uint32_t msp = *(volatile uint32_t*)APPLICATION_ADDR; + if ((msp & APP_VALIDITY_BITS) != 0) { + // Application is invalid. + return; + } + + // undo our DFU settings + // TODO probably should disable all IRQ sources first + #if defined(MBOOT_BOARD_CLEANUP) + MBOOT_BOARD_CLEANUP(reset_mode); + #endif + #if USE_CACHE && defined(STM32F7) + SCB_DisableICache(); + SCB_DisableDCache(); + #endif + + // Jump to the application. + branch_to_application(reset_mode, APPLICATION_ADDR); +} + +static void leave_bootloader(void) { + #if !MBOOT_LEAVE_BOOTLOADER_VIA_RESET + // Try to enter the application via a jump, if it's valid. + try_enter_application(BOARDCTRL_RESET_MODE_BOOTLOADER); + #endif + NVIC_SystemReset(); +} + static void do_reset(void) { led_state_all(0); mp_hal_delay_ms(50); @@ -1337,7 +1381,7 @@ static void do_reset(void) { i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn); #endif mp_hal_delay_ms(50); - NVIC_SystemReset(); + leave_bootloader(); } extern PCD_HandleTypeDef pcd_fs_handle; @@ -1402,17 +1446,11 @@ void stm32_main(int initial_r0) { } int reset_mode = get_reset_mode(); - uint32_t msp = *(volatile uint32_t*)APPLICATION_ADDR; - if (reset_mode != BOARDCTRL_RESET_MODE_BOOTLOADER && (msp & APP_VALIDITY_BITS) == 0) { - // not DFU mode so jump to application, passing through reset_mode - // undo our DFU settings - // TODO probably should disable all IRQ sources first - #if USE_CACHE && defined(STM32F7) - SCB_DisableICache(); - SCB_DisableDCache(); - #endif - __set_MSP(msp); - ((void (*)(uint32_t)) *((volatile uint32_t*)(APPLICATION_ADDR + 4)))(reset_mode); + if (reset_mode != BOARDCTRL_RESET_MODE_BOOTLOADER) { + // Bootloader mode was not selected so try to enter the application, + // passing through the reset_mode. This will return if the application + // is invalid. + try_enter_application(reset_mode); } enter_bootloader: @@ -1461,7 +1499,7 @@ enter_bootloader: } // Always reset because the application is expecting to resume led_state_all(0); - NVIC_SystemReset(); + leave_bootloader(); } #endif From 9a0bca2c2a6aef7b032d9c5bde378058c8258a08 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 May 2021 13:33:56 +1000 Subject: [PATCH 105/349] stm32/mboot: Make LEDs and reset-mode selection more configurable. A board can now customise mboot with: - MBOOT_LED1, MBOOT_LED2, MBOOT_LED3, MBOOT_LED4: if it needs to have different LEDs for mboot compared to the application - MBOOT_BOARD_LED_INIT: if it needs a fully customised LED init function - MBOOT_BOARD_LED_STATE: if it needs a fully customised LED state-setting function - MBOOT_BOARD_GET_RESET_MODE: if it needs a fully customised function to get the reset mode With full customisation, the only requirement is a single LED to show the status of the bootloader (idle, erasing, flashing, etc), which can be configured to do nothing if needed. Signed-off-by: Damien George --- ports/stm32/mboot/main.c | 71 ++++++++++++++++++++++++++++++--------- ports/stm32/mboot/mboot.h | 2 ++ 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 2bee5a666f..3a0242a8d6 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -374,12 +374,27 @@ void mp_hal_pin_config_speed(uint32_t port_pin, uint32_t speed) { /******************************************************************************/ // LED +#if defined(MBOOT_LED1) +#define LED0 MBOOT_LED1 +#elif defined(MICROPY_HW_LED1) #define LED0 MICROPY_HW_LED1 +#endif + +#if defined(MBOOT_LED2) +#define LED1 MBOOT_LED2 +#elif defined(MICROPY_HW_LED2) #define LED1 MICROPY_HW_LED2 -#ifdef MICROPY_HW_LED3 +#endif + +#if defined(MBOOT_LED3) +#define LED2 MBOOT_LED3 +#elif defined(MICROPY_HW_LED3) #define LED2 MICROPY_HW_LED3 #endif -#ifdef MICROPY_HW_LED4 + +#if defined(MBOOT_LED4) +#define LED3 MBOOT_LED4 +#elif defined(MICROPY_HW_LED4) #define LED3 MICROPY_HW_LED4 #endif @@ -397,28 +412,45 @@ static uint32_t led0_ms_interval = 0; static int led0_toggle_count = 0; MP_WEAK void led_init(void) { + #if defined(MBOOT_BOARD_LED_INIT) + // Custom LED init function provided by the board. + MBOOT_BOARD_LED_INIT(); + #else + // Init LEDs using GPIO calls. mp_hal_pin_output(LED0); + #ifdef LED1 mp_hal_pin_output(LED1); + #endif #ifdef LED2 mp_hal_pin_output(LED2); #endif #ifdef LED3 mp_hal_pin_output(LED3); #endif + #endif + led0_cur_state = LED0_STATE_OFF; } MP_WEAK void led_state(uint32_t led, int val) { + #if defined(MBOOT_BOARD_LED_STATE) + // Custom LED state function provided by the board. + return MBOOT_BOARD_LED_STATE(led, val); + #else + // Set LEDs using GPIO calls. if (val) { MICROPY_HW_LED_ON(led); } else { MICROPY_HW_LED_OFF(led); } + #endif } void led_state_all(unsigned int mask) { led_state(LED0, mask & 1); + #ifdef LED1 led_state(LED1, mask & 2); + #endif #ifdef LED2 led_state(LED2, mask & 4); #endif @@ -445,17 +477,6 @@ void led0_update() { } } -/******************************************************************************/ -// USR BUTTON - -static void usrbtn_init(void) { - mp_hal_pin_config(MICROPY_HW_USRSW_PIN, MP_HAL_PIN_MODE_INPUT, MICROPY_HW_USRSW_PULL, 0); -} - -static int usrbtn_state(void) { - return mp_hal_pin_read(MICROPY_HW_USRSW_PIN) == MICROPY_HW_USRSW_PRESSED; -} - /******************************************************************************/ // FLASH @@ -1287,6 +1308,14 @@ static int pyb_usbdd_shutdown(void) { /******************************************************************************/ // main +#if defined(MBOOT_BOARD_GET_RESET_MODE) + +static inline int mboot_get_reset_mode(void) { + return MBOOT_BOARD_GET_RESET_MODE(); +} + +#else + #define RESET_MODE_NUM_STATES (4) #define RESET_MODE_TIMEOUT_CYCLES (8) #ifdef LED2 @@ -1299,7 +1328,15 @@ static int pyb_usbdd_shutdown(void) { #define RESET_MODE_LED_STATES 0x3210 #endif -static int get_reset_mode(void) { +static void usrbtn_init(void) { + mp_hal_pin_config(MICROPY_HW_USRSW_PIN, MP_HAL_PIN_MODE_INPUT, MICROPY_HW_USRSW_PULL, 0); +} + +static int usrbtn_state(void) { + return mp_hal_pin_read(MICROPY_HW_USRSW_PIN) == MICROPY_HW_USRSW_PRESSED; +} + +static int mboot_get_reset_mode(void) { usrbtn_init(); int reset_mode = BOARDCTRL_RESET_MODE_NORMAL; if (usrbtn_state()) { @@ -1334,6 +1371,8 @@ static int get_reset_mode(void) { return reset_mode; } +#endif + NORETURN static __attribute__((naked)) void branch_to_application(uint32_t r0, uint32_t bl_addr) { __asm volatile ( "ldr r2, [r1, #0]\n" // get address of stack pointer @@ -1445,7 +1484,7 @@ void stm32_main(int initial_r0) { goto enter_bootloader; } - int reset_mode = get_reset_mode(); + int reset_mode = mboot_get_reset_mode(); if (reset_mode != BOARDCTRL_RESET_MODE_BOOTLOADER) { // Bootloader mode was not selected so try to enter the application, // passing through the reset_mode. This will return if the application @@ -1455,7 +1494,7 @@ void stm32_main(int initial_r0) { enter_bootloader: - // Init subsystems (get_reset_mode() may call these, calling them again is ok) + // Init subsystems (mboot_get_reset_mode() may call these, calling them again is ok) led_init(); // set the system clock to be HSE diff --git a/ports/stm32/mboot/mboot.h b/ports/stm32/mboot/mboot.h index 8f8a8afdd7..3a27ce08ef 100644 --- a/ports/stm32/mboot/mboot.h +++ b/ports/stm32/mboot/mboot.h @@ -85,6 +85,8 @@ enum { extern uint8_t _estack[ELEM_DATA_SIZE]; +void systick_init(void); + uint32_t get_le32(const uint8_t *b); void led_state_all(unsigned int mask); From 6affcb0104336e629390b2bfba997f3446f9ea58 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 13 May 2021 16:26:07 +1000 Subject: [PATCH 106/349] tests/run-multitests.py: Flush stdout for each line of trace output. Signed-off-by: Damien George --- tests/run-multitests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-multitests.py b/tests/run-multitests.py index 3163a48e63..66ca799675 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -243,6 +243,7 @@ def trace_instance_output(instance_idx, line): if cmd_args.trace_output: t_ms = round((time.time() - trace_t0) * 1000) print("{:6} i{} :".format(t_ms, instance_idx), line) + sys.stdout.flush() def run_test_on_instances(test_file, num_instances, instances): From 57365d855734142deb030ebcd00c10efcedf554b Mon Sep 17 00:00:00 2001 From: stijn Date: Wed, 12 May 2021 17:02:06 +0200 Subject: [PATCH 107/349] py/objarray: Prohibit comparison of mismatching types. Array equality is defined as each element being equal but to keep code size down MicroPython implements a binary comparison. This can only be used correctly for elements with the same binary layout though so turn it into an NotImplementedError when comparing types for which the binary comparison yielded incorrect results: types with different sizes, and floating point numbers because nan != nan. --- py/objarray.c | 25 +++++++++++++++++++++++- tests/basics/array1.py | 9 +++++++++ tests/basics/array_micropython.py | 12 ++++++++++++ tests/cpydiff/module_array_comparison.py | 9 +++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/cpydiff/module_array_comparison.py diff --git a/py/objarray.c b/py/objarray.c index c27366d720..2f1f68d81a 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -258,6 +258,16 @@ STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { } } +STATIC int typecode_for_comparison(int typecode) { + if (typecode == BYTEARRAY_TYPECODE) { + typecode = 'B'; + } + if (typecode <= 'Z') { + typecode += 32; // to lowercase + } + return typecode; +} + STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_array_t *lhs = MP_OBJ_TO_PTR(lhs_in); switch (op) { @@ -319,7 +329,20 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs if (!mp_get_buffer(rhs_in, &rhs_bufinfo, MP_BUFFER_READ)) { return mp_const_false; } - return mp_obj_new_bool(mp_seq_cmp_bytes(op, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len)); + // mp_seq_cmp_bytes is used so only compatible representations can be correctly compared. + // The type doesn't matter: array/bytearray/str/bytes all have the same buffer layout, so + // just check if the typecodes are compatible; for testing equality the types should have the + // same code except for signedness, and not be floating point because nan never equals nan. + // Note that typecode_for_comparison always returns lowercase letters to save code size. + // No need for (& TYPECODE_MASK) here: xxx_get_buffer already takes care of that. + const int lhs_code = typecode_for_comparison(lhs_bufinfo.typecode); + const int rhs_code = typecode_for_comparison(rhs_bufinfo.typecode); + if (lhs_code == rhs_code && lhs_code != 'f' && lhs_code != 'd') { + return mp_obj_new_bool(mp_seq_cmp_bytes(op, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len)); + } + // mp_obj_equal_not_equal treats returning MP_OBJ_NULL as 'fall back to pointer comparison' + // for MP_BINARY_OP_EQUAL but that is incompatible with CPython. + mp_raise_NotImplementedError(NULL); } default: diff --git a/tests/basics/array1.py b/tests/basics/array1.py index 5b3f475786..15789e2c99 100644 --- a/tests/basics/array1.py +++ b/tests/basics/array1.py @@ -41,14 +41,23 @@ except ValueError: # equality (CPython requires both sides are array) print(bytes(array.array('b', [0x61, 0x62, 0x63])) == b'abc') print(array.array('b', [0x61, 0x62, 0x63]) == b'abc') +print(array.array('B', [0x61, 0x62, 0x63]) == b'abc') print(array.array('b', [0x61, 0x62, 0x63]) != b'abc') print(array.array('b', [0x61, 0x62, 0x63]) == b'xyz') print(array.array('b', [0x61, 0x62, 0x63]) != b'xyz') print(b'abc' == array.array('b', [0x61, 0x62, 0x63])) +print(b'abc' == array.array('B', [0x61, 0x62, 0x63])) print(b'abc' != array.array('b', [0x61, 0x62, 0x63])) print(b'xyz' == array.array('b', [0x61, 0x62, 0x63])) print(b'xyz' != array.array('b', [0x61, 0x62, 0x63])) +compatible_typecodes = [] +for t in ["b", "h", "i", "l", "q"]: + compatible_typecodes.append((t, t)) + compatible_typecodes.append((t, t.upper())) +for a, b in compatible_typecodes: + print(array.array(a, [1, 2]) == array.array(b, [1, 2])) + class X(array.array): pass diff --git a/tests/basics/array_micropython.py b/tests/basics/array_micropython.py index 6b3dc7a93b..44dc1d83d8 100644 --- a/tests/basics/array_micropython.py +++ b/tests/basics/array_micropython.py @@ -17,3 +17,15 @@ print(a[0]) a = array.array('P') a.append(1) print(a[0]) + +# comparison between mismatching binary layouts is not implemented +typecodes = ["b", "h", "i", "l", "q", "P", "O", "S", "f", "d"] +for a in typecodes: + for b in typecodes: + if a == b and a not in ["f", "d"]: + continue + try: + array.array(a) == array.array(b) + print('FAIL') + except NotImplementedError: + pass diff --git a/tests/cpydiff/module_array_comparison.py b/tests/cpydiff/module_array_comparison.py new file mode 100644 index 0000000000..a442af3f5b --- /dev/null +++ b/tests/cpydiff/module_array_comparison.py @@ -0,0 +1,9 @@ +""" +categories: Modules,array +description: Comparison between different typecodes not supported +cause: Code size +workaround: Compare individual elements +""" +import array + +array.array("b", [1, 2]) == array.array("i", [1, 2]) From 09be0c083cb493c70b38079aa6fd785aa9b0b90a Mon Sep 17 00:00:00 2001 From: stijn Date: Mon, 10 May 2021 16:40:51 +0200 Subject: [PATCH 108/349] py/objarray: Implement more/less comparisons for array. --- py/objarray.c | 17 ++++++++++++----- tests/basics/array1.py | 21 +++++++++++++++++++++ tests/basics/bytearray1.py | 20 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/py/objarray.c b/py/objarray.c index 2f1f68d81a..5bd9454716 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -258,12 +258,13 @@ STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { } } -STATIC int typecode_for_comparison(int typecode) { +STATIC int typecode_for_comparison(int typecode, bool *is_unsigned) { if (typecode == BYTEARRAY_TYPECODE) { typecode = 'B'; } if (typecode <= 'Z') { typecode += 32; // to lowercase + *is_unsigned = true; } return typecode; } @@ -322,7 +323,11 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs return mp_const_false; } - case MP_BINARY_OP_EQUAL: { + case MP_BINARY_OP_EQUAL: + case MP_BINARY_OP_LESS: + case MP_BINARY_OP_LESS_EQUAL: + case MP_BINARY_OP_MORE: + case MP_BINARY_OP_MORE_EQUAL: { mp_buffer_info_t lhs_bufinfo; mp_buffer_info_t rhs_bufinfo; array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ); @@ -333,11 +338,13 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs // The type doesn't matter: array/bytearray/str/bytes all have the same buffer layout, so // just check if the typecodes are compatible; for testing equality the types should have the // same code except for signedness, and not be floating point because nan never equals nan. + // For > and < the types should be the same and unsigned. // Note that typecode_for_comparison always returns lowercase letters to save code size. // No need for (& TYPECODE_MASK) here: xxx_get_buffer already takes care of that. - const int lhs_code = typecode_for_comparison(lhs_bufinfo.typecode); - const int rhs_code = typecode_for_comparison(rhs_bufinfo.typecode); - if (lhs_code == rhs_code && lhs_code != 'f' && lhs_code != 'd') { + bool is_unsigned = false; + const int lhs_code = typecode_for_comparison(lhs_bufinfo.typecode, &is_unsigned); + const int rhs_code = typecode_for_comparison(rhs_bufinfo.typecode, &is_unsigned); + if (lhs_code == rhs_code && lhs_code != 'f' && lhs_code != 'd' && (op == MP_BINARY_OP_EQUAL || is_unsigned)) { return mp_obj_new_bool(mp_seq_cmp_bytes(op, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len)); } // mp_obj_equal_not_equal treats returning MP_OBJ_NULL as 'fall back to pointer comparison' diff --git a/tests/basics/array1.py b/tests/basics/array1.py index 15789e2c99..f21ad4bd75 100644 --- a/tests/basics/array1.py +++ b/tests/basics/array1.py @@ -66,3 +66,24 @@ print(X('b', [0x61, 0x62, 0x63]) == b'abc') print(X('b', [0x61, 0x62, 0x63]) != b'abc') print(X('b', [0x61, 0x62, 0x63]) == array.array('b', [0x61, 0x62, 0x63])) print(X('b', [0x61, 0x62, 0x63]) != array.array('b', [0x61, 0x62, 0x63])) + +# other comparisons +for typecode in ["B", "H", "I", "L", "Q"]: + a = array.array(typecode, [1, 1]) + print(a < a) + print(a <= a) + print(a > a) + print(a >= a) + + al = array.array(typecode, [1, 0]) + ab = array.array(typecode, [1, 2]) + + print(a < al) + print(a <= al) + print(a > al) + print(a >= al) + + print(a < ab) + print(a <= ab) + print(a > ab) + print(a >= ab) diff --git a/tests/basics/bytearray1.py b/tests/basics/bytearray1.py index b598500264..d12292e879 100644 --- a/tests/basics/bytearray1.py +++ b/tests/basics/bytearray1.py @@ -27,6 +27,26 @@ print(bytearray([1]) == b"1") print(b"1" == bytearray([1])) print(bytearray() == bytearray()) +b1 = bytearray([1, 2, 3]) +b2 = bytearray([1, 2, 3]) +b3 = bytearray([1, 3]) +print(b1 == b2) +print(b2 != b3) +print(b1 <= b2) +print(b1 <= b3) +print(b1 < b3) +print(b1 >= b2) +print(b3 >= b2) +print(b3 > b2) +print(b1 != b2) +print(b2 == b3) +print(b1 > b2) +print(b1 > b3) +print(b1 >= b3) +print(b1 < b2) +print(b3 < b2) +print(b3 <= b2) + # comparison with other type should return False print(bytearray() == 1) From 43e7e5f00a601b36b5b39f1fef036d6c25d5562c Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 May 2021 12:54:03 +1000 Subject: [PATCH 109/349] lib/lwip: Switch to use GitHub mirror repo. It is hopefully more reliable. Signed-off-by: Damien George --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index ceaa5342b4..faa89c4f5c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,7 +7,7 @@ url = https://github.com/atgreen/libffi [submodule "lib/lwip"] path = lib/lwip - url = https://git.savannah.gnu.org/r/lwip.git + url = https://github.com/lwip-tcpip/lwip.git [submodule "lib/berkeley-db-1.xx"] path = lib/berkeley-db-1.xx url = https://github.com/pfalcon/berkeley-db-1.xx From 94a3f8a4b0b29e49b8f83c522b5478c94e4d3643 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 11 May 2021 08:24:36 -0500 Subject: [PATCH 110/349] tests/run-tests.py: Parallelize running tests by default. This significantly reduces the time taken to run the test suite (on the unix port). Use `-j1` to disable this feature. Signed-off-by: Jeff Epler --- tests/run-tests.py | 92 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/tests/run-tests.py b/tests/run-tests.py index a5a9b60637..619df5ed36 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -8,6 +8,10 @@ import argparse import inspect import re from glob import glob +import multiprocessing +from multiprocessing.pool import ThreadPool +import threading +import tempfile # See stackoverflow.com/questions/2632199: __file__ nor sys.argv[0] # are guaranteed to always work, this one should though. @@ -157,12 +161,14 @@ def run_micropython(pyb, args, test_file, is_special=False): # if running via .mpy, first compile the .py file if args.via_mpy: + mpy_modname = tempfile.mktemp(dir="") + mpy_filename = mpy_modname + ".mpy" subprocess.check_output( [MPYCROSS] + args.mpy_cross_flags.split() - + ["-o", "mpytest.mpy", "-X", "emit=" + args.emit, test_file] + + ["-o", mpy_filename, "-X", "emit=" + args.emit, test_file] ) - cmdlist.extend(["-m", "mpytest"]) + cmdlist.extend(["-m", mpy_modname]) else: cmdlist.append(test_file) @@ -175,7 +181,7 @@ def run_micropython(pyb, args, test_file, is_special=False): # clean up if we had an intermediate .mpy file if args.via_mpy: - rm_f("mpytest.mpy") + rm_f(mpy_filename) else: # run on pyboard @@ -247,12 +253,32 @@ def run_feature_check(pyb, args, base_path, test_file): return run_micropython(pyb, args, base_path("feature_check", test_file), is_special=True) -def run_tests(pyb, tests, args, result_dir): - test_count = 0 - testcase_count = 0 - passed_count = 0 - failed_tests = [] - skipped_tests = [] +class ThreadSafeCounter: + def __init__(self, start=0): + self._value = start + self._lock = threading.Lock() + + def increment(self): + self.add(1) + + def add(self, to_add): + with self._lock: + self._value += to_add + + def append(self, arg): + self.add([arg]) + + @property + def value(self): + return self._value + + +def run_tests(pyb, tests, args, result_dir, num_threads=1): + test_count = ThreadSafeCounter() + testcase_count = ThreadSafeCounter() + passed_count = ThreadSafeCounter() + failed_tests = ThreadSafeCounter([]) + skipped_tests = ThreadSafeCounter([]) skip_tests = set() skip_native = False @@ -490,7 +516,7 @@ def run_tests(pyb, tests, args, result_dir): ) # native doesn't have proper traceback info skip_tests.add("micropython/schedule.py") # native code doesn't check pending events - for test_file in tests: + def run_one_test(test_file): test_file = test_file.replace("\\", "/") if args.filters: @@ -500,7 +526,7 @@ def run_tests(pyb, tests, args, result_dir): if pat.search(test_file): verdict = action if verdict == "exclude": - continue + return test_basename = test_file.replace("..", "_").replace("./", "").replace("/", "_") test_name = os.path.splitext(os.path.basename(test_file))[0] @@ -533,12 +559,12 @@ def run_tests(pyb, tests, args, result_dir): if args.list_tests: if not skip_it: print(test_file) - continue + return if skip_it: print("skip ", test_file) skipped_tests.append(test_name) - continue + return # get expected output test_file_expected = test_file + ".exp" @@ -560,7 +586,7 @@ def run_tests(pyb, tests, args, result_dir): output_expected = output_expected.replace(b"\r\n", b"\n") if args.write_exp: - continue + return # run MicroPython output_mupy = run_micropython(pyb, args, test_file) @@ -568,16 +594,16 @@ def run_tests(pyb, tests, args, result_dir): if output_mupy == b"SKIP\n": print("skip ", test_file) skipped_tests.append(test_name) - continue + return - testcase_count += len(output_expected.splitlines()) + testcase_count.add(len(output_expected.splitlines())) filename_expected = os.path.join(result_dir, test_basename + ".exp") filename_mupy = os.path.join(result_dir, test_basename + ".out") if output_expected == output_mupy: print("pass ", test_file) - passed_count += 1 + passed_count.increment() rm_f(filename_expected) rm_f(filename_mupy) else: @@ -588,16 +614,32 @@ def run_tests(pyb, tests, args, result_dir): print("FAIL ", test_file) failed_tests.append(test_name) - test_count += 1 + test_count.increment() + + if pyb or args.list_tests: + num_threads = 1 + + if num_threads > 1: + pool = ThreadPool(num_threads) + pool.map(run_one_test, tests) + else: + for test in tests: + run_one_test(test) if args.list_tests: return True - print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) - print("{} tests passed".format(passed_count)) + print( + "{} tests performed ({} individual testcases)".format( + test_count.value, testcase_count.value + ) + ) + print("{} tests passed".format(passed_count.value)) + skipped_tests = sorted(skipped_tests.value) if len(skipped_tests) > 0: print("{} tests skipped: {}".format(len(skipped_tests), " ".join(skipped_tests))) + failed_tests = sorted(failed_tests.value) if len(failed_tests) > 0: print("{} tests failed: {}".format(len(failed_tests), " ".join(failed_tests))) return False @@ -698,6 +740,14 @@ the last matching regex is used: cmd_parser.add_argument( "--keep-path", action="store_true", help="do not clear MICROPYPATH when running tests" ) + cmd_parser.add_argument( + "-j", + "--jobs", + default=multiprocessing.cpu_count(), + metavar="N", + type=int, + help="Number of tests to run simultaneously", + ) cmd_parser.add_argument("files", nargs="*", help="input test files") cmd_parser.add_argument( "--print-failures", @@ -800,7 +850,7 @@ the last matching regex is used: try: os.makedirs(args.result_dir, exist_ok=True) - res = run_tests(pyb, tests, args, args.result_dir) + res = run_tests(pyb, tests, args, args.result_dir, args.jobs) finally: if pyb: pyb.close() From 30cbcf881daeecbc100554879e8a92d71185d9f6 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:24:44 +1000 Subject: [PATCH 111/349] docs/esp32: Add APA106 to quickref. --- docs/esp32/quickref.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index a569ff0a4e..68938feedc 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -483,10 +483,10 @@ Be sure to put a 4.7k pull-up resistor on the data line. Note that the ``convert_temp()`` method must be called each time you want to sample the temperature. -NeoPixel driver ---------------- +NeoPixel and APA106 driver +-------------------------- -Use the ``neopixel`` module:: +Use the ``neopixel`` and ``apa106`` modules:: from machine import Pin from neopixel import NeoPixel @@ -497,6 +497,13 @@ Use the ``neopixel`` module:: np.write() # write data to all pixels r, g, b = np[0] # get first pixel colour + +The APA106 driver extends NeoPixel, but internally uses a different colour order:: + + from apa106 import APA106 + ap = APA106(pin, 8) + r, g, b = ap[0] + For low-level driving of a NeoPixel:: import esp @@ -508,6 +515,7 @@ For low-level driving of a NeoPixel:: 400kHz) devices by passing ``timing=0`` when constructing the ``NeoPixel`` object. +APA102 (DotStar) uses a different driver as it has an additional clock pin. Capacitive touch ---------------- From 85c51a548fc83d0776029b01b1be3748f82e296a Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 15:57:20 +1000 Subject: [PATCH 112/349] docs/esp32: Mention Signal in GPIO section of quickref. --- docs/esp32/quickref.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 68938feedc..1709891265 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -171,6 +171,10 @@ Notes: * The pull value of some pins can be set to ``Pin.PULL_HOLD`` to reduce power consumption during deepsleep. +There's a higher-level abstraction :ref:`machine.Signal ` +which can be used to invert a pin. Useful for illuminating active-low LEDs +using ``on()`` or ``value(1)``. + UART (serial bus) ----------------- From d43ed087aee3444a96da059dfdb532c810f7656c Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 15:54:28 +1000 Subject: [PATCH 113/349] docs/esp8266: Mention Signal in GPIO section of quickref. --- docs/esp8266/quickref.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index af2ef1ca1a..c4fa779c21 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -138,6 +138,10 @@ Also note that Pin(16) is a special pin (used for wakeup from deepsleep mode) and may be not available for use with higher-level classes like ``Neopixel``. +There's a higher-level abstraction :ref:`machine.Signal ` +which can be used to invert a pin. Useful for illuminating active-low LEDs +using ``on()`` or ``value(1)``. + UART (serial bus) ----------------- From 97fee47716627b06bfb11dbcc43f6a000d6e7257 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 30 Apr 2021 14:00:13 +1000 Subject: [PATCH 114/349] docs/esp8266: Add SSD1306 to quickref and tutorial. --- docs/esp8266/quickref.rst | 14 +++++ docs/esp8266/tutorial/index.rst | 1 + docs/esp8266/tutorial/ssd1306.rst | 93 +++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 docs/esp8266/tutorial/ssd1306.rst diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index c4fa779c21..bc648a348a 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -424,6 +424,20 @@ The DHT driver is implemented in software and works on all pins:: d.temperature() # eg. 23.6 (°C) d.humidity() # eg. 41.3 (% RH) +SSD1306 driver +-------------- + +Driver for SSD1306 monochrome OLED displays. See tutorial :ref:`ssd1306`. :: + + from machine import Pin, I2C + import ssd1306 + + i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) + display = ssd1306.SSD1306_I2C(128, 64, i2c) + + display.text('Hello World', 0, 0, 1) + display.show() + WebREPL (web browser interactive prompt) ---------------------------------------- diff --git a/docs/esp8266/tutorial/index.rst b/docs/esp8266/tutorial/index.rst index 4ba211a4b2..79ebd92279 100644 --- a/docs/esp8266/tutorial/index.rst +++ b/docs/esp8266/tutorial/index.rst @@ -31,4 +31,5 @@ to ``__. neopixel.rst apa102.rst dht.rst + ssd1306.rst nextsteps.rst diff --git a/docs/esp8266/tutorial/ssd1306.rst b/docs/esp8266/tutorial/ssd1306.rst new file mode 100644 index 0000000000..4dca82afc4 --- /dev/null +++ b/docs/esp8266/tutorial/ssd1306.rst @@ -0,0 +1,93 @@ +.. _ssd1306: + +Using a SSD1306 OLED display +============================ + +The SSD1306 OLED display uses either a SPI or I2C interface and comes in a variety of +sizes (128x64, 128x32, 72x40, 64x48) and colours (white, yellow, blue, yellow + blue). + +Hardware SPI interface:: + + from machine import Pin, SPI + import ssd1306 + + hspi = SPI(1) # sck=14 (scl), mosi=13 (sda), miso=12 (unused) + + dc = Pin(4) # data/command + rst = Pin(5) # reset + cs = Pin(15) # chip select, some modules do not have a pin for this + + display = ssd1306.SSD1306_SPI(128, 64, hspi, dc, rst, cs) + +Software SPI interface:: + + from machine import Pin, SoftSPI + import ssd1306 + + spi = SoftSPI(baudrate=500000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12)) + + dc = Pin(4) # data/command + rst = Pin(5) # reset + cs = Pin(15) # chip select, some modules do not have a pin for this + + display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs) + +I2C interface:: + + from machine import Pin, I2C + import ssd1306 + + # using default address 0x3C + i2c = I2C(sda=Pin(4), scl=Pin(5)) + display = ssd1306.SSD1306_I2C(128, 64, i2c) + +Print Hello World on the first line:: + + display.text('Hello, World!', 0, 0, 1) + display.show() + +Basic functions:: + + display.poweroff() # power off the display, pixels persist in memory + display.poweron() # power on the display, pixels redrawn + display.contrast(0) # dim + display.contrast(255) # bright + display.invert(1) # display inverted + display.invert(0) # display normal + display.rotate(True) # rotate 180 degrees + display.rotate(False) # rotate 0 degrees + display.show() # write the contents of the FrameBuffer to display memory + +Subclassing FrameBuffer provides support for graphics primitives:: + + display.fill(0) # fill entire screen with colour=0 + display.pixel(0, 10) # get pixel at x=0, y=10 + display.pixel(0, 10, 1) # set pixel at x=0, y=10 to colour=1 + display.hline(0, 8, 4, 1) # draw horizontal line x=0, y=8, width=4, colour=1 + display.vline(0, 8, 4, 1) # draw vertical line x=0, y=8, height=4, colour=1 + display.line(0, 0, 127, 63, 1) # draw a line from 0,0 to 127,63 + display.rect(10, 10, 107, 43, 1) # draw a rectangle outline 10,10 to 107,43, colour=1 + display.fill_rect(10, 10, 107, 43, 1) # draw a solid rectangle 10,10 to 107,43, colour=1 + display.text('Hello World', 0, 0, 1) # draw some text at x=0, y=0, colour=1 + display.scroll(20, 0) # scroll 20 pixels to the right + + # draw another FrameBuffer on top of the current one at the given coordinates + import framebuf + fbuf = framebuf.FrameBuffer(bytearray(8 * 8 * 1), 8, 8, framebuf.MONO_VLSB) + fbuf.line(0, 0, 7, 7, 1) + display.blit(fbuf, 10, 10, 0) # draw on top at x=10, y=10, key=0 + display.show() + +Draw the MicroPython logo and print some text:: + + display.fill(0) + display.fill_rect(0, 0, 32, 32, 1) + display.fill_rect(2, 2, 28, 28, 0) + display.vline(9, 8, 22, 1) + display.vline(16, 2, 22, 1) + display.vline(23, 8, 22, 1) + display.fill_rect(26, 24, 2, 4, 1) + display.text('MicroPython', 40, 0, 1) + display.text('SSD1306', 40, 12, 1) + display.text('OLED 128x64', 40, 24, 1) + display.show() From 538b9a9be5e914eae302d31d8ddedec0f049482a Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 14 May 2021 13:23:44 +1000 Subject: [PATCH 115/349] esp32/machine_i2c: Allow boards to configure I2C pins using new macros. Following how SPI is configured (and how stm32 does it). --- ports/esp32/machine_i2c.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/ports/esp32/machine_i2c.c b/ports/esp32/machine_i2c.c index fd5180b8d0..d9003f45b5 100644 --- a/ports/esp32/machine_i2c.c +++ b/ports/esp32/machine_i2c.c @@ -32,14 +32,19 @@ #include "driver/i2c.h" -#define I2C_0_DEFAULT_SCL (GPIO_NUM_18) -#define I2C_0_DEFAULT_SDA (GPIO_NUM_19) +#ifndef MICROPY_HW_I2C0_SCL +#define MICROPY_HW_I2C0_SCL (GPIO_NUM_18) +#define MICROPY_HW_I2C0_SDA (GPIO_NUM_19) +#endif + +#ifndef MICROPY_HW_I2C1_SCL #if CONFIG_IDF_TARGET_ESP32 -#define I2C_1_DEFAULT_SCL (GPIO_NUM_25) -#define I2C_1_DEFAULT_SDA (GPIO_NUM_26) +#define MICROPY_HW_I2C1_SCL (GPIO_NUM_25) +#define MICROPY_HW_I2C1_SDA (GPIO_NUM_26) #else -#define I2C_1_DEFAULT_SCL (GPIO_NUM_9) -#define I2C_1_DEFAULT_SDA (GPIO_NUM_8) +#define MICROPY_HW_I2C1_SCL (GPIO_NUM_9) +#define MICROPY_HW_I2C1_SDA (GPIO_NUM_8) +#endif #endif #define I2C_DEFAULT_TIMEOUT_US (10000) // 10ms @@ -149,11 +154,11 @@ mp_obj_t machine_hw_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_ self->base.type = &machine_hw_i2c_type; self->port = i2c_id; if (self->port == I2C_NUM_0) { - self->scl = I2C_0_DEFAULT_SCL; - self->sda = I2C_0_DEFAULT_SDA; + self->scl = MICROPY_HW_I2C0_SCL; + self->sda = MICROPY_HW_I2C0_SDA; } else { - self->scl = I2C_1_DEFAULT_SCL; - self->sda = I2C_1_DEFAULT_SDA; + self->scl = MICROPY_HW_I2C1_SCL; + self->sda = MICROPY_HW_I2C1_SDA; } first_init = true; } From 9e65662a11c37599299ba4ab9c3ddf0510306498 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 14 May 2021 14:00:01 +1000 Subject: [PATCH 116/349] esp32/boards: Set default I2C and SPI pins on UM_xxx boards. And fix incorrect I2C and SPI pins in the feathers2 module. --- ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py | 8 ++++---- ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h | 9 ++++++++- ports/esp32/boards/UM_TINYPICO/mpconfigboard.h | 3 +++ ports/esp32/boards/UM_TINYS2/mpconfigboard.h | 3 +++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py index 32126fc9c9..93c50a1810 100644 --- a/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py +++ b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py @@ -22,12 +22,12 @@ DOTSTAR_DATA = const(40) # SPI SPI_MOSI = const(35) -SPI_MISO = const(36) -SPI_CLK = const(37) +SPI_MISO = const(37) +SPI_CLK = const(36) # I2C -I2C_SDA = const(38) -I2C_SCL = const(33) +I2C_SDA = const(8) +I2C_SCL = const(9) # DAC DAC1 = const(17) diff --git a/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h index c045adccd9..8d0c9f78c8 100644 --- a/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h +++ b/ports/esp32/boards/UM_FEATHERS2/mpconfigboard.h @@ -2,4 +2,11 @@ #define MICROPY_HW_MCU_NAME "ESP32-S2" #define MICROPY_PY_BLUETOOTH (0) -#define MICROPY_HW_ENABLE_SDCARD (0) \ No newline at end of file +#define MICROPY_HW_ENABLE_SDCARD (0) + +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + +#define MICROPY_HW_SPI1_MOSI (35) // SDO +#define MICROPY_HW_SPI1_MISO (37) // SDI +#define MICROPY_HW_SPI1_SCK (36) diff --git a/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h index 05ee5eaf72..6bf70cc13b 100644 --- a/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h +++ b/ports/esp32/boards/UM_TINYPICO/mpconfigboard.h @@ -1,6 +1,9 @@ #define MICROPY_HW_BOARD_NAME "TinyPICO" #define MICROPY_HW_MCU_NAME "ESP32-PICO-D4" +#define MICROPY_HW_I2C0_SCL (22) +#define MICROPY_HW_I2C0_SDA (21) + #define MICROPY_HW_SPI1_SCK (18) #define MICROPY_HW_SPI1_MOSI (23) #define MICROPY_HW_SPI1_MISO (19) diff --git a/ports/esp32/boards/UM_TINYS2/mpconfigboard.h b/ports/esp32/boards/UM_TINYS2/mpconfigboard.h index 87d266e58c..1052f6d79c 100644 --- a/ports/esp32/boards/UM_TINYS2/mpconfigboard.h +++ b/ports/esp32/boards/UM_TINYS2/mpconfigboard.h @@ -4,6 +4,9 @@ #define MICROPY_PY_BLUETOOTH (0) #define MICROPY_HW_ENABLE_SDCARD (0) +#define MICROPY_HW_I2C0_SCL (9) +#define MICROPY_HW_I2C0_SDA (8) + #define MICROPY_HW_SPI1_MOSI (35) #define MICROPY_HW_SPI1_MISO (36) #define MICROPY_HW_SPI1_SCK (37) From 605b74f390e1ce9acdbca32d0b3215d37b96852e Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Fri, 14 May 2021 15:36:59 +1000 Subject: [PATCH 117/349] esp32/boards: Fix spelling mistakes in comments for UM_xxx boards. --- ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py | 4 ++-- ports/esp32/boards/UM_TINYPICO/modules/tinypico.py | 2 +- ports/esp32/boards/UM_TINYS2/modules/tinys2.py | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py index 93c50a1810..95e1f52681 100644 --- a/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py +++ b/ports/esp32/boards/UM_FEATHERS2/modules/feathers2.py @@ -50,7 +50,7 @@ def toggle_led(state): l.value(not l.value()) -# Create ADC and set attenuation and return teh ambient light value from the onboard sensor +# Create ADC and set attenuation and return the ambient light value from the onboard sensor def get_amb_light(): adc = ADC(Pin(AMB_LIGHT)) adc.atten(ADC.ATTN_11DB) @@ -62,7 +62,7 @@ def get_amb_light(): # prevent parasitic power from lighting the LED even with the LDO off, causing current use. # The DotStar is a beautiful LED, but parasitic power makes it a terrible choice for battery use :( def set_ldo2_power(state): - """Set the power for the on-board Dostar to allow no current draw when not needed.""" + """Set the power for the on-board Dotstar to allow no current draw when not needed.""" # Set the power pin to the inverse of state ldo2 = Pin(LDO2, Pin.OUT) ldo2.value(state) diff --git a/ports/esp32/boards/UM_TINYPICO/modules/tinypico.py b/ports/esp32/boards/UM_TINYPICO/modules/tinypico.py index 846e07960a..04b274bb53 100644 --- a/ports/esp32/boards/UM_TINYPICO/modules/tinypico.py +++ b/ports/esp32/boards/UM_TINYPICO/modules/tinypico.py @@ -80,7 +80,7 @@ def get_battery_charging(): # need to be able to cut power to it to minimise power consumption during deep sleep or with general battery powered use # to minimise unneeded battery drain def set_dotstar_power(state): - """Set the power for the on-board Dostar to allow no current draw when not needed.""" + """Set the power for the on-board Dotstar to allow no current draw when not needed.""" # Set the power pin to the inverse of state if state: Pin(DOTSTAR_PWR, Pin.OUT, None) # Break the PULL_HOLD on the pin diff --git a/ports/esp32/boards/UM_TINYS2/modules/tinys2.py b/ports/esp32/boards/UM_TINYS2/modules/tinys2.py index ca59cb1235..0a3eaf14d4 100644 --- a/ports/esp32/boards/UM_TINYS2/modules/tinys2.py +++ b/ports/esp32/boards/UM_TINYS2/modules/tinys2.py @@ -38,7 +38,7 @@ DAC2 = const(18) # Helper functions def set_pixel_power(state): - """Enable or Disable power to the onboard NeoPixel to either show colour, or to reduce power fro deep sleep.""" + """Enable or Disable power to the onboard NeoPixel to either show colour, or to reduce power for deep sleep.""" Pin(RGB_PWR, Pin.OUT).value(state) @@ -59,7 +59,7 @@ def get_vbus_present(): return Pin(VBUS_SENSE, Pin.IN).value() == 1 -# Dotstar rainbow colour wheel +# NeoPixel rainbow colour wheel def rgb_color_wheel(wheel_pos): """Color wheel to allow for cycling through the rainbow of RGB colors.""" wheel_pos = wheel_pos % 255 @@ -74,9 +74,9 @@ def rgb_color_wheel(wheel_pos): return wheel_pos * 3, 255 - wheel_pos * 3, 0 -# Go into deep sleep but shut down the APA first to save power -# Use this if you want lowest deep sleep current +# Go into deep sleep but shut down the RGB LED first to save power +# Use this if you want lowest deep sleep current def go_deepsleep(t): - """Deep sleep helper that also powers down the on-board Dotstar.""" + """Deep sleep helper that also powers down the on-board NeoPixel.""" set_pixel_power(False) machine.deepsleep(t) From 47e6c52f0c2bf058c5d099dd2993192e0978e172 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 May 2021 22:05:03 +1000 Subject: [PATCH 118/349] tests/cpydiff: Add test and workaround for function.__module__ attr. MicroPython does not store any reference from a function object to the module it was defined in, but there is a way to use function.__globals__ to indirectly get the module. See issue #7259. Signed-off-by: Damien George --- tests/cpydiff/core_function_moduleattr.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/cpydiff/core_function_moduleattr.py diff --git a/tests/cpydiff/core_function_moduleattr.py b/tests/cpydiff/core_function_moduleattr.py new file mode 100644 index 0000000000..71747c1f40 --- /dev/null +++ b/tests/cpydiff/core_function_moduleattr.py @@ -0,0 +1,13 @@ +""" +categories: Core,Functions +description: Function objects do not have the ``__module__`` attribute +cause: MicroPython is optimized for reduced code size and RAM usage. +workaround: Use ``sys.modules[function.__globals__['__name__']]`` for non-builtin modules. +""" + + +def f(): + pass + + +print(f.__module__) From 1446107b4d24915143f8212c2f649a0e628735cc Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 00:22:53 +1000 Subject: [PATCH 119/349] py/objarray: Use mp_obj_memoryview_init helper in mp_obj_new_memoryview. Signed-off-by: Damien George --- py/objarray.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/py/objarray.c b/py/objarray.c index 5bd9454716..be85674f87 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -201,11 +201,7 @@ STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) { mp_obj_array_t *self = m_new_obj(mp_obj_array_t); - self->base.type = &mp_type_memoryview; - self->typecode = typecode; - self->memview_offset = 0; - self->len = nitems; - self->items = items; + mp_obj_memoryview_init(self, typecode, 0, nitems, items); return MP_OBJ_FROM_PTR(self); } From 6d2680fa36696fd0b2fd7a595f4a26153cd84e07 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 00:23:13 +1000 Subject: [PATCH 120/349] py/objarray: Fix constructing a memoryview from a memoryview. Fixes issue #7261. Signed-off-by: Damien George --- py/objarray.c | 8 ++++++++ tests/basics/memoryview_gc.py | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/py/objarray.c b/py/objarray.c index be85674f87..16a4d4aac7 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -220,6 +220,14 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL), bufinfo.buf)); + // If the input object is a memoryview then need to point the items of the + // new memoryview to the start of the buffer so the GC can trace it. + if (mp_obj_get_type(args[0]) == &mp_type_memoryview) { + mp_obj_array_t *other = MP_OBJ_TO_PTR(args[0]); + self->memview_offset = other->memview_offset; + self->items = other->items; + } + // test if the object can be written to if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) { self->typecode |= MP_OBJ_ARRAY_TYPECODE_FLAG_RW; // indicate writable buffer diff --git a/tests/basics/memoryview_gc.py b/tests/basics/memoryview_gc.py index d366cbbb15..5cd6124ada 100644 --- a/tests/basics/memoryview_gc.py +++ b/tests/basics/memoryview_gc.py @@ -21,3 +21,13 @@ for i in range(100000): # check that the memoryview is still what we want print(list(m)) + +# check that creating a memoryview of a memoryview retains the underlying data +m = None +gc.collect() # cleanup from previous test +m = memoryview(memoryview(bytearray(i for i in range(50)))[5:-5]) +print(sum(m), list(m[:10])) +gc.collect() +for i in range(10): + list(range(10)) # allocate memory to overwrite any reclaimed heap +print(sum(m), list(m[:10])) From 126b1c727118352923703719a2a3d45b9fad3c97 Mon Sep 17 00:00:00 2001 From: Bob Abeles Date: Fri, 14 May 2021 07:57:19 -0700 Subject: [PATCH 121/349] py/nlraarch64: Add underscore prefix to function symbols for Darwin ABI. The proper way to do this is to test for __APPLE__ and __MACH__, where __APPLE__ tests for an Apple OS and __MACH__ tests that it is based on CMU Mach. Using both tests ensures that just Darwin (Apple's open source base for MacOS, iOS, etc.) is recognized. __APPLE__ by itself will test for any Apple OS, which can include older OS 7-9 and any future Apple OS. __MACH__ tests for any OS based on CMU Mach, including Darwin and GNU Hurd. Fixes #7232. --- py/nlraarch64.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/py/nlraarch64.c b/py/nlraarch64.c index 2df0dc9c85..1295351cbe 100644 --- a/py/nlraarch64.c +++ b/py/nlraarch64.c @@ -34,8 +34,13 @@ // Implemented purely as inline assembly; inside a function, we have to deal with undoing the prologue, restoring // SP and LR. This way, we don't. __asm( + #if defined(__APPLE__) && defined(__MACH__) + "_nlr_push: \n" + ".global _nlr_push \n" + #else "nlr_push: \n" ".global nlr_push \n" + #endif "mov x9, sp \n" "stp lr, x9, [x0, #16]\n" // 16 == offsetof(nlr_buf_t, regs) "stp x19, x20, [x0, #32]\n" @@ -44,7 +49,11 @@ __asm( "stp x25, x26, [x0, #80]\n" "stp x27, x28, [x0, #96]\n" "str x29, [x0, #112]\n" + #if defined(__APPLE__) && defined(__MACH__) + "b _nlr_push_tail \n" // do the rest in C + #else "b nlr_push_tail \n" // do the rest in C + #endif ); NORETURN void nlr_jump(void *val) { From 7ceccad4e2f1e9d073f5781c32e5b377e8391a25 Mon Sep 17 00:00:00 2001 From: Bob Abeles Date: Fri, 14 May 2021 08:05:40 -0700 Subject: [PATCH 122/349] py/nlrx64: Correct the detection of Darwin ABI. __APPLE__ tests for an Apple OS and __MACH__ tests that it is based on CMU Mach. Using both tests ensures that just Darwin is recognized. --- py/nlrx64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py/nlrx64.c b/py/nlrx64.c index f5d02afbdb..6f006e755e 100644 --- a/py/nlrx64.c +++ b/py/nlrx64.c @@ -58,7 +58,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { #else __asm volatile ( - #if defined(__APPLE__) || defined(__MACH__) + #if defined(__APPLE__) && defined(__MACH__) "pop %rbp \n" // undo function's prelude #endif "movq (%rsp), %rax \n" // load return %rip @@ -70,7 +70,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { "movq %r13, 56(%rdi) \n" // store %r13 into nlr_buf "movq %r14, 64(%rdi) \n" // store %r14 into nlr_buf "movq %r15, 72(%rdi) \n" // store %r15 into nlr_buf - #if defined(__APPLE__) || defined(__MACH__) + #if defined(__APPLE__) && defined(__MACH__) "jmp _nlr_push_tail \n" // do the rest in C #else "jmp nlr_push_tail \n" // do the rest in C From 94fb5e7f5a409e9596657508c6a9ed1c609de267 Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Fri, 14 May 2021 08:35:43 -0300 Subject: [PATCH 123/349] nrf: Add machine.memXX, and allow boards to customise some features. --- ports/nrf/modules/machine/modmachine.c | 4 ++++ ports/nrf/mpconfigport.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/nrf/modules/machine/modmachine.c b/ports/nrf/modules/machine/modmachine.c index 3330349cd5..7e45b83df8 100644 --- a/ports/nrf/modules/machine/modmachine.c +++ b/ports/nrf/modules/machine/modmachine.c @@ -201,6 +201,10 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) }, + { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, + #if MICROPY_PY_MACHINE_UART { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_hard_uart_type) }, #endif diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index c246c53dd5..714b1cc24f 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -44,8 +44,6 @@ #endif #define MICROPY_ALLOC_PATH_MAX (512) #define MICROPY_PERSISTENT_CODE_LOAD (0) -#define MICROPY_EMIT_THUMB (0) -#define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_COMP_MODULE_CONST (0) #define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) #define MICROPY_READER_VFS (MICROPY_VFS) @@ -123,7 +121,6 @@ #define MICROPY_PY_CMATH (0) #define MICROPY_PY_IO (0) #define MICROPY_PY_IO_FILEIO (0) -#define MICROPY_PY_UERRNO (0) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_UCTYPES (0) @@ -131,7 +128,6 @@ #define MICROPY_PY_UJSON (0) #define MICROPY_PY_URE (0) #define MICROPY_PY_UHEAPQ (0) -#define MICROPY_PY_UHASHLIB (0) #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PULSE (0) From ea2d83e96175ef1ed260cca917024502e01a5546 Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Thu, 13 May 2021 18:18:04 -0300 Subject: [PATCH 124/349] nrf/boards: Add support for evk_nina_b3 board. --- ports/nrf/boards/evk_nina_b3/mpconfigboard.h | 85 +++++++++++++++++++ ports/nrf/boards/evk_nina_b3/mpconfigboard.mk | 7 ++ ports/nrf/boards/evk_nina_b3/pins.csv | 48 +++++++++++ 3 files changed, 140 insertions(+) create mode 100644 ports/nrf/boards/evk_nina_b3/mpconfigboard.h create mode 100644 ports/nrf/boards/evk_nina_b3/mpconfigboard.mk create mode 100644 ports/nrf/boards/evk_nina_b3/pins.csv diff --git a/ports/nrf/boards/evk_nina_b3/mpconfigboard.h b/ports/nrf/boards/evk_nina_b3/mpconfigboard.h new file mode 100644 index 0000000000..eaca796be4 --- /dev/null +++ b/ports/nrf/boards/evk_nina_b3/mpconfigboard.h @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +// Pin numbering scheme for nrf52840-based boards +// +// Software Pins 0-31 correspond to physical pins +// 0.x and software Pins 32-47 correspond to physical pins 1.x. +// +// Example: Pin(47) would be 1.15 on the PCA10059 + +// Board data +#define MICROPY_HW_BOARD_NAME "EVK_NINA_B3" +#define MICROPY_HW_MCU_NAME "NRF52840" +#define MICROPY_PY_SYS_PLATFORM "nrf52" + +// Enable @viper and @native +#define MICROPY_EMIT_THUMB (1) +#define MICROPY_EMIT_INLINE_THUMB (1) + +// Enable optional modules +#define MICROPY_PY_UERRNO (1) +#define MICROPY_PY_UHASHLIB (1) + +// Peripherals Config +#define MICROPY_PY_MACHINE_UART (1) +#define MICROPY_PY_MACHINE_HW_PWM (1) +#define MICROPY_PY_MACHINE_HW_SPI (1) +#define MICROPY_PY_MACHINE_TIMER (1) +#define MICROPY_PY_MACHINE_RTCOUNTER (1) +#define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_ADC (1) +#define MICROPY_PY_MACHINE_TEMP (1) +#define MICROPY_HW_ENABLE_RNG (1) + +// Configure LEDS +#define MICROPY_HW_HAS_LED (1) +#define MICROPY_HW_LED_COUNT (3) +#define MICROPY_HW_LED_PULLUP (1) +#define MICROPY_HW_LED1 (13) // LED1 RED +#define MICROPY_HW_LED2 (25) // LED2 GREEN +#define MICROPY_HW_LED3 (32) // LED3 BLUE + +// UART config +#define MICROPY_HW_UART1_RX (29) +#define MICROPY_HW_UART1_TX (45) +#define MICROPY_HW_UART1_CTS (44) +#define MICROPY_HW_UART1_RTS (31) +#define MICROPY_HW_UART1_HWFC (1) + +// SPI config +#define MICROPY_HW_SPI0_NAME "SPI0" +#define MICROPY_HW_SPI0_SCK (12) +#define MICROPY_HW_SPI0_MOSI (14) +#define MICROPY_HW_SPI0_MISO (15) + +// PWM Names +#define MICROPY_HW_PWM0_NAME "PWM0" +#define MICROPY_HW_PWM1_NAME "PWM1" +#define MICROPY_HW_PWM2_NAME "PWM2" + +// How Many LED indexes appear in the help() message +#define HELP_TEXT_BOARD_LED "1,2,3" diff --git a/ports/nrf/boards/evk_nina_b3/mpconfigboard.mk b/ports/nrf/boards/evk_nina_b3/mpconfigboard.mk new file mode 100644 index 0000000000..ca555d3932 --- /dev/null +++ b/ports/nrf/boards/evk_nina_b3/mpconfigboard.mk @@ -0,0 +1,7 @@ +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +SOFTDEV_VERSION = 6.1.1 +LD_FILES += boards/nrf52840_1M_256k.ld + +NRF_DEFINES += -DNRF52840_XXAA diff --git a/ports/nrf/boards/evk_nina_b3/pins.csv b/ports/nrf/boards/evk_nina_b3/pins.csv new file mode 100644 index 0000000000..e6190bac0a --- /dev/null +++ b/ports/nrf/boards/evk_nina_b3/pins.csv @@ -0,0 +1,48 @@ +P0,P0 +P1,P1 +P2,P2,ADC0_IN0 +P3,P3,ADC0_IN1 +P4,P4,ADC0_IN2 +P5,P5,ADC0_IN3 +P6,P6 +P7,P7 +P8,P8 +P9,P9 +P10,P10 +P11,P11 +P12,P12 +P13,P13 +P14,P14 +P15,P15 +P16,P16 +P17,P17 +P18,P18 +P19,P19 +P20,P20 +P21,P21 +P22,P22 +P23,P23 +P24,P24 +P25,P25 +P26,P26 +P27,P27 +P28,P28,ADC0_IN4 +P29,P29,ADC0_IN5 +P30,P30,ADC0_IN6 +P31,P31,ADC0_IN7 +P32,P32 +P33,P33 +P34,P34 +P35,P35 +P36,P36 +P37,P37 +P38,P38 +P39,P39 +P40,P40 +P41,P41 +P42,P42 +P43,P43 +P44,P44 +P45,P45 +P46,P46 +P47,P47 From 07528d1f855cf7a970913477b40c664700a0aa4d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 16 May 2021 20:11:44 -0700 Subject: [PATCH 125/349] docs/library: Clarify what type of algorithm is implemented in heapq. --- docs/library/uheapq.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/library/uheapq.rst b/docs/library/uheapq.rst index f822f1e7f3..9ae1f61a17 100644 --- a/docs/library/uheapq.rst +++ b/docs/library/uheapq.rst @@ -6,9 +6,11 @@ |see_cpython_module| :mod:`python:heapq`. -This module implements the heap queue algorithm. +This module implements the +`min heap queue algorithm `_. -A heap queue is simply a list that has its elements stored in a certain way. +A heap queue is essentially a list that has its elements stored in such a way +that the first item of the list is always the smallest. Functions --------- @@ -19,8 +21,10 @@ Functions .. function:: heappop(heap) - Pop the first item from the ``heap``, and return it. Raises IndexError if - heap is empty. + Pop the first item from the ``heap``, and return it. Raise ``IndexError`` if + ``heap`` is empty. + + The returned item will be the smallest item in the ``heap``. .. function:: heapify(x) From 452fa3f8d4cd8880da06b8a41e191e2acac59c3f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 16 May 2021 20:21:26 -0700 Subject: [PATCH 126/349] docs/library: Add a blank line to fix formatting for ussl docs. --- docs/library/ussl.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/library/ussl.rst b/docs/library/ussl.rst index 14e3f3ad14..77d278d41d 100644 --- a/docs/library/ussl.rst +++ b/docs/library/ussl.rst @@ -13,7 +13,8 @@ facilities for network sockets, both client-side and server-side. Functions --------- -.. function:: ussl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None, do_handshake=True) +.. function:: ussl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None, do_handshake=True) + Takes a `stream` *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type), and returns an instance of ssl.SSLSocket, which wraps the underlying stream in an SSL context. Returned object has the usual `stream` interface methods like From 7408ca1d7857df5ea348da35c9ee12f70a024478 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 16 May 2021 13:27:54 +1000 Subject: [PATCH 127/349] mimxrt: Improve ticks and sleep functions using GPT. SysTick cannot wake the CPU from WFI/WFE so a hardware timer is needed to keep track of ticks/delay (similar to the nrf port). Fixes issue #7234. Signed-off-by: Damien George --- ports/mimxrt/Makefile | 2 + ports/mimxrt/board_init.c | 7 -- ports/mimxrt/main.c | 2 + ports/mimxrt/mphalport.c | 17 +---- ports/mimxrt/mphalport.h | 16 +++-- ports/mimxrt/ticks.c | 137 ++++++++++++++++++++++++++++++++++++++ ports/mimxrt/ticks.h | 35 ++++++++++ 7 files changed, 189 insertions(+), 27 deletions(-) create mode 100644 ports/mimxrt/ticks.c create mode 100644 ports/mimxrt/ticks.h diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 85e77b978e..3a001182a0 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -82,6 +82,7 @@ SRC_TINYUSB_IMX_C += \ $(MCU_DIR)/project_template/clock_config.c \ $(MCU_DIR)/drivers/fsl_clock.c \ $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_gpt.c \ $(MCU_DIR)/drivers/fsl_common.c \ $(MCU_DIR)/drivers/fsl_lpuart.c \ $(MCU_DIR)/drivers/fsl_flexram.c \ @@ -90,6 +91,7 @@ SRC_C = \ main.c \ led.c \ pin.c \ + ticks.c \ tusb_port.c \ board_init.c \ $(BOARD_DIR)/flash_config.c \ diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index cd7dc9a7dd..9095c88048 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -53,9 +53,6 @@ void board_init(void) { // Enable IOCON clock CLOCK_EnableClock(kCLOCK_Iomuxc); - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); - // ------------- USB0 ------------- // // Clock @@ -85,10 +82,6 @@ void board_init(void) { // CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); } -void SysTick_Handler(void) { - systick_ms++; -} - void USB_OTG1_IRQHandler(void) { tud_int_handler(0); tud_task(); diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index e06283a8ab..7832afffcb 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -32,6 +32,7 @@ #include "py/stackctrl.h" #include "lib/utils/gchelper.h" #include "lib/utils/pyexec.h" +#include "ticks.h" #include "tusb.h" #include "led.h" @@ -41,6 +42,7 @@ void board_init(void); int main(void) { board_init(); + ticks_init(); tusb_init(); led_init(); diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c index 9fee3e85d0..02a61a4f2a 100644 --- a/ports/mimxrt/mphalport.c +++ b/ports/mimxrt/mphalport.c @@ -27,6 +27,7 @@ #include "py/runtime.h" #include "py/mphal.h" +#include "ticks.h" #include "tusb.h" #include CPU_HEADER_H @@ -46,22 +47,6 @@ void mp_hal_set_interrupt_char(int c) { #endif -void mp_hal_delay_ms(mp_uint_t ms) { - ms += 1; - uint32_t t0 = systick_ms; - while (systick_ms - t0 < ms) { - MICROPY_EVENT_POLL_HOOK - } -} - -void mp_hal_delay_us(mp_uint_t us) { - uint32_t ms = us / 1000 + 1; - uint32_t t0 = systick_ms; - while (systick_ms - t0 < ms) { - __WFI(); - } -} - int mp_hal_stdin_rx_chr(void) { for (;;) { // TODO diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 2b9e49432c..993e151566 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -28,21 +28,29 @@ #define MICROPY_INCLUDED_MIMXRT_MPHALPORT_H #include +#include "ticks.h" #define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) #define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) -extern volatile uint32_t systick_ms; - void mp_hal_set_interrupt_char(int c); static inline mp_uint_t mp_hal_ticks_ms(void) { - return systick_ms; + return ticks_ms32(); } static inline mp_uint_t mp_hal_ticks_us(void) { - return systick_ms * 1000; + return ticks_us32(); +} + +static inline void mp_hal_delay_ms(mp_uint_t ms) { + uint64_t us = (uint64_t)ms * 1000; + ticks_delay_us64(us); +} + +static inline void mp_hal_delay_us(mp_uint_t us) { + ticks_delay_us64(us); } static inline mp_uint_t mp_hal_ticks_cpu(void) { diff --git a/ports/mimxrt/ticks.c b/ports/mimxrt/ticks.c new file mode 100644 index 0000000000..676f81b30e --- /dev/null +++ b/ports/mimxrt/ticks.c @@ -0,0 +1,137 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "ticks.h" +#include "fsl_gpt.h" + +// General purpose timer for keeping microsecond and millisecond tick values. +#define GPTx GPT2 +#define GPTx_IRQn GPT2_IRQn +#define GPTx_IRQHandler GPT2_IRQHandler + +static uint32_t ticks_us64_upper; +static uint32_t ticks_ms_upper; + +void ticks_init(void) { + ticks_us64_upper = 0; + ticks_ms_upper = 0; + + gpt_config_t config; + config.clockSource = kGPT_ClockSource_Osc; + config.divider = 24; // XTAL is 24MHz + config.enableFreeRun = true; + config.enableRunInWait = true; + config.enableRunInStop = true; + config.enableRunInDoze = true; + config.enableRunInDbg = false; + config.enableMode = true; + GPT_Init(GPTx, &config); + + GPT_EnableInterrupts(GPTx, kGPT_RollOverFlagInterruptEnable); + NVIC_SetPriority(GPTx_IRQn, 0); // highest priority + NVIC_EnableIRQ(GPTx_IRQn); + + GPT_StartTimer(GPTx); +} + +void GPTx_IRQHandler(void) { + if (GPT_GetStatusFlags(GPTx, kGPT_OutputCompare1Flag)) { + GPT_ClearStatusFlags(GPTx, kGPT_OutputCompare1Flag); + GPT_DisableInterrupts(GPTx, kGPT_OutputCompare1InterruptEnable); + __SEV(); + } + if (GPT_GetStatusFlags(GPTx, kGPT_RollOverFlag)) { + GPT_ClearStatusFlags(GPTx, kGPT_RollOverFlag); + ++ticks_us64_upper; + if (++ticks_ms_upper >= 1000) { + // Wrap upper counter at a multiple of 1000 so that when mp_hal_ticks_ms() + // wraps due to overflow it wraps smoothly. + ticks_ms_upper = 0; + } + } +} + +static void ticks_wake_after_us32(uint32_t us) { + if (us < 2) { + // Delay too short to guarantee that we won't miss it when setting the OCR below. + __SEV(); + } else { + // Disable IRQs so setting the OCR is done without any interruption. + uint32_t irq_state = DisableGlobalIRQ(); + GPT_EnableInterrupts(GPTx, kGPT_OutputCompare1InterruptEnable); + uint32_t oc = GPT_GetCurrentTimerCount(GPTx) + us; + GPT_SetOutputCompareValue(GPTx, kGPT_OutputCompare_Channel1, oc); + EnableGlobalIRQ(irq_state); + } +} + +static uint64_t ticks_us64_with(uint32_t *upper_ptr) { + uint32_t irq_state = DisableGlobalIRQ(); + uint32_t lower = GPT_GetCurrentTimerCount(GPTx); + uint32_t upper = *upper_ptr; + uint32_t overflow = GPT_GetStatusFlags(GPTx, kGPT_RollOverFlag); + EnableGlobalIRQ(irq_state); + if (overflow && lower < 0x80000000) { + // The timer counter overflowed before reading it but the IRQ handler + // has not yet been called, so perform the IRQ arithmetic now. + ++upper; + } + return (uint64_t)upper << 32 | (uint64_t)lower; +} + +uint32_t ticks_us32(void) { + return GPT_GetCurrentTimerCount(GPTx); +} + +uint64_t ticks_us64(void) { + return ticks_us64_with(&ticks_us64_upper); +} + +uint32_t ticks_ms32(void) { + // This will return a value that only has the lower 32-bits valid. + return ticks_us64_with(&ticks_ms_upper) / 1000; +} + +void ticks_delay_us64(uint64_t us) { + uint64_t t0 = ticks_us64(); + for (;;) { + uint64_t dt = ticks_us64() - t0; + if (dt >= us) { + return; + } + dt = us - dt; + if (dt > 0xffffffff) { + dt = 0xffffffff; + } + ticks_wake_after_us32((uint32_t)dt); + if (dt < 50) { + __WFE(); + } else { + MICROPY_EVENT_POLL_HOOK + } + } +} diff --git a/ports/mimxrt/ticks.h b/ports/mimxrt/ticks.h new file mode 100644 index 0000000000..11127c29cc --- /dev/null +++ b/ports/mimxrt/ticks.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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_MIMXRT_TICKS_H +#define MICROPY_INCLUDED_MIMXRT_TICKS_H + +void ticks_init(void); +uint32_t ticks_us32(void); +uint64_t ticks_us64(void); +uint32_t ticks_ms32(void); +void ticks_delay_us64(uint64_t us); + +#endif // MICROPY_INCLUDED_MIMXRT_TICKS_H From 9d58d46e0a28b7bd3344cae049e8085bcd75cb75 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 28 Jul 2020 16:27:19 +1000 Subject: [PATCH 128/349] docs/library/pyb.Pin.rst: Update the arguments for Pin.init(). Add details for Pin.init() value and alt arguments. --- docs/library/pyb.Pin.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 3d019cd8e0..6465653f74 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -98,11 +98,11 @@ Class methods Methods ------- -.. method:: Pin.init(mode, pull=Pin.PULL_NONE, af=-1) +.. method:: Pin.init(mode, pull=Pin.PULL_NONE, \*, value=None, alt=-1) Initialise the pin: - - ``mode`` can be one of: + - *mode* can be one of: - ``Pin.IN`` - configure the pin for input; - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; @@ -111,14 +111,17 @@ Methods - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - ``Pin.ANALOG`` - configure the pin for analog. - - ``pull`` can be one of: + - *pull* can be one of: - ``Pin.PULL_NONE`` - no pull up or down resistors; - ``Pin.PULL_UP`` - enable the pull-up resistor; - ``Pin.PULL_DOWN`` - enable the pull-down resistor. - - when mode is ``Pin.AF_PP`` or ``Pin.AF_OD``, then af can be the index or name - of one of the alternate functions associated with a pin. + - *value* if not None will set the port output value before enabling the pin. + + - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the + index or name of one of the alternate functions associated with a pin. + This arg was previously called *af* which can still be used if needed. Returns: ``None``. From c24003abec78ee443ddc1bdc375c48513e45a54a Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Mon, 13 Jan 2020 17:25:01 +1100 Subject: [PATCH 129/349] stm32/boards: Add VCC_GND_F407VE board. --- ports/stm32/boards/VCC_GND_F407VE/bdev.c | 28 +++ .../stm32/boards/VCC_GND_F407VE/board_init.c | 7 + .../boards/VCC_GND_F407VE/mpconfigboard.h | 163 ++++++++++++++++++ .../boards/VCC_GND_F407VE/mpconfigboard.mk | 6 + ports/stm32/boards/VCC_GND_F407VE/pins.csv | 112 ++++++++++++ .../VCC_GND_F407VE/stm32f4xx_hal_conf.h | 15 ++ 6 files changed, 331 insertions(+) create mode 100644 ports/stm32/boards/VCC_GND_F407VE/bdev.c create mode 100644 ports/stm32/boards/VCC_GND_F407VE/board_init.c create mode 100644 ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h create mode 100644 ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk create mode 100644 ports/stm32/boards/VCC_GND_F407VE/pins.csv create mode 100644 ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/VCC_GND_F407VE/bdev.c b/ports/stm32/boards/VCC_GND_F407VE/bdev.c new file mode 100644 index 0000000000..18b5b85b18 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/bdev.c @@ -0,0 +1,28 @@ +#include "storage.h" + +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// External SPI flash uses standard SPI interface + +STATIC const mp_soft_spi_obj_t soft_spi_bus = { + .delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = MICROPY_HW_SPIFLASH_SCK, + .mosi = MICROPY_HW_SPIFLASH_MOSI, + .miso = MICROPY_HW_SPIFLASH_MISO, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void*)&soft_spi_bus, + .bus.u_spi.proto = &mp_soft_spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +#endif diff --git a/ports/stm32/boards/VCC_GND_F407VE/board_init.c b/ports/stm32/boards/VCC_GND_F407VE/board_init.c new file mode 100644 index 0000000000..1d5900de55 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/board_init.c @@ -0,0 +1,7 @@ +#include "py/mphal.h" + +void VCC_GND_F407VE_board_early_init(void) { + // set SPI flash CS pin high + mp_hal_pin_output(pin_A4); + mp_hal_pin_write(pin_A4, 1); +} diff --git a/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h new file mode 100644 index 0000000000..fd896c6666 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.h @@ -0,0 +1,163 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * MIT License; Copyright (c) 2021 Damien P. George + */ + +// STM32F407VET6 Mini by VCC-GND Studio +// http://vcc-gnd.com/ +// https://item.taobao.com/item.htm?ft=t&id=523361737493 +// https://www.aliexpress.com/wholesale?SearchText=STM32F407VET6+Mini + +// DFU mode can be accessed by switching BOOT0 DIP ON (towards USB) + +#define MICROPY_HW_BOARD_NAME "VCC-GND STM32F407VE" +#define MICROPY_HW_MCU_NAME "STM32F407VE" +#define MICROPY_HW_FLASH_FS_LABEL "VCCGNDF407VE" + +// 1 = use internal flash (512 KByte) +// 0 = use external SPI flash +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) + +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 25MHz +#define MICROPY_HW_CLK_PLLM (25) // divide external clock by this to get 1MHz +#define MICROPY_HW_CLK_PLLN (336) // PLL clock in MHz +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) // divide PLL clock by this to get core clock +#define MICROPY_HW_CLK_PLLQ (7) // divide core clock by this to get 48MHz + +// The board has a 32kHz crystal for the RTC +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_US (0) +// #define MICROPY_HW_RTC_USE_CALOUT (1) // turn on/off PC13 512Hz output + +// USART1 +#define MICROPY_HW_UART1_TX (pin_A9) // PA9,PB6 +#define MICROPY_HW_UART1_RX (pin_A10) // PA10,PB7 + +// USART2 +#define MICROPY_HW_UART2_TX (pin_A2) // PA2,PD5 +#define MICROPY_HW_UART2_RX (pin_A3) // PA3,PD6 +#define MICROPY_HW_UART2_RTS (pin_A1) // PA1,PD4 +#define MICROPY_HW_UART2_CTS (pin_A0) // PA0,PD3 + +// USART3 +#define MICROPY_HW_UART3_TX (pin_D8) // PB10,PC10,PD8 +#define MICROPY_HW_UART3_RX (pin_D9) // PB11,PC11,PD9 +#define MICROPY_HW_UART3_RTS (pin_D12) // PB14,PD12 +#define MICROPY_HW_UART3_CTS (pin_D11) // PB13,PD11 + +// UART4 +#define MICROPY_HW_UART4_TX (pin_A0) // PA0,PC10 +#define MICROPY_HW_UART4_RX (pin_A1) // PA1,PC11 + +// UART5 +#define MICROPY_HW_UART5_TX (pin_C12) // PC12 +#define MICROPY_HW_UART5_RX (pin_D2) // PD2 + +// USART6 +#define MICROPY_HW_UART6_TX (pin_C6) // PC6,PG14 +#define MICROPY_HW_UART6_RX (pin_C7) // PC7,PG9 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B6) // PB8,PB6 +#define MICROPY_HW_I2C1_SDA (pin_B7) // PB9,PB7 +#define MICROPY_HW_I2C2_SCL (pin_B10) // PB10 +#define MICROPY_HW_I2C2_SDA (pin_B11) // PB11 +#define MICROPY_HW_I2C3_SCL (pin_A8) // PA8 +#define MICROPY_HW_I2C3_SDA (pin_C9) // PC9 +// AT24C08 EEPROM on I2C1 0x50-0x53 + +// I2S buses +// I2S2_CK PB13 +// I2S2_MCK PC6 +// I2S2_SD PB15 +// I2S2_WS PB12 +// I2S3_CK PB3 +// I2S3_MCK PC7 +// I2S3_SD PB5 +// I2S3_WS PA15 + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) // PA4 +#define MICROPY_HW_SPI1_SCK (pin_A5) // PA5,PB3 +#define MICROPY_HW_SPI1_MISO (pin_A6) // PA6,PB4 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // PA7,PB5 + +#define MICROPY_HW_SPI2_NSS (pin_B12) // PB12 +#define MICROPY_HW_SPI2_SCK (pin_B13) // PB13 +#define MICROPY_HW_SPI2_MISO (pin_B14) // PB14 +#define MICROPY_HW_SPI2_MOSI (pin_B15) // PB15 + +#define MICROPY_HW_SPI3_NSS (pin_A15) // PA15 +#define MICROPY_HW_SPI3_SCK (pin_B3) // PB3 +#define MICROPY_HW_SPI3_MISO (pin_B4) // PB4 +#define MICROPY_HW_SPI3_MOSI (pin_B5) // PB5 + +// CAN buses +#define MICROPY_HW_CAN1_TX (pin_B9) // PB9,PD1,PA12 +#define MICROPY_HW_CAN1_RX (pin_B8) // PB8,PD0,PA11 +#define MICROPY_HW_CAN2_TX (pin_B13) // PB13 +#define MICROPY_HW_CAN2_RX (pin_B12) // PB12 + +// DAC +// DAC_OUT1 PA4 +// DAC_OUT2 PA5 + +// LEDs +#define MICROPY_HW_LED1 (pin_B9) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// If using external SPI flash +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// The board does not have onboard SPI flash. You need to add an external one. +#define MICROPY_HW_SPIFLASH_SIZE_BITS (4 * 1024 * 1024) // W25X40 - 4 Mbit (512 KByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (32 * 1024 * 1024) // W25Q32 - 32 Mbit (4 MByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (64 * 1024 * 1024) // W25Q64 - 64 Mbit (8 MByte) +// #define MICROPY_HW_SPIFLASH_SIZE_BITS (128 * 1024 * 1024) // W25Q128 - 128 Mbit (16 MByte) + +#define MICROPY_HW_SPIFLASH_CS (pin_A4) // also in board_init.c +#define MICROPY_HW_SPIFLASH_SCK (pin_A5) +#define MICROPY_HW_SPIFLASH_MISO (pin_A6) +#define MICROPY_HW_SPIFLASH_MOSI (pin_A7) + +#define MICROPY_BOARD_EARLY_INIT VCC_GND_F407VE_board_early_init +void VCC_GND_F407VE_board_early_init(void); + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ +) +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl), (n)) + +#endif + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) +// 1 - PC10 - DAT2/RES +// 2 - PC11 - CD/DAT3/CS +// 3 - PD2 - CMD/DI +// 4 - VCC - VDD +// 5 - PC12 - CLK/SCLK +// 6 - GND - VSS +// 7 - PC8 - DAT0/D0 +// 8 - PC9 - DAT1/RES +// 9 SW2 - GND +// 10 SW1 - PA8 + +// USB config +#define MICROPY_HW_USB_FS (1) +// #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +// #define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) diff --git a/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk new file mode 100644 index 0000000000..b154dcfbac --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/mpconfigboard.mk @@ -0,0 +1,6 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F407xx +AF_FILE = boards/stm32f405_af.csv +LD_FILES = boards/stm32f405.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 diff --git a/ports/stm32/boards/VCC_GND_F407VE/pins.csv b/ports/stm32/boards/VCC_GND_F407VE/pins.csv new file mode 100644 index 0000000000..f04d96771b --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/pins.csv @@ -0,0 +1,112 @@ +P1_1,GND +P1_2,GND +P1_3,VBAT +P1_4,VCC_3V3 +P1_5,VIN_5V +P1_6,VIN_5V +P1_7,PE0 +P1_8,PE1 +P1_9,PE2 +P1_10,PE3 +P1_11,PE4 +P1_12,PE5 +P1_13,PE6 +P1_14,PC13 +P1_15,PC14 +P1_16,PC15 +P1_17,PC0 +P1_18,PC1 +P1_19,PC2 +P1_20,PC3 +P1_21,PA0 +P1_22,PA2 +P1_23,PA1 +P1_24,PA3 +P1_25,PA4 +P1_26,PA5 +P1_27,PA6 +P1_28,PA7 +P1_29,PC4 +P1_30,PC5 +P1_31,PB0 +P1_32,PB1 +P1_33,PB2 +P1_34,PE7 +P1_35,PE8 +P1_36,PE9 +P2_1,PE11 +P2_2,PE10 +P2_3,PE13 +P2_4,PE12 +P2_5,PE15 +P2_6,PE14 +P2_7,PB11 +P2_8,PB10 +P2_9,PB13 +P2_10,PB12 +P2_11,PB15 +P2_12,PB14 +P2_13,PD9 +P2_14,PD8 +P2_15,PD11 +P2_16,PD10 +P2_17,PD13 +P2_18,PD12 +P2_19,PD15 +P2_20,PD14 +P3_1,PC8 +P3_2,PC6 +P3_3,PC9 +P3_4,PC7 +P3_5,PA9 +P3_6,PA8 +P3_7,PA11 +P3_8,PA10 +P3_9,PA13 +P3_10,PA12 +P3_11,PA15 +P3_12,PA14 +P3_13,PC11 +P3_14,PC10 +P3_15,PC12 +P3_16,PD0 +P3_17,PD1 +P3_18,PD2 +P3_19,PD3 +P3_20,PD4 +P3_21,PD5 +P3_22,PD6 +P3_23,PD7 +P3_24,PB3 +P3_25,PB4 +P3_26,PB5 +P3_27,PB6 +P3_28,PB7 +P3_29,PB8 +P3_30,PB9 +P3_31,GND +P3_32,GND +P3_33,VCC_3V3 +P3_34,VCC_3V3 +P3_35,GND +P3_36,GND +DAC1,PA4 +DAC2,PA5 +BLUE_LED,PB9 +BOOT1,PB2 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +SWCLK,PA14 +SWDIO,PA13 +OSC32_IN,PC14 +OSC32_OUT,PC15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CK,PC12 +SD_CMD,PD2 +SD,PA8 +SD_SW,PA8 diff --git a/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h b/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..fe2069fe14 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407VE/stm32f4xx_hal_conf.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (25000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From 1ca66efbf7be4f57ab31df5ecb81d27da4aefd0d Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Mon, 13 Jan 2020 17:26:01 +1100 Subject: [PATCH 130/349] stm32/boards: Add VCC_GND_F407ZG board. --- ports/stm32/boards/VCC_GND_F407ZG/bdev.c | 28 +++ .../stm32/boards/VCC_GND_F407ZG/board_init.c | 7 + .../boards/VCC_GND_F407ZG/mpconfigboard.h | 182 ++++++++++++++++++ .../boards/VCC_GND_F407ZG/mpconfigboard.mk | 10 + ports/stm32/boards/VCC_GND_F407ZG/pins.csv | 157 +++++++++++++++ .../VCC_GND_F407ZG/stm32f4xx_hal_conf.h | 15 ++ 6 files changed, 399 insertions(+) create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/bdev.c create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/board_init.c create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/pins.csv create mode 100644 ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h diff --git a/ports/stm32/boards/VCC_GND_F407ZG/bdev.c b/ports/stm32/boards/VCC_GND_F407ZG/bdev.c new file mode 100644 index 0000000000..18b5b85b18 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/bdev.c @@ -0,0 +1,28 @@ +#include "storage.h" + +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// External SPI flash uses standard SPI interface + +STATIC const mp_soft_spi_obj_t soft_spi_bus = { + .delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = MICROPY_HW_SPIFLASH_SCK, + .mosi = MICROPY_HW_SPIFLASH_MOSI, + .miso = MICROPY_HW_SPIFLASH_MISO, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void*)&soft_spi_bus, + .bus.u_spi.proto = &mp_soft_spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +#endif diff --git a/ports/stm32/boards/VCC_GND_F407ZG/board_init.c b/ports/stm32/boards/VCC_GND_F407ZG/board_init.c new file mode 100644 index 0000000000..1f4663fdf9 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/board_init.c @@ -0,0 +1,7 @@ +#include "py/mphal.h" + +void VCC_GND_F407ZG_board_early_init(void) { + // set SPI flash CS pin high + mp_hal_pin_output(pin_C4); + mp_hal_pin_write(pin_C4, 1); +} diff --git a/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h new file mode 100644 index 0000000000..bd17ab410f --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.h @@ -0,0 +1,182 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * MIT License; Copyright (c) 2021 Damien P. George + */ + +// STM32F407ZGT6 Mini by VCC-GND Studio +// http://vcc-gnd.com/ +// https://item.taobao.com/item.htm?ft=t&id=523383164199 +// https://www.aliexpress.com/wholesale?SearchText=STM32F407ZGT6+Mini + +// DFU mode can be accessed by switching BOOT0 DIP ON (towards USB) + +#define MICROPY_HW_BOARD_NAME "VCC-GND STM32F407ZG" +#define MICROPY_HW_MCU_NAME "STM32F407ZG" +#define MICROPY_HW_FLASH_FS_LABEL "VCCGNDF407ZG" + +// 1 = use internal flash (1 MByte) +// 0 = use onboard SPI flash (512 KByte) Winbond W25X40 +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_ENABLE_SDCARD (1) + +// HSE is 25MHz +#define MICROPY_HW_CLK_PLLM (25) // divide external clock by this to get 1MHz +#define MICROPY_HW_CLK_PLLN (336) // PLL clock in MHz +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) // divide PLL clock by this to get core clock +#define MICROPY_HW_CLK_PLLQ (7) // divide core clock by this to get 48MHz + +// The board has a 32kHz crystal for the RTC +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_US (0) +// #define MICROPY_HW_RTC_USE_CALOUT (1) // turn on/off PC13 512Hz output + +// USART1 +#define MICROPY_HW_UART1_TX (pin_A9) // PA9,PB6 +#define MICROPY_HW_UART1_RX (pin_A10) // PA10,PB7 +#define MICROPY_HW_UART1_RTS (pin_A12) +#define MICROPY_HW_UART1_CTS (pin_A11) +// USART1_CK PA8 + +// USART2 +#define MICROPY_HW_UART2_TX (pin_A2) // PA2,PD5 +#define MICROPY_HW_UART2_RX (pin_A3) // PA3,PD6 +#define MICROPY_HW_UART2_RTS (pin_A1) // PA1,PD4 +#define MICROPY_HW_UART2_CTS (pin_A0) // PA0,PD3 +// USART2_CK PA4,PD7 + +// USART3 +#define MICROPY_HW_UART3_TX (pin_D8) // PB10,PC10,PD8 +#define MICROPY_HW_UART3_RX (pin_D9) // PB11,PC11,PD9 +#define MICROPY_HW_UART3_RTS (pin_D12) // PB14,PD12 +#define MICROPY_HW_UART3_CTS (pin_D11) // PB13,PD11 +// USART3_CK PB12,PC12,PD10 + +// UART4 +#define MICROPY_HW_UART4_TX (pin_A0) // PA0,PC10 +#define MICROPY_HW_UART4_RX (pin_A1) // PA1,PC11 + +// UART5 +#define MICROPY_HW_UART5_TX (pin_C12) // PC12 +#define MICROPY_HW_UART5_RX (pin_D2) // PD2 + +// USART6 +#define MICROPY_HW_UART6_TX (pin_C6) // PC6,PG14 +#define MICROPY_HW_UART6_RX (pin_C7) // PC7,PG9 +#define MICROPY_HW_UART6_RTS (pin_G8) // PG8,PG12 +#define MICROPY_HW_UART6_CTS (pin_G13) // PG13,PG15 +// USART6_CK PC8,PG7 + +// I2C buses +#define MICROPY_HW_I2C1_SCL (pin_B6) // PB8,PB6 +#define MICROPY_HW_I2C1_SDA (pin_B7) // PB9,PB7 +// I2C1_SMBA PB5 +#define MICROPY_HW_I2C2_SCL (pin_B10) // PB10,PF1 +#define MICROPY_HW_I2C2_SDA (pin_B11) // PB11,PF0 +// I2C2_SMBA PB12,PF2 +#define MICROPY_HW_I2C3_SCL (pin_A8) // PA8 +#define MICROPY_HW_I2C3_SDA (pin_C9) // PC9 +// I2C3_SMBA PA9 + +// AT24C08 EEPROM on I2C1 0x50-0x53 + +// I2S buses - multiplexed with SPI2 and SPI3 +// I2S2_CK PB10,PB13 +// I2S2_MCK PC6 +// I2S2_SD PB15,PC3 +// I2S2_WS PB9,PB12 +// I2S3_CK PB3,PC10 +// I2S3_MCK PC7 +// I2S3_SD PB5,PC12 +// I2S3_WS PA4,PA15 + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) // PA4,PA15 +#define MICROPY_HW_SPI1_SCK (pin_A5) // PA5,PB3 +#define MICROPY_HW_SPI1_MISO (pin_A6) // PA6,PB4 +#define MICROPY_HW_SPI1_MOSI (pin_A7) // PA7,PB5 + +#define MICROPY_HW_SPI2_NSS (pin_B12) // PB12,PB9 +#define MICROPY_HW_SPI2_SCK (pin_B13) // PB13,PB10 +#define MICROPY_HW_SPI2_MISO (pin_B14) // PB14,PC2 +#define MICROPY_HW_SPI2_MOSI (pin_B15) // PB15,PC3 + +#define MICROPY_HW_SPI3_NSS (pin_A15) // PA15,PA4 +#define MICROPY_HW_SPI3_SCK (pin_B3) // PB3,PC10 +#define MICROPY_HW_SPI3_MISO (pin_B4) // PB4,PC11 +#define MICROPY_HW_SPI3_MOSI (pin_B5) // PB5,PC12 + +// CAN buses +#define MICROPY_HW_CAN1_TX (pin_B9) // PB9,PD1,PA12 +#define MICROPY_HW_CAN1_RX (pin_B8) // PB8,PD0,PA11 +#define MICROPY_HW_CAN2_TX (pin_B13) // PB13,PB6 +#define MICROPY_HW_CAN2_RX (pin_B12) // PB12,PB5 + +// DAC +// DAC_OUT1 PA4 +// DAC_OUT2 PA5 + +// LEDs +#define MICROPY_HW_LED1 (pin_G15) // blue +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +// If using onboard SPI flash +#if !MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE + +// W25X40 SPI Flash = 4 Mbit (512 KByte) +#define MICROPY_HW_SPIFLASH_SIZE_BITS (4 * 1024 * 1024) +#define MICROPY_HW_SPIFLASH_CS (pin_C4) +#define MICROPY_HW_SPIFLASH_SCK (pin_A5) +#define MICROPY_HW_SPIFLASH_MISO (pin_A6) +#define MICROPY_HW_SPIFLASH_MOSI (pin_A7) + +#define MICROPY_BOARD_EARLY_INIT VCC_GND_F407ZG_board_early_init +void VCC_GND_F407ZG_board_early_init(void); + +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \ + (op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ +) +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl), (n)) + +#endif + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_F10) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) +// 1 - PC10 - DAT2/RES +// 2 - PC11 - CD/DAT3/CS +// 3 - PD2 - CMD/DI +// 4 - VCC - VDD +// 5 - PC12 - CLK/SCLK +// 6 - GND - VSS +// 7 - PC8 - DAT0/D0 +// 8 - PC9 - DAT1/RES +// 9 SW2 - GND +// 10 SW1 - PF10 + +// USB config +#define MICROPY_HW_USB_FS (1) +// #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +// #define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// Ethernet via RMII +#define MICROPY_HW_ETH_MDC (pin_C1) +#define MICROPY_HW_ETH_MDIO (pin_A2) +#define MICROPY_HW_ETH_RMII_REF_CLK (pin_A1) +#define MICROPY_HW_ETH_RMII_CRS_DV (pin_A7) +#define MICROPY_HW_ETH_RMII_RXD0 (pin_C4) +#define MICROPY_HW_ETH_RMII_RXD1 (pin_C5) +#define MICROPY_HW_ETH_RMII_TX_EN (pin_B11) +#define MICROPY_HW_ETH_RMII_TXD0 (pin_B12) +#define MICROPY_HW_ETH_RMII_TXD1 (pin_B13) diff --git a/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk new file mode 100644 index 0000000000..c67807867e --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/mpconfigboard.mk @@ -0,0 +1,10 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F407xx +AF_FILE = boards/stm32f405_af.csv +LD_FILES = boards/stm32f405.ld boards/common_ifs.ld +TEXT0_ADDR = 0x08000000 +TEXT1_ADDR = 0x08020000 + +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 diff --git a/ports/stm32/boards/VCC_GND_F407ZG/pins.csv b/ports/stm32/boards/VCC_GND_F407ZG/pins.csv new file mode 100644 index 0000000000..780523a075 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/pins.csv @@ -0,0 +1,157 @@ +P1_1,GND +P1_2,GND +P1_3,VBAT +P1_4,VCC_3V3 +P1_5,VIN_5V +P1_6,VIN_5V +P1_7,PF2 +P1_8,PF3 +P1_9,PF4 +P1_10,PF5 +P1_11,PF6 +P1_12,PF7 +P1_13,PF8 +P1_14,PF9 +P1_15,PF10 +P1_16,PC0 +P1_17,PC1 +P1_18,PC2 +P1_19,PC3 +P1_20,PA0 +P1_21,PA1 +P1_22,PA2 +P1_23,PA3 +P1_24,PA4 +P1_25,PA5 +P1_26,PA6 +P1_27,PA7 +P1_28,PC4 +P1_29,PC5 +P1_30,PB0 +P1_31,PB1 +P1_32,PB2 +P1_33,PF11 +P1_34,PF12 +P1_35,PF13 +P1_36,PF14 +P1_37,PF15 +P1_38,PG0 +P1_39,PG1 +P1_40,PE7 +P1_41,PE8 +P1_42,PE9 +P1_43,GND +P1_44,GND +P2_1,PG7 +P2_2,PG6 +P2_3,PG5 +P2_4,PG4 +P2_5,PG3 +P2_6,PG2 +P2_7,PD15 +P2_8,PD14 +P2_9,PD13 +P2_10,PD12 +P2_11,PD11 +P2_12,PD10 +P2_13,PD9 +P2_14,PD8 +P2_15,PB15 +P2_16,PB14 +P2_17,PB13 +P2_18,PB12 +P2_19,PB11 +P2_20,PB10 +P2_21,PE15 +P2_22,PE14 +P2_23,PE13 +P2_24,PE12 +P2_25,PE11 +P2_26,PE10 +P3_1,PF1 +P3_2,PF0 +P3_3,PC15 +P3_4,PC14 +P3_5,PC13 +P3_6,PE6 +P3_7,PE5 +P3_8,PE4 +P3_9,PE3 +P3_10,PE2 +P3_11,PE1 +P3_12,PE0 +P4_1,GND +P4_2,GND +P4_3,VCC_3V3 +P4_4,VCC_3V3 +P4_5,PB9 +P4_6,PB8 +P4_7,PB7 +P4_8,PB6 +P4_9,PB5 +P4_10,PB4 +P4_11,PB3 +P4_12,PG15 +P4_13,PG14 +P4_14,PG13 +P4_15,PG12 +P4_16,PG11 +P4_17,PG10 +P4_18,PG9 +P4_19,PD7 +P4_20,PD6 +P4_21,PD5 +P4_22,PD4 +P4_23,PD3 +P4_24,PD2 +P4_25,PD1 +P4_26,PD0 +P4_27,PC12 +P4_28,PC11 +P4_29,PC10 +P4_30,PA15 +P4_31,PA14 +P4_32,PA13 +P4_33,PA12 +P4_34,PA11 +P4_35,PA10 +P4_36,PA9 +P4_37,PA8 +P4_38,PC9 +P4_39,PC8 +P4_40,PC7 +P4_41,PC6 +P4_42,PG8 +P4_43,GND +P4_44,GND +DAC1,PA4 +DAC2,PA5 +SRAM_CS,PG10 +SF_CS,PB12 +BLUE_LED,PG15 +BOOT1,PB2 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +SWCLK,PA14 +SWDIO,PA13 +OSC32_IN,PC14 +OSC32_OUT,PC15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CK,PC12 +SD_CMD,PD2 +SD,PF10 +SD_SW,PF10 +ETH_MDC,PC1 +ETH_MDIO,PA2 +ETH_RMII_REF_CLK,PA1 +ETH_RMII_CRS_DV,PA7 +ETH_RMII_RXD0,PC4 +ETH_RMII_RXD1,PC5 +ETH_RMII_TX_EN,PB11 +ETH_RMII_TXD0,PB12 +ETH_RMII_TXD1,PB13 diff --git a/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h b/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..fe2069fe14 --- /dev/null +++ b/ports/stm32/boards/VCC_GND_F407ZG/stm32f4xx_hal_conf.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (25000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H From 47b778332a0e89740775db544e7c22065df528c2 Mon Sep 17 00:00:00 2001 From: Mike Causer Date: Thu, 20 May 2021 16:21:47 +1000 Subject: [PATCH 131/349] all: Replace busses with buses. "buses" is the widely accepted plural form of "bus". --- docs/library/network.CC3K.rst | 2 +- docs/library/network.WIZNET5K.rst | 2 +- docs/library/pyb.CAN.rst | 2 +- docs/library/pyb.I2C.rst | 2 +- docs/library/pyb.SPI.rst | 2 +- docs/library/pyb.UART.rst | 2 +- docs/library/pyb.rst | 2 +- ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h | 6 +++--- ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h | 4 ++-- ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h | 6 +++--- ports/stm32/boards/CERB40/mpconfigboard.h | 6 +++--- ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h | 4 ++-- ports/stm32/boards/HYDRABUS/mpconfigboard.h | 4 ++-- ports/stm32/boards/LIMIFROG/mpconfigboard.h | 4 ++-- ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h | 4 ++-- ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h | 6 +++--- ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h | 6 +++--- ports/stm32/boards/OLIMEX_E407/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBD_SF2/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBD_SF6/mpconfigboard.h | 2 +- ports/stm32/boards/PYBLITEV10/mpconfigboard.h | 4 ++-- ports/stm32/boards/PYBV10/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBV11/mpconfigboard.h | 6 +++--- ports/stm32/boards/PYBV3/mpconfigboard.h | 4 ++-- ports/stm32/boards/PYBV4/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F411DISC/mpconfigboard.h | 4 ++-- ports/stm32/boards/STM32F429DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F439/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F4DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F769DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32F7DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32L476DISC/mpconfigboard.h | 6 +++--- ports/stm32/boards/STM32L496GDISC/mpconfigboard.h | 4 ++-- ports/stm32/machine_uart.c | 2 +- ports/stm32/pyb_i2c.c | 2 +- ports/stm32/pyb_spi.c | 2 +- ports/stm32/spi.c | 2 +- ports/teensy/uart.c | 2 +- 49 files changed, 105 insertions(+), 105 deletions(-) diff --git a/docs/library/network.CC3K.rst b/docs/library/network.CC3K.rst index 18210e2d26..41d3fb437e 100644 --- a/docs/library/network.CC3K.rst +++ b/docs/library/network.CC3K.rst @@ -25,7 +25,7 @@ For this example to work the CC3000 module must have the following connections: - VBEN connected to Y4 - IRQ connected to Y3 -It is possible to use other SPI busses and other pins for CS, VBEN and IRQ. +It is possible to use other SPI buses and other pins for CS, VBEN and IRQ. Constructors ------------ diff --git a/docs/library/network.WIZNET5K.rst b/docs/library/network.WIZNET5K.rst index e21e3a4978..9e2c40f7f3 100644 --- a/docs/library/network.WIZNET5K.rst +++ b/docs/library/network.WIZNET5K.rst @@ -26,7 +26,7 @@ For this example to work the WIZnet5x00 module must have the following connectio - nSS connected to X5 - nRESET connected to X4 -It is possible to use other SPI busses and other pins for nSS and nRESET. +It is possible to use other SPI buses and other pins for nSS and nRESET. Constructors ------------ diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst index 649bcda108..bcaeeba9df 100644 --- a/docs/library/pyb.CAN.rst +++ b/docs/library/pyb.CAN.rst @@ -30,7 +30,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See :meth:`CAN.init` for parameters of initialisation. - The physical pins of the CAN busses are: + The physical pins of the CAN buses are: - ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)`` - ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)`` diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst index 641dcb8815..56b036e074 100644 --- a/docs/library/pyb.I2C.rst +++ b/docs/library/pyb.I2C.rst @@ -64,7 +64,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the I2C busses on Pyboards V1.0 and V1.1 are: + The physical pins of the I2C buses on Pyboards V1.0 and V1.1 are: - ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)`` - ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)`` diff --git a/docs/library/pyb.SPI.rst b/docs/library/pyb.SPI.rst index 24e2ec5a73..c76b16789a 100644 --- a/docs/library/pyb.SPI.rst +++ b/docs/library/pyb.SPI.rst @@ -36,7 +36,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the SPI busses are: + The physical pins of the SPI buses are: - ``SPI(1)`` is on the X position: ``(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)`` - ``SPI(2)`` is on the Y position: ``(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)`` diff --git a/docs/library/pyb.UART.rst b/docs/library/pyb.UART.rst index a1d6e59002..e1735403c4 100644 --- a/docs/library/pyb.UART.rst +++ b/docs/library/pyb.UART.rst @@ -57,7 +57,7 @@ Constructors the bus, if any). If extra arguments are given, the bus is initialised. See ``init`` for parameters of initialisation. - The physical pins of the UART busses on Pyboard are: + The physical pins of the UART buses on Pyboard are: - ``UART(4)`` is on ``XA``: ``(TX, RX) = (X1, X2) = (PA0, PA1)`` - ``UART(1)`` is on ``XB``: ``(TX, RX) = (X9, X10) = (PB6, PB7)`` diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst index addcd20a91..321be3c52f 100644 --- a/docs/library/pyb.rst +++ b/docs/library/pyb.rst @@ -126,7 +126,7 @@ Power related functions - pclk2: frequency of the APB2 bus If given any arguments then the function sets the frequency of the CPU, - and the busses if additional arguments are given. Frequencies are given in + and the buses if additional arguments are given. Frequencies are given in Hz. Eg freq(120000000) sets sysclk (the CPU frequency) to 120MHz. Note that not all values are supported and the largest supported frequency not greater than the given value will be selected. diff --git a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h index 36d1d31315..afa81a5ba0 100644 --- a/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h +++ b/ports/stm32/boards/ADAFRUIT_F405_EXPRESS/mpconfigboard.h @@ -39,7 +39,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) // D6 #define MICROPY_HW_UART6_RX (pin_C7) // D5 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "I2C1" #define MICROPY_HW_I2C1_SCL (pin_B6) // SCL #define MICROPY_HW_I2C1_SDA (pin_B7) // SDA @@ -47,7 +47,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) // TX #define MICROPY_HW_I2C2_SDA (pin_B11) // RX -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "SPIFLASH" #define MICROPY_HW_SPI1_NSS (pin_A15) // FLASH CS #define MICROPY_HW_SPI1_SCK (pin_B3) // FLASH CLK @@ -59,7 +59,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // MISO #define MICROPY_HW_SPI2_MOSI (pin_B15) // MOSI -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "CAN1" #define MICROPY_HW_CAN1_TX (pin_B9) // D10 #define MICROPY_HW_CAN1_RX (pin_B8) // D9 diff --git a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h index b330e8fdc1..0cded1bc86 100644 --- a/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h +++ b/ports/stm32/boards/B_L072Z_LRWAN1/mpconfigboard.h @@ -35,11 +35,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h b/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h index a88bcf6756..b017edab99 100644 --- a/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h +++ b/ports/stm32/boards/B_L475E_IOT01A/mpconfigboard.h @@ -28,20 +28,20 @@ // USART3 config for internal use #define MICROPY_HW_UART3_TX (pin_D8) #define MICROPY_HW_UART3_RX (pin_D9) -// USART4 config +// USART4 config #define MICROPY_HW_UART4_TX (pin_A0) #define MICROPY_HW_UART4_RX (pin_A1) // USART 1 is connected to the virtual com port on the ST-LINK #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/CERB40/mpconfigboard.h b/ports/stm32/boards/CERB40/mpconfigboard.h index 7c166922be..2f9199d4e0 100644 --- a/ports/stm32/boards/CERB40/mpconfigboard.h +++ b/ports/stm32/boards/CERB40/mpconfigboard.h @@ -31,7 +31,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -39,7 +39,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -49,7 +49,7 @@ #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h b/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h index 53c7f3cd50..ed8178d7d4 100644 --- a/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h +++ b/ports/stm32/boards/ESPRUINO_PICO/mpconfigboard.h @@ -32,7 +32,7 @@ #define MICROPY_HW_UART6_TX (pin_A11) #define MICROPY_HW_UART6_RX (pin_A12) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -40,7 +40,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_B4) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/HYDRABUS/mpconfigboard.h b/ports/stm32/boards/HYDRABUS/mpconfigboard.h index d8f1a864b2..d894f1606c 100644 --- a/ports/stm32/boards/HYDRABUS/mpconfigboard.h +++ b/ports/stm32/boards/HYDRABUS/mpconfigboard.h @@ -30,13 +30,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/LIMIFROG/mpconfigboard.h b/ports/stm32/boards/LIMIFROG/mpconfigboard.h index 4b750c17ff..be9b5a8bb8 100644 --- a/ports/stm32/boards/LIMIFROG/mpconfigboard.h +++ b/ports/stm32/boards/LIMIFROG/mpconfigboard.h @@ -25,13 +25,13 @@ void LIMIFROG_board_early_init(void); #define MICROPY_HW_UART3_TX (pin_C10) #define MICROPY_HW_UART3_RX (pin_C11) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h b/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h index d2075b52bf..38bf8b41e9 100644 --- a/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h +++ b/ports/stm32/boards/NETDUINO_PLUS_2/mpconfigboard.h @@ -39,11 +39,11 @@ void NETDUINO_PLUS_2_board_early_init(void); #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) -// SPI busses +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_B12) #define MICROPY_HW_SPI2_SCK (pin_B13) #define MICROPY_HW_SPI2_MISO (pin_B14) diff --git a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h index fb8de60221..7333dcd0c1 100644 --- a/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F091RC/mpconfigboard.h @@ -49,13 +49,13 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 #define MICROPY_HW_I2C2_SDA (pin_B11) // pin 18 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h index babf63c7a1..6b874e298c 100644 --- a/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F401RE/mpconfigboard.h @@ -30,7 +30,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -38,7 +38,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h index 26b1e0b619..e37ce889c3 100644 --- a/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F411RE/mpconfigboard.h @@ -21,7 +21,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -29,7 +29,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h index 2f488159a4..5297ceda5c 100644 --- a/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F413ZH/mpconfigboard.h @@ -41,7 +41,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -49,7 +49,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) // shared with DAC #define MICROPY_HW_SPI1_SCK (pin_A5) // shared with DAC #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -71,7 +71,7 @@ #define MICROPY_HW_SPI5_MISO (pin_E13) #define MICROPY_HW_SPI5_MOSI (pin_E14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_G1) #define MICROPY_HW_CAN1_RX (pin_G0) #define MICROPY_HW_CAN2_TX (pin_G12) diff --git a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h index 05c98e113f..86c02b5178 100644 --- a/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F429ZI/mpconfigboard.h @@ -38,11 +38,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_B3) #define MICROPY_HW_SPI1_MISO (pin_B4) @@ -58,7 +58,7 @@ #define MICROPY_HW_SPI5_MISO (pin_F8) #define MICROPY_HW_SPI5_MOSI (pin_F9) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h index cd4ad36fa0..27845b33aa 100644 --- a/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F446RE/mpconfigboard.h @@ -24,7 +24,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) // Arduino D10, pin 17 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B7) // pin 21 on CN7 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -32,7 +32,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10 #define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h index c9b0c60f27..402efcfe31 100644 --- a/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F746ZG/mpconfigboard.h @@ -40,19 +40,19 @@ #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h index b659223b4d..4ed9f41832 100644 --- a/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_F767ZI/mpconfigboard.h @@ -41,7 +41,7 @@ void NUCLEO_F767ZI_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -49,13 +49,13 @@ void NUCLEO_F767ZI_board_early_init(void); #define MICROPY_HW_I2C4_SCL (pin_F14) #define MICROPY_HW_I2C4_SDA (pin_F15) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) #define MICROPY_HW_SPI3_MOSI (pin_B5) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_D1) #define MICROPY_HW_CAN1_RX (pin_D0) diff --git a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h index 324f2b03ce..f25263fd2b 100644 --- a/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_H743ZI/mpconfigboard.h @@ -49,7 +49,7 @@ void NUCLEO_H743ZI_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_3 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_F1) @@ -57,7 +57,7 @@ void NUCLEO_H743ZI_board_early_init(void); #define MICROPY_HW_I2C4_SCL (pin_F14) #define MICROPY_HW_I2C4_SDA (pin_F15) -// SPI +// SPI buses #define MICROPY_HW_SPI3_NSS (pin_A4) #define MICROPY_HW_SPI3_SCK (pin_B3) #define MICROPY_HW_SPI3_MISO (pin_B4) diff --git a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h index a5c5dc9a0e..b7f7bc4c88 100644 --- a/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L073RZ/mpconfigboard.h @@ -34,11 +34,11 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h index 14b3bab8a7..0a3ac1f185 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h @@ -42,13 +42,13 @@ #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_4 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_A9) #define MICROPY_HW_I2C1_SDA (pin_A10) #define MICROPY_HW_I2C3_SCL (pin_A7) #define MICROPY_HW_I2C3_SDA (pin_B4) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_B0) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h index 9823ae9b9b..1b5827d5ae 100644 --- a/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L452RE/mpconfigboard.h @@ -34,7 +34,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino D15, pin 3 on CN10 #define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino D14, pin 5 on CN10 #define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10 @@ -44,7 +44,7 @@ #define MICROPY_HW_I2C4_SCL (pin_C0) // pin 38 on CN7 #define MICROPY_HW_I2C4_SDA (pin_C1) // pin 36 on CN7 -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7 #define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10 #define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10 @@ -58,7 +58,7 @@ #define MICROPY_HW_SPI3_MISO (pin_C11) // pin 2 on CN7 #define MICROPY_HW_SPI3_MOSI (pin_C12) // pin 3 on CN7 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) diff --git a/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h index 2899a97ace..a7bb0b36bb 100644 --- a/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L476RG/mpconfigboard.h @@ -46,7 +46,7 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) @@ -54,7 +54,7 @@ #define MICROPY_HW_I2C3_SCL (pin_C0) #define MICROPY_HW_I2C3_SDA (pin_C1) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_B3) #define MICROPY_HW_SPI1_MISO (pin_B4) @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN bus +// CAN buses #define MICROPY_HW_CAN1_TX (pin_A12) #define MICROPY_HW_CAN1_RX (pin_A11) diff --git a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h index d5cd7bb1ec..999f97a708 100644 --- a/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h +++ b/ports/stm32/boards/OLIMEX_E407/mpconfigboard.h @@ -36,13 +36,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -52,7 +52,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h index 57cc75efc6..48b3ee3eb9 100644 --- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h @@ -122,7 +122,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_UART6_RTS (pyb_pin_BT_RTS) #define MICROPY_HW_UART6_CTS (pyb_pin_BT_CTS) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pyb_pin_X9) #define MICROPY_HW_I2C1_SDA (pyb_pin_X10) @@ -130,7 +130,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_I2C2_SCL (pyb_pin_Y9) #define MICROPY_HW_I2C2_SDA (pyb_pin_Y10) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pyb_pin_X5) #define MICROPY_HW_SPI1_SCK (pyb_pin_X6) @@ -146,7 +146,7 @@ extern struct _spi_bdev_t spi_bdev2; #define MICROPY_HW_SPI3_MISO (pyb_pin_W50) #define MICROPY_HW_SPI3_MOSI (pyb_pin_W46) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "X" #define MICROPY_HW_CAN1_TX (pyb_pin_X10) #define MICROPY_HW_CAN1_RX (pyb_pin_X9) diff --git a/ports/stm32/boards/PYBD_SF6/mpconfigboard.h b/ports/stm32/boards/PYBD_SF6/mpconfigboard.h index cbfbe39945..8c11d7b2ee 100644 --- a/ports/stm32/boards/PYBD_SF6/mpconfigboard.h +++ b/ports/stm32/boards/PYBD_SF6/mpconfigboard.h @@ -49,7 +49,7 @@ #define MICROPY_HW_UART7_TX (pyb_pin_W16) #define MICROPY_HW_UART7_RX (pyb_pin_W22B) -// Extra CAN busses +// Extra CAN buses #define MICROPY_HW_CAN2_NAME "Y" #define MICROPY_HW_CAN2_TX (pyb_pin_Y6) #define MICROPY_HW_CAN2_RX (pyb_pin_Y5) diff --git a/ports/stm32/boards/PYBLITEV10/mpconfigboard.h b/ports/stm32/boards/PYBLITEV10/mpconfigboard.h index 77509a6003..1643e250cb 100644 --- a/ports/stm32/boards/PYBLITEV10/mpconfigboard.h +++ b/ports/stm32/boards/PYBLITEV10/mpconfigboard.h @@ -35,7 +35,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -43,7 +43,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_B8) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 diff --git a/ports/stm32/boards/PYBV10/mpconfigboard.h b/ports/stm32/boards/PYBV10/mpconfigboard.h index dda98776cd..52382f44d5 100644 --- a/ports/stm32/boards/PYBV10/mpconfigboard.h +++ b/ports/stm32/boards/PYBV10/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -52,7 +52,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/PYBV11/mpconfigboard.h b/ports/stm32/boards/PYBV11/mpconfigboard.h index 7d10c13e8f..8e84694048 100644 --- a/ports/stm32/boards/PYBV11/mpconfigboard.h +++ b/ports/stm32/boards/PYBV11/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -52,7 +52,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -64,7 +64,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/PYBV3/mpconfigboard.h b/ports/stm32/boards/PYBV3/mpconfigboard.h index 7f1531770f..9c956efd6d 100644 --- a/ports/stm32/boards/PYBV3/mpconfigboard.h +++ b/ports/stm32/boards/PYBV3/mpconfigboard.h @@ -44,7 +44,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -56,7 +56,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 #define MICROPY_HW_CAN2_TX (pin_B13) // Y6 diff --git a/ports/stm32/boards/PYBV4/mpconfigboard.h b/ports/stm32/boards/PYBV4/mpconfigboard.h index c1c6075113..2bd569ecdf 100644 --- a/ports/stm32/boards/PYBV4/mpconfigboard.h +++ b/ports/stm32/boards/PYBV4/mpconfigboard.h @@ -41,7 +41,7 @@ #define MICROPY_HW_UART6_PORT (GPIOC) #define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) @@ -49,7 +49,7 @@ #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NAME "X" #define MICROPY_HW_SPI1_NSS (pin_A4) // X5 #define MICROPY_HW_SPI1_SCK (pin_A5) // X6 @@ -61,7 +61,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) // Y7 #define MICROPY_HW_SPI2_MOSI (pin_B15) // Y8 -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_NAME "YA" #define MICROPY_HW_CAN1_TX (pin_B9) // Y4 #define MICROPY_HW_CAN1_RX (pin_B8) // Y3 diff --git a/ports/stm32/boards/STM32F411DISC/mpconfigboard.h b/ports/stm32/boards/STM32F411DISC/mpconfigboard.h index 13172333b7..97da204612 100644 --- a/ports/stm32/boards/STM32F411DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F411DISC/mpconfigboard.h @@ -26,7 +26,7 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B9) //#define MICROPY_HW_I2C2_SCL (pin_B10) @@ -34,7 +34,7 @@ #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_A9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) diff --git a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h index 9b65f61743..95cab08c8f 100644 --- a/ports/stm32/boards/STM32F429DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F429DISC/mpconfigboard.h @@ -22,11 +22,11 @@ #define MICROPY_HW_UART2_TX (pin_D8) #define MICROPY_HW_UART2_RX (pin_D9) -// I2C busses +// I2C buses #define MICROPY_HW_I2C3_SCL (pin_A8) #define MICROPY_HW_I2C3_SDA (pin_C9) -// SPI busses +// SPI buses //#define MICROPY_HW_SPI1_NSS (pin_A4) //#define MICROPY_HW_SPI1_SCK (pin_A5) //#define MICROPY_HW_SPI1_MISO (pin_A6) @@ -52,7 +52,7 @@ //#define MICROPY_HW_SPI6_MISO (pin_G12) //#define MICROPY_HW_SPI6_MOSI (pin_G14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F439/mpconfigboard.h b/ports/stm32/boards/STM32F439/mpconfigboard.h index a4e1093445..702ef265bb 100644 --- a/ports/stm32/boards/STM32F439/mpconfigboard.h +++ b/ports/stm32/boards/STM32F439/mpconfigboard.h @@ -40,11 +40,11 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_A8) #define MICROPY_HW_I2C1_SDA (pin_C9) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -74,7 +74,7 @@ //#define MICROPY_HW_SPI6_MISO (pin_G12) //#define MICROPY_HW_SPI6_MOSI (pin_G14) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h index 3e4c8261cc..dbe52e6b10 100644 --- a/ports/stm32/boards/STM32F4DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F4DISC/mpconfigboard.h @@ -43,13 +43,13 @@ #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI1_NSS (pin_A4) #define MICROPY_HW_SPI1_SCK (pin_A5) #define MICROPY_HW_SPI1_MISO (pin_A6) @@ -59,7 +59,7 @@ #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h index 5004a8ecac..87cefb5017 100644 --- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h @@ -59,19 +59,19 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_A11) #define MICROPY_HW_SPI2_SCK (pin_A12) #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32F7DISC/mpconfigboard.h b/ports/stm32/boards/STM32F7DISC/mpconfigboard.h index b07f0a7b8f..cf7061902e 100644 --- a/ports/stm32/boards/STM32F7DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32F7DISC/mpconfigboard.h @@ -38,20 +38,20 @@ void STM32F7DISC_board_early_init(void); #define MICROPY_HW_UART_REPL PYB_UART_1 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B8) #define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C3_SCL (pin_H7) #define MICROPY_HW_I2C3_SDA (pin_H8) -// SPI +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_I0) #define MICROPY_HW_SPI2_SCK (pin_I1) #define MICROPY_HW_SPI2_MISO (pin_B14) #define MICROPY_HW_SPI2_MOSI (pin_B15) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) #define MICROPY_HW_CAN2_TX (pin_B13) diff --git a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h index ad62f761e5..58fb8ef144 100644 --- a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h @@ -50,19 +50,19 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_B6) #define MICROPY_HW_I2C1_SDA (pin_B7) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -// SPI busses +// SPI buses #define MICROPY_HW_SPI2_NSS (pin_D0) #define MICROPY_HW_SPI2_SCK (pin_D1) #define MICROPY_HW_SPI2_MISO (pin_D3) #define MICROPY_HW_SPI2_MOSI (pin_D4) -// CAN busses +// CAN buses #define MICROPY_HW_CAN1_TX (pin_B9) #define MICROPY_HW_CAN1_RX (pin_B8) diff --git a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h index 5d9fa25bc3..d4d78454af 100644 --- a/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h +++ b/ports/stm32/boards/STM32L496GDISC/mpconfigboard.h @@ -26,13 +26,13 @@ #define MICROPY_HW_UART_REPL PYB_UART_2 #define MICROPY_HW_UART_REPL_BAUD 115200 -// I2C busses +// I2C buses #define MICROPY_HW_I2C1_SCL (pin_G14) #define MICROPY_HW_I2C1_SDA (pin_G13) #define MICROPY_HW_I2C2_SCL (pin_H4) #define MICROPY_HW_I2C2_SDA (pin_B14) -// SPI busses +// SPI buses // -> To the arduino connector #define MICROPY_HW_SPI1_NSS (pin_A15) #define MICROPY_HW_SPI1_SCK (pin_A5) diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index eceb5b6e7a..1b8db2e3e6 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -294,7 +294,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the UART busses are: +/// The physical pins of the UART buses are: /// /// - `UART(4)` is on `XA`: `(TX, RX) = (X1, X2) = (PA0, PA1)` /// - `UART(1)` is on `XB`: `(TX, RX) = (X9, X10) = (PB6, PB7)` diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index ee8b498a13..f0bd38333d 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -660,7 +660,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, size_t n_args, co /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the I2C busses are: +/// The physical pins of the I2C buses are: /// /// - `I2C(1)` is on the X position: `(SCL, SDA) = (X9, X10) = (PB6, PB7)` /// - `I2C(2)` is on the Y position: `(SCL, SDA) = (Y9, Y10) = (PB10, PB11)` diff --git a/ports/stm32/pyb_spi.c b/ports/stm32/pyb_spi.c index cc9dd11636..99a1cd77b4 100644 --- a/ports/stm32/pyb_spi.c +++ b/ports/stm32/pyb_spi.c @@ -125,7 +125,7 @@ STATIC mp_obj_t pyb_spi_init_helper(const pyb_spi_obj_t *self, size_t n_args, co // the bus, if any). If extra arguments are given, the bus is initialised. // See `init` for parameters of initialisation. // -// The physical pins of the SPI busses are: +// The physical pins of the SPI buses are: // - `SPI(1)` is on the X position: `(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)` // - `SPI(2)` is on the Y position: `(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)` // diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index f8ab791898..d3b3a784e8 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -31,7 +31,7 @@ #include "py/mphal.h" #include "spi.h" -// Possible DMA configurations for SPI busses: +// Possible DMA configurations for SPI buses: // SPI1_TX: DMA2_Stream3.CHANNEL_3 or DMA2_Stream5.CHANNEL_3 // SPI1_RX: DMA2_Stream0.CHANNEL_3 or DMA2_Stream2.CHANNEL_3 // SPI2_TX: DMA1_Stream4.CHANNEL_0 diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c index 471b40ee01..6373047b00 100644 --- a/ports/teensy/uart.c +++ b/ports/teensy/uart.c @@ -302,7 +302,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, uint n_args, const mp /// the bus, if any). If extra arguments are given, the bus is initialised. /// See `init` for parameters of initialisation. /// -/// The physical pins of the UART busses are: +/// The physical pins of the UART buses are: /// /// - `UART(4)` is on `XA`: `(TX, RX) = (X1, X2) = (PA0, PA1)` /// - `UART(1)` is on `XB`: `(TX, RX) = (X9, X10) = (PB6, PB7)` From 04927dfaca06d68a35ff1a5700a5e4eb283b5f2d Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 14 Nov 2020 18:54:26 +1100 Subject: [PATCH 132/349] tools/mpy_ld.py: Support R_X86_64_GOTPCREL reloc for x86-64 arch. This can be treated by the linker the same as R_X86_64_REX_GOTPCRELX, according to https://reviews.llvm.org/D18301. Signed-off-by: Damien George --- tools/mpy_ld.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 774966a7f6..8522499438 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -73,6 +73,7 @@ R_XTENSA_SLOT0_OP = 20 R_ARM_BASE_PREL = 25 # aka R_ARM_GOTPC R_ARM_GOT_BREL = 26 # aka R_ARM_GOT32 R_ARM_THM_JUMP24 = 30 +R_X86_64_GOTPCREL = 9 R_X86_64_REX_GOTPCRELX = 42 R_386_GOT32X = 43 @@ -132,7 +133,7 @@ ARCH_DATA = { | MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, 2, 8, - (R_X86_64_REX_GOTPCRELX,), + (R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX), asm_jump_x86, ), "armv7m": ArchData( @@ -536,7 +537,10 @@ def do_relocation_text(env, text_addr, r): # Relcation pointing to GOT reloc = addr = env.got_entries[s.name].offset - elif env.arch.name == "EM_X86_64" and r_info_type == R_X86_64_REX_GOTPCRELX: + elif env.arch.name == "EM_X86_64" and r_info_type in ( + R_X86_64_GOTPCREL, + R_X86_64_REX_GOTPCRELX, + ): # Relcation pointing to GOT got_entry = env.got_entries[s.name] addr = env.got_section.addr + got_entry.offset From f49d47c167ce97b48ff3e9cbbc016b09664390f5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Nov 2020 23:37:05 +1100 Subject: [PATCH 133/349] py/asmx64: Support use of top 8 regs in src_r64 argument. Signed-off-by: Damien George --- py/asmx64.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/py/asmx64.c b/py/asmx64.c index fd64eaf98b..62df5c6d4a 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -285,31 +285,28 @@ void asm_x64_mov_r64_to_mem64(asm_x64_t *as, int src_r64, int dest_r64, int dest } void asm_x64_mov_mem8_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_2(as, 0x0f, OPCODE_MOVZX_RM8_TO_R64); } else { - asm_x64_write_byte_3(as, REX_PREFIX | REX_R, 0x0f, OPCODE_MOVZX_RM8_TO_R64); + asm_x64_write_byte_3(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), 0x0f, OPCODE_MOVZX_RM8_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } void asm_x64_mov_mem16_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_2(as, 0x0f, OPCODE_MOVZX_RM16_TO_R64); } else { - asm_x64_write_byte_3(as, REX_PREFIX | REX_R, 0x0f, OPCODE_MOVZX_RM16_TO_R64); + asm_x64_write_byte_3(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), 0x0f, OPCODE_MOVZX_RM16_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } void asm_x64_mov_mem32_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { - assert(src_r64 < 8); - if (dest_r64 < 8) { + if (src_r64 < 8 && dest_r64 < 8) { asm_x64_write_byte_1(as, OPCODE_MOV_RM64_TO_R64); } else { - asm_x64_write_byte_2(as, REX_PREFIX | REX_R, OPCODE_MOV_RM64_TO_R64); + asm_x64_write_byte_2(as, REX_PREFIX | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), OPCODE_MOV_RM64_TO_R64); } asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } From 5176a2d7325d941d8f2f41b31eab87b6e7a83f06 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Nov 2020 23:37:58 +1100 Subject: [PATCH 134/349] py/emitnative: Fix x86-64 emitter to generate correct 8/16-bit stores. Fixes issue #6643. Signed-off-by: Damien George --- py/emitnative.c | 4 ++-- tests/micropython/viper_misc2.py | 21 +++++++++++++++++++++ tests/micropython/viper_misc2.py.exp | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/micropython/viper_misc2.py create mode 100644 tests/micropython/viper_misc2.py.exp diff --git a/py/emitnative.c b/py/emitnative.c index 052a505911..425ba2d33e 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1769,7 +1769,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { int reg_index = REG_ARG_2; int reg_value = REG_ARG_3; emit_pre_pop_reg_flexible(emit, &vtype_base, ®_base, reg_index, reg_value); - #if N_X86 + #if N_X64 || N_X86 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) emit_pre_pop_reg(emit, &vtype_value, reg_value); #else @@ -1856,7 +1856,7 @@ STATIC void emit_native_store_subscr(emit_t *emit) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("can't store with '%q' index"), vtype_to_qstr(vtype_index)); } - #if N_X86 + #if N_X64 || N_X86 // special case: x86 needs byte stores to be from lower 4 regs (REG_ARG_3 is EDX) emit_pre_pop_reg(emit, &vtype_value, reg_value); #else diff --git a/tests/micropython/viper_misc2.py b/tests/micropython/viper_misc2.py new file mode 100644 index 0000000000..8f0be487d6 --- /dev/null +++ b/tests/micropython/viper_misc2.py @@ -0,0 +1,21 @@ +# Miscellaneous viper tests + +# Test correct use of registers in load and store +@micropython.viper +def expand(dest: ptr8, source: ptr8, length: int): + n = 0 + for x in range(0, length, 2): + c = source[x] + d = source[x + 1] + dest[n] = (c & 0xE0) | ((c & 0x1C) >> 1) + n += 1 + dest[n] = ((c & 3) << 6) | ((d & 0xE0) >> 4) + n += 1 + dest[n] = ((d & 0x1C) << 3) | ((d & 3) << 2) + n += 1 + + +source = b"\xaa\xaa\xff\xff" +dest = bytearray(len(source) // 2 * 3) +expand(dest, source, len(source)) +print(dest) diff --git a/tests/micropython/viper_misc2.py.exp b/tests/micropython/viper_misc2.py.exp new file mode 100644 index 0000000000..eff2f5e41d --- /dev/null +++ b/tests/micropython/viper_misc2.py.exp @@ -0,0 +1 @@ +bytearray(b'\xa4\x8aH\xee\xce\xec') From a96afae90f6e5d693173382561d06e583b0b5fa5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 May 2021 14:10:37 +1000 Subject: [PATCH 135/349] stm32/sdio: Fix case of SDIO DMA turning off mid transfer. The DMA driver will turn off DMA if it hasn't been used for an amount of time (to save power). The SDIO driver for cyw43 WLAN was not informing the DMA driver that it was using DMA and there was a chance that the DMA would turn off in the middle of an SDIO DMA transfer. The symptoms of this would be printing of SDIO error messages and a failure to communicate with the cyw43 WLAN module. This commit fixes this issue by changing the SDIO driver to use the dma_nohal_XXX API to initialise and start the DMA. Signed-off-by: Damien George --- ports/stm32/dma.c | 2 +- ports/stm32/sdio.c | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 4320315ba4..d4b41771b0 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -40,7 +40,7 @@ #define DMA_IDLE_TICK_MAX (8) // 8*8 = 64 msec #define DMA_IDLE_TICK(tick) (((tick) & ~(SYSTICK_DISPATCH_NUM_SLOTS - 1) & DMA_SYSTICK_MASK) == 0) -#define ENABLE_SDIO (MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD) +#define ENABLE_SDIO (MICROPY_HW_ENABLE_SDCARD || MICROPY_HW_ENABLE_MMCARD || MICROPY_PY_NETWORK_CYW43) typedef enum { dma_id_not_defined=-1, diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index dfd4092577..0291e3e81d 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -28,6 +28,7 @@ #include "py/mperrno.h" #include "py/mphal.h" +#include "dma.h" #include "pin.h" #include "pin_static_af.h" #include "pendsv.h" @@ -382,27 +383,21 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le } #if defined(STM32F7) - DMA2->LIFCR = 0x3f << 22; - DMA2_Stream3->FCR = 0x07; // ? - DMA2_Stream3->PAR = (uint32_t)&SDMMC->FIFO; if ((uint32_t)buf & 3) { printf("sdio_transfer_cmd53: buf=%p is not aligned for DMA\n", buf); return -MP_EINVAL; } - DMA2_Stream3->M0AR = (uint32_t)buf; - DMA2_Stream3->NDTR = ((len + block_size - 1) & ~(block_size - 1)) / 4; - DMA2_Stream3->CR = 4 << 25 // channel 4 - | 1 << 23 // MBURST INCR4 - | 1 << 21 // PBURST INCR4 - | 3 << 16 // PL very high - | 2 << 13 // MSIZE word - | 2 << 11 // PSIZE word - | 1 << 10 // MINC enabled - | 0 << 9 // PINC disabled - | write << 6 // DIR mem-to-periph - | 1 << 5 // PFCTRL periph is flow controller - | 1 << 0 // EN + uint32_t dma_config = + 2 << DMA_SxCR_MSIZE_Pos // MSIZE word + | 2 << DMA_SxCR_PSIZE_Pos // PSIZE word + | write << DMA_SxCR_DIR_Pos // DIR mem-to-periph + | 1 << DMA_SxCR_PFCTRL_Pos // PFCTRL periph is flow controller ; + uint32_t dma_src = (uint32_t)buf; + uint32_t dma_dest = (uint32_t)&SDMMC->FIFO; + uint32_t dma_len = ((len + block_size - 1) & ~(block_size - 1)) / 4; + dma_nohal_init(&dma_SDIO_0, dma_config); + dma_nohal_start(&dma_SDIO_0, dma_src, dma_dest, dma_len); #else SDMMC->IDMABASE0 = (uint32_t)buf; SDMMC->IDMACTRL = SDMMC_IDMA_IDMAEN; @@ -456,6 +451,9 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #else printf("sdio_transfer_cmd53: timeout wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif + if (sdmmc_dma) { + dma_nohal_deinit(&dma_SDIO_0); + } return -MP_ETIMEDOUT; } } @@ -468,6 +466,9 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #else printf("sdio_transfer_cmd53: error=%08lx wr=%d len=%u dma=%u buf_idx=%u STA=%08x SDMMC=%08x:%08x IDMA=%08x\n", sdmmc_error, write, (uint)len, (uint)dma, sdmmc_buf_cur - buf, (uint)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->DCTRL, (uint)SDMMC->IDMACTRL); #endif + if (sdmmc_dma) { + dma_nohal_deinit(&dma_SDIO_0); + } return -(0x1000000 | sdmmc_error); } @@ -476,6 +477,8 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le printf("sdio_transfer_cmd53: didn't transfer correct length: cur=%p top=%p\n", sdmmc_buf_cur, sdmmc_buf_top); return -MP_EIO; } + } else { + dma_nohal_deinit(&dma_SDIO_0); } return 0; From 748339b28126e69fd2dc2778b2a182901d0a4693 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 22:17:45 +1000 Subject: [PATCH 136/349] stm32/uart: Configure pull-up only on RX and CTS, not TX and RTS. RX and CTS are the input pins and pull-ups are enabled so they don't cause a problem if left unconnected. But the output pins don't need a pull up (they were originally all configured with pull up in commit 8f7491a109a555ca897ae49efe98f4cc2b080311). If needed, the pull-ups can be disabled in Python using machine.Pin after the UART is constructed. See issue #4369. Signed-off-by: Damien George --- ports/stm32/uart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index a2b69967b6..9f74416170 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -474,10 +474,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj, } uint32_t mode = MP_HAL_PIN_MODE_ALT; - uint32_t pull = MP_HAL_PIN_PULL_UP; for (uint i = 0; i < 4; i++) { if (pins[i] != NULL) { + // Configure pull-up on RX and CTS (the input pins). + uint32_t pull = (i & 1) ? MP_HAL_PIN_PULL_UP : MP_HAL_PIN_PULL_NONE; bool ret = mp_hal_pin_config_alt(pins[i], mode, pull, uart_fn, uart_unit); if (!ret) { return false; From ea81bcf1c0ddeb8be34192cbededecfa425c039b Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 May 2021 23:57:45 +1000 Subject: [PATCH 137/349] stm32/mboot: Leave bootloader from thread mode, not from IRQ. Leaving the bootloader from an IRQ (eg USB or I2C IRQ) will not work if MBOOT_LEAVE_BOOTLOADER_VIA_RESET is disabled, ie if mboot jumps directly to the application. This is because the CPU will still be in IRQ state when the application starts and IRQs of lower priority will be blocked. Fix this by setting a flag when the bootloader should finish, and exit the bootloader always from the main (top level) thread. This also improves the USB behaviour of mboot: it no longer abruptly disconnects when the manifest command is sent. Signed-off-by: Damien George --- ports/stm32/mboot/dfu.h | 2 ++ ports/stm32/mboot/main.c | 33 ++++++++++++++++----------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/ports/stm32/mboot/dfu.h b/ports/stm32/mboot/dfu.h index 73db3545d8..e867a3e22d 100644 --- a/ports/stm32/mboot/dfu.h +++ b/ports/stm32/mboot/dfu.h @@ -26,6 +26,7 @@ #ifndef MICROPY_INCLUDED_STM32_MBOOT_DFU_H #define MICROPY_INCLUDED_STM32_MBOOT_DFU_H +#include #include // DFU spec: https://www.usb.org/sites/default/files/DFU_1.1.pdf @@ -106,6 +107,7 @@ typedef struct _dfu_state_t { dfu_cmd_t cmd; dfu_status_t status; uint8_t error; + bool leave_dfu; uint16_t wBlockNum; uint16_t wLength; uint32_t addr; diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 3a0242a8d6..c1e1d59d23 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -106,8 +106,6 @@ static volatile uint32_t systick_ms; // Global dfu state dfu_context_t dfu_context SECTION_NOZERO_BSS; -static void do_reset(void); - uint32_t get_le32(const uint8_t *b) { return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24; } @@ -771,7 +769,7 @@ void i2c_slave_process_rx_end(i2c_slave_t *i2c) { memcpy(buf + 12 + sizeof(MICROPY_HW_MCU_NAME), MICROPY_HW_BOARD_NAME, sizeof(MICROPY_HW_BOARD_NAME) - 1); len = 12 + sizeof(MICROPY_HW_MCU_NAME) + sizeof(MICROPY_HW_BOARD_NAME) - 1; } else if (buf[0] == I2C_CMD_RESET && len == 0) { - do_reset(); + dfu_context.leave_dfu = true; } else if (buf[0] == I2C_CMD_GETLAYOUT && len == 0) { len = strlen(FLASH_LAYOUT_STR); memcpy(buf, FLASH_LAYOUT_STR, len); @@ -864,6 +862,7 @@ static void dfu_init(void) { dfu_context.cmd = DFU_CMD_NONE; dfu_context.status = DFU_STATUS_OK; dfu_context.error = 0; + dfu_context.leave_dfu = false; dfu_context.addr = 0x08000000; } @@ -931,7 +930,8 @@ static void dfu_handle_rx(int cmd, int arg, int len, const void *buf) { static void dfu_process(void) { if (dfu_context.state == DFU_STATE_MANIFEST) { - do_reset(); + // Set a flag to leave DFU mode from the main thread (here we are in an IRQ handler). + dfu_context.leave_dfu = true; } if (dfu_context.state == DFU_STATE_BUSY) { @@ -1412,17 +1412,6 @@ static void leave_bootloader(void) { NVIC_SystemReset(); } -static void do_reset(void) { - led_state_all(0); - mp_hal_delay_ms(50); - pyb_usbdd_shutdown(); - #if defined(MBOOT_I2C_SCL) - i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn); - #endif - mp_hal_delay_ms(50); - leave_bootloader(); -} - extern PCD_HandleTypeDef pcd_fs_handle; extern PCD_HandleTypeDef pcd_hs_handle; @@ -1561,7 +1550,7 @@ enter_bootloader: #if MBOOT_USB_RESET_ON_DISCONNECT bool has_connected = false; #endif - for (;;) { + while (!dfu_context.leave_dfu) { #if USE_USB_POLLING #if MBOOT_USB_AUTODETECT_PORT || MICROPY_HW_USB_MAIN_DEV == USB_PHY_FS_ID if (USB_OTG_FS->GINTSTS & USB_OTG_FS->GINTMSK) { @@ -1585,10 +1574,20 @@ enter_bootloader: has_connected = true; } if (has_connected && pyb_usbdd.hUSBDDevice.dev_state == USBD_STATE_SUSPENDED) { - do_reset(); + break; } #endif } + + // Shutdown and leave the bootloader. + led_state_all(0); + mp_hal_delay_ms(50); + pyb_usbdd_shutdown(); + #if defined(MBOOT_I2C_SCL) + i2c_slave_shutdown(MBOOT_I2Cx, I2Cx_EV_IRQn); + #endif + mp_hal_delay_ms(50); + leave_bootloader(); } void NMI_Handler(void) { From 247d7e2e8e7ec262a141b0fc4190a94cce8103ef Mon Sep 17 00:00:00 2001 From: Tobias Thyrrestrup Date: Tue, 18 May 2021 15:38:49 +0200 Subject: [PATCH 138/349] tools/pydfu.py: Remove default VID/PID values. As the new default behaviour, this allows PyDFU to be used with all devices, not just the ones matching a specific set of VID/PID values. But it's still possible to specify VID/PID if needed to narrow down the selection of the USB device. Signed-off-by: Tobias Thyrrestrup --- tools/pydfu.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/pydfu.py b/tools/pydfu.py index 42b4fa2da6..ea658d300b 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -23,10 +23,6 @@ import usb.core import usb.util import zlib -# VID/PID -__VID = 0x0483 -__PID = 0xDF11 - # USB request __TIMEOUT __TIMEOUT = 4000 @@ -112,10 +108,10 @@ def find_dfu_cfg_descr(descr): return None -def init(): +def init(**kwargs): """Initializes the found DFU device so that we can program it.""" global __dev, __cfg_descr - devices = get_dfu_devices(idVendor=__VID, idProduct=__PID) + devices = get_dfu_devices(**kwargs) if not devices: raise ValueError("No DFU device found") if len(devices) > 1: @@ -565,15 +561,13 @@ def cli_progress(addr, offset, size): def main(): """Test program for verifying this files functionality.""" global __verbose - global __VID - global __PID # Parse CMD args parser = argparse.ArgumentParser(description="DFU Python Util") parser.add_argument( "-l", "--list", help="list available DFU devices", action="store_true", default=False ) - parser.add_argument("--vid", help="USB Vendor ID", type=lambda x: int(x, 0), default=__VID) - parser.add_argument("--pid", help="USB Product ID", type=lambda x: int(x, 0), default=__PID) + parser.add_argument("--vid", help="USB Vendor ID", type=lambda x: int(x, 0), default=None) + parser.add_argument("--pid", help="USB Product ID", type=lambda x: int(x, 0), default=None) parser.add_argument( "-m", "--mass-erase", help="mass erase device", action="store_true", default=False ) @@ -588,14 +582,18 @@ def main(): __verbose = args.verbose - __VID = args.vid - __PID = args.pid + kwargs = {} + if args.vid: + kwargs["idVendor"] = args.vid + + if args.pid: + kwargs["idProduct"] = args.pid if args.list: - list_dfu_devices(idVendor=__VID, idProduct=__PID) + list_dfu_devices(**kwargs) return - init() + init(**kwargs) command_run = False if args.mass_erase: From a7a9f2fe897d2c4e3c18618c996460224df08114 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Thu, 20 May 2021 22:12:35 -0500 Subject: [PATCH 139/349] tools/ci.sh: Update zephyr docker image to v0.17.3. Updates the zephyr docker image and SDK to the latest versions. Signed-off-by: Maureen Helm --- tools/ci.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ci.sh b/tools/ci.sh index 33cf364ddd..57421ae242 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -479,14 +479,14 @@ function ci_windows_build { # ports/zephyr function ci_zephyr_setup { - docker pull zephyrprojectrtos/ci:v0.11.13 + docker pull zephyrprojectrtos/ci:v0.17.3 docker run --name zephyr-ci -d -it \ -v "$(pwd)":/micropython \ - -e ZEPHYR_SDK_INSTALL_DIR=/opt/sdk/zephyr-sdk-0.12.2 \ + -e ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-0.12.4 \ -e ZEPHYR_TOOLCHAIN_VARIANT=zephyr \ -e ZEPHYR_BASE=/zephyrproject/zephyr \ -w /micropython/ports/zephyr \ - zephyrprojectrtos/ci:v0.11.13 + zephyrprojectrtos/ci:v0.17.3 docker ps -a } From e61ac453dcabaeca2406f1fb6ef113522f341aa2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 May 2021 22:09:25 +1000 Subject: [PATCH 140/349] py/mkrules.cmake: Add MPY_LIB_DIR and BOARD_DIR to makemanifest call. So that the FROZEN_MANIFEST option in cmake works the same as make. Signed-off-by: Damien George --- py/mkrules.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/py/mkrules.cmake b/py/mkrules.cmake index f20240c62b..7589255b20 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -125,9 +125,13 @@ if(MICROPY_FROZEN_MANIFEST) MICROPY_MODULE_FROZEN_MPY=\(1\) ) + if(NOT MICROPY_LIB_DIR) + set(MICROPY_LIB_DIR ${MICROPY_DIR}/../micropython-lib) + endif() + add_custom_command( OUTPUT ${MICROPY_FROZEN_CONTENT} - COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/tools/makemanifest.py -o ${MICROPY_FROZEN_CONTENT} -v "MPY_DIR=${MICROPY_DIR}" -v "PORT_DIR=${MICROPY_PORT_DIR}" -b "${CMAKE_BINARY_DIR}" -f${MICROPY_CROSS_FLAGS} ${MICROPY_FROZEN_MANIFEST} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/tools/makemanifest.py -o ${MICROPY_FROZEN_CONTENT} -v "MPY_DIR=${MICROPY_DIR}" -v "MPY_LIB_DIR=${MICROPY_LIB_DIR}" -v "PORT_DIR=${MICROPY_PORT_DIR}" -v "BOARD_DIR=${MICROPY_BOARD_DIR}" -b "${CMAKE_BINARY_DIR}" -f${MICROPY_CROSS_FLAGS} ${MICROPY_FROZEN_MANIFEST} DEPENDS MICROPY_FORCE_BUILD ${MICROPY_QSTRDEFS_GENERATED} VERBATIM From 3b950ed2959c603ff30dd6052c157e7981c4d2d6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 May 2021 22:10:09 +1000 Subject: [PATCH 141/349] tools/ci.sh: Use FROZEN_MANIFEST in an esp32 build to test feature. This tests that FROZEN_MANIFEST works with cmake (on esp32 at least). Signed-off-by: Damien George --- tools/ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ci.sh b/tools/ci.sh index 57421ae242..7b38ce0df0 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -109,7 +109,7 @@ function ci_esp32_build { make ${MAKEOPTS} -C ports/esp32 submodules make ${MAKEOPTS} -C ports/esp32 make ${MAKEOPTS} -C ports/esp32 clean - make ${MAKEOPTS} -C ports/esp32 USER_C_MODULES=../../../examples/usercmodule/micropython.cmake + make ${MAKEOPTS} -C ports/esp32 USER_C_MODULES=../../../examples/usercmodule/micropython.cmake FROZEN_MANIFEST=$(pwd)/ports/esp32/boards/manifest.py if [ -d $IDF_PATH/components/esp32s2 ]; then make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S2 fi From 0aa01b0205adc7544315fed602029e792a235b2e Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 00:04:01 +1000 Subject: [PATCH 142/349] lib/mbedtls: Switch to currently latest commit of LTS branch v2.16. Signed-off-by: Damien George --- lib/mbedtls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mbedtls b/lib/mbedtls index 1b6a24f759..1bc2c9cb8b 160000 --- a/lib/mbedtls +++ b/lib/mbedtls @@ -1 +1 @@ -Subproject commit 1b6a24f759cefbb4a69ae9476885d7f42a847e3d +Subproject commit 1bc2c9cb8b8fe4659bd94b8ebba5a4c02029b7fa From ff5d39529c3bf331dd8171aaa24937b2650f40fd Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Fri, 21 Aug 2020 16:03:21 +0200 Subject: [PATCH 143/349] mimxrt: Implement machine.Pin class. - modified pin type from pin_obj_t to machine_pin_obj_t - created machine_pin.c - implemented basic version of make-pins.py to genertate pins.c/.h files automatically; the only alternate function currently supported is GPIO - added af.csv files for all supported MCUs - replaced pins.c/pins.h files with pin.csv for all boards - implemented on/off/high/low/value/init methods - Implemented IN/OUT/OPEN_DRAIN modes - modified LDFLAGS for DEBUG build to get usefull .elf file for debugging Signed-off-by: Philipp Ebensberger --- ports/mimxrt/Makefile | 41 ++- ports/mimxrt/README.md | 5 +- ports/mimxrt/board_init.c | 2 - .../boards/MIMXRT1010_EVK/mpconfigboard.h | 2 +- .../boards/MIMXRT1010_EVK/mpconfigboard.mk | 19 ++ ports/mimxrt/boards/MIMXRT1010_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv | 57 ++++ ports/mimxrt/boards/MIMXRT1010_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1011.ld | 2 +- ports/mimxrt/boards/MIMXRT1011_af.csv | 44 +++ .../boards/MIMXRT1020_EVK/mpconfigboard.h | 3 +- .../boards/MIMXRT1020_EVK/mpconfigboard.mk | 18 ++ ports/mimxrt/boards/MIMXRT1020_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv | 33 +++ ports/mimxrt/boards/MIMXRT1020_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1021_af.csv | 94 ++++++ .../boards/MIMXRT1050_EVK/mpconfigboard.h | 2 +- ports/mimxrt/boards/MIMXRT1050_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1050_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1052_af.csv | 125 ++++++++ .../boards/MIMXRT1060_EVK/mpconfigboard.h | 2 +- .../boards/MIMXRT1060_EVK/mpconfigboard.mk | 19 ++ ports/mimxrt/boards/MIMXRT1060_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1060_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1062_af.csv | 125 ++++++++ .../boards/MIMXRT1064_EVK/mpconfigboard.h | 2 +- ports/mimxrt/boards/MIMXRT1064_EVK/pins.c | 33 --- ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv | 51 ++++ ports/mimxrt/boards/MIMXRT1064_EVK/pins.h | 30 -- ports/mimxrt/boards/MIMXRT1064_af.csv | 125 ++++++++ ports/mimxrt/boards/TEENSY40/mpconfigboard.h | 2 +- ports/mimxrt/boards/TEENSY40/pins.c | 33 --- ports/mimxrt/boards/TEENSY40/pins.csv | 55 ++++ ports/mimxrt/boards/TEENSY40/pins.h | 30 -- ports/mimxrt/boards/make-pins.py | 259 +++++++++++++++++ ports/mimxrt/boards/mimxrt_prefix.c | 26 ++ ports/mimxrt/led.c | 6 +- ports/mimxrt/led.h | 2 +- ports/mimxrt/machine_pin.c | 273 ++++++++++++++++++ ports/mimxrt/modmachine.c | 2 + ports/mimxrt/mphalport.h | 4 + ports/mimxrt/pin.c | 106 ++++++- ports/mimxrt/pin.h | 106 +++++-- ports/mimxrt/tusb_port.c | 2 +- 46 files changed, 1659 insertions(+), 435 deletions(-) delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1010_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1011_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1020_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1021_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1050_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1052_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1060_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1062_af.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.c create mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv delete mode 100644 ports/mimxrt/boards/MIMXRT1064_EVK/pins.h create mode 100644 ports/mimxrt/boards/MIMXRT1064_af.csv delete mode 100644 ports/mimxrt/boards/TEENSY40/pins.c create mode 100644 ports/mimxrt/boards/TEENSY40/pins.csv delete mode 100644 ports/mimxrt/boards/TEENSY40/pins.h create mode 100644 ports/mimxrt/boards/make-pins.py create mode 100644 ports/mimxrt/boards/mimxrt_prefix.c create mode 100644 ports/mimxrt/machine_pin.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index 3a001182a0..0c893f9634 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -23,6 +23,16 @@ GIT_SUBMODULES = lib/tinyusb lib/nxp_driver MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) LD_FILES = boards/$(MCU_SERIES).ld $(TOP)/$(MCU_DIR)/gcc/$(MCU_SERIES)xxxxx_flexspi_nor.ld +MAKE_PINS = boards/make-pins.py +BOARD_PINS = $(BOARD_DIR)/pins.csv +AF_FILE = boards/$(MCU_SERIES)_af.csv +PREFIX_FILE = boards/mimxrt_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_gen.c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + # mcu driver cause following warnings #CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs CFLAGS += -Wno-error=unused-parameter @@ -49,12 +59,14 @@ CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ -D__START=main \ -DCPU_HEADER_H='<$(MCU_SERIES).h>' -LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref +LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref --print-memory-usage LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) # Tune for Debugging or Optimization ifeq ($(DEBUG),1) CFLAGS += -O0 -ggdb +LDFLAGS += --gc-sections +CFLAGS += -fdata-sections -ffunction-sections else CFLAGS += -Os -DNDEBUG LDFLAGS += --gc-sections @@ -95,8 +107,8 @@ SRC_C = \ tusb_port.c \ board_init.c \ $(BOARD_DIR)/flash_config.c \ - $(BOARD_DIR)/pins.c \ machine_led.c \ + machine_pin.c \ modutime.c \ modmachine.c \ mphalport.c \ @@ -116,15 +128,17 @@ SRC_S = lib/utils/gchelper_m3.s \ # List of sources for qstr extraction SRC_QSTR += \ machine_led.c \ + machine_pin.c \ modutime.c \ modmachine.c \ pin.c \ - $(BOARD_DIR)/pins.c \ + $(GEN_PINS_SRC) \ OBJ += $(PY_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) +OBJ += $(BUILD)/pins_gen.o # Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces @@ -142,4 +156,25 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(BUILD)/firmware.hex: $(BUILD)/firmware.elf $(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@ +# Making OBJ use an order-only depenedency on the generated pins.h file +# has the side effect of making the pins.h file before we actually compile +# any of the objects. The normal dependency generation will deal with the +# case when pins.h is modified. But when it doesn't exist, we don't know +# which source files might need it. +$(OBJ): | $(GEN_PINS_HDR) + +# With conditional pins, we may need to regenerate qstrdefs.h when config +# options change. +$(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h + +# Use a pattern rule here so that make will only call make-pins.py once to make +# both pins_gen.c and pins.h +$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE)\ + --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC) + +$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c + $(call compile_c) + include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt/README.md b/ports/mimxrt/README.md index a2b5cf79a1..c24939f478 100644 --- a/ports/mimxrt/README.md +++ b/ports/mimxrt/README.md @@ -5,10 +5,13 @@ Currently supports Teensy 4.0 and the i.MX RT1010 EVK board. Features: - REPL over USB VCP + - machine.Pin Known issues: - pyboard.py doesn't work with files larger than 64 bytes + - machine.Pin class currently does not support GPIOMUX option of + i.MX RT101x variants TODO: - Enable TCM - - Peripherals (pins, LED, Timers, etc) + - Peripherals (LED, Timers, etc) diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c index 9095c88048..0336cdf686 100644 --- a/ports/mimxrt/board_init.c +++ b/ports/mimxrt/board_init.c @@ -39,8 +39,6 @@ #include "clock_config.h" -#define LED_STATE_ON (0) - volatile uint32_t systick_ms = 0; const uint8_t dcd_data[] = { 0x00 }; diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h index eeddd0e021..5a89423b50 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (16 * 1024 * 1024) // i.MX RT1010 EVK has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_11) +#define MICROPY_HW_LED1_PIN (pin_GPIO_11) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk index e178545845..c5b5055324 100644 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/mpconfigboard.mk @@ -2,6 +2,25 @@ MCU_SERIES = MIMXRT1011 MCU_VARIANT = MIMXRT1011DAE5A JLINK_PATH = /media/RT1010-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = -USB +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c deleted file mode 100644 index e0397e09ed..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_11_af[] = { - PIN_AF(GPIOMUX_IO11, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_11 = PIN(GPIO_11, GPIO1, 5, GPIO_11_af); diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv new file mode 100644 index 0000000000..f7fdf39643 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.csv @@ -0,0 +1,57 @@ +D0,GPIO_09 +D1,GPIO_10 +D2,GPIO_AD_05 +D3,GPIO_AD_06 +D4,GPIO_08 +D5,GPIO_01 +D6,GPIO_AD_01 +D7,GPIO_AD_02 +D8,GPIO_SD_02 +D9,GPIO_03 +D10,GPIO_AD_05 +D11,GPIO_AD_04 +D12,GPIO_AD_03 +D13,GPIO_AD_06 +D14,GPIO_01 +D15,GPIO_02 +CUR_A,GPIO_AD_01 +CUR_B,GPIO_AD_02 +CUR_C,GPIO_AD_07 +VOLT_DCB,GPIO_AD_09 +CUR_DCB,GPIO_AD_10 +A0,GPIO_AD_07 +A1,GPIO_AD_09 +A2,GPIO_AD_10 +A3,GPIO_AD_14 +A4,GPIO_AD_01 +A5,GPIO_AD_02 +PWM_AT,GPIO_02 +PWM_AB,GPIO_01 +PWM_BT,GPIO_04 +PWM_BB,GPIO_03 +PWM_CT,GPIO_06 +PWM_CB,GPIO_05 +ENC_A,GPIO_AD_05 +ENC_B,GPIO_AD_06 +LED_GREEN,GPIO_11 +GPIO_01,GPIO_01 +GPIO_02,GPIO_02 +GPIO_03,GPIO_03 +GPIO_04,GPIO_04 +GPIO_05,GPIO_05 +GPIO_06,GPIO_06 +GPIO_08,GPIO_08 +GPIO_09,GPIO_09 +GPIO_10,GPIO_10 +GPIO_11,GPIO_11 +GPIO_AD_01,GPIO_AD_01 +GPIO_AD_02,GPIO_AD_02 +GPIO_AD_03,GPIO_AD_03 +GPIO_AD_04,GPIO_AD_04 +GPIO_AD_05,GPIO_AD_05 +GPIO_AD_06,GPIO_AD_06 +GPIO_AD_07,GPIO_AD_07 +GPIO_AD_09,GPIO_AD_09 +GPIO_AD_10,GPIO_AD_10 +GPIO_AD_14,GPIO_AD_14 +GPIO_SD_02,GPIO_SD_02 diff --git a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h deleted file mode 100644 index 99534932a1..0000000000 --- a/ports/mimxrt/boards/MIMXRT1010_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_11; diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index 0512c48a7f..9db30adee8 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -1,5 +1,5 @@ /* 24kiB stack. */ -__stack_size__ = 0x6000; +__stack_size__ = 0x4000; _estack = __StackTop; _sstack = __StackLimit; diff --git a/ports/mimxrt/boards/MIMXRT1011_af.csv b/ports/mimxrt/boards/MIMXRT1011_af.csv new file mode 100644 index 0000000000..11dd085463 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1011_af.csv @@ -0,0 +1,44 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_00,FLEXSPI_B_DQS,SAI3_MCLK,LPSPI2_PCS3,LPSPI1_PCS3,PIT_TRIGGER0,GPIO1_IO00,,,,,,,ALT5 +GPIO_01,SAI1_RX_BCLK,WDOG1_ANY,FLEXPWM1_PWM0_B,LPI2C1_SDA,KPP_ROW3,GPIO1_IO01,,,,,,,ALT5 +GPIO_02,SAI1_RX_SYNC,WDOG2_B,FLEXPWM1_PWM0_A,LPI2C1_SCL,KPP_COL3,GPIO1_IO02,,,,,,,ALT5 +GPIO_03,SAI1_RX_DATA0,GPT1_COMPARE3,FLEXPWM1_PWM1_B,,SPDIF_SR_CLK,GPIO1_IO03,,,,,,,ALT5 +GPIO_04,SAI1_TX_DATA0,GPT1_CAPTURE2,FLEXPWM1_PWM1_A,,SPDIF_IN,GPIO1_IO04,,,,,,,ALT5 +GPIO_05,SAI1_TX_DATA1,GPT1_COMPARE2,FLEXPWM1_PWM2_B,LPUART4_RXD,SPDIF_OUT,GPIO1_IO05,,,,,,,ALT0 +GPIO_06,SAI1_TX_BCLK,GPT1_CAPTURE1,FLEXPWM1_PWM2_A,LPUART4_TXD,SPDIF_EXT_CLK,GPIO1_IO06,,,,,,,ALT5 +GPIO_07,SAI1_TX_SYNC,GPT1_COMPARE1,FLEXPWM1_PWM3_B,LPUART3_RXD,SPDIF_LOCK,GPIO1_IO07,LPUART1_RTS_B,,,,,,ALT5 +GPIO_08,SAI1_MCLK,GPT1_CLK,FLEXPWM1_PWM3_A,LPUART3_TXD,FLEXIO1_IO00,GPIO1_IO08,LPUART1_CTS_B,,,,,,ALT5 +GPIO_09,LPUART1_RXD,WDOG1_B,FLEXSPI_A_SS1_B,LPI2C2_SDA,FLEXIO1_IO01,GPIO1_IO09,SPDIF_SR_CLK,,,,,,ALT5 +GPIO_10,LPUART1_TXD,LPI2C1_HREQ,EWM_OUT_B,LPI2C2_SCL,FLEXIO1_IO02,GPIO1_IO10,SPDIF_IN,,,,,,ALT5 +GPIO_11,LPUART3_RXD,LPI2C1_SDA,KPP_ROW0,FLEXSPI_B_SS1_B,FLEXIO1_IO03,GPIO1_IO11,SPDIF_OUT,ARM_TRACE3,,,,,ALT5 +GPIO_12,LPUART3_TXD,LPI2C1_SCL,KPP_COL0,USB_OTG1_OC,FLEXIO1_IO04,GPIO1_IO12,SPDIF_EXT_CLK,ARM_TRACE2,,,,,ALT5 +GPIO_13,LPUART2_RXD,LPSPI2_PCS2,KPP_ROW3,USB_OTG1_ID,FLEXIO1_IO05,GPIO1_IO13,SPDIF_LOCK,ARM_TRACE1,,,,,ALT5 +GPIO_AD_00,LPUART2_TXD,LPSPI1_PCS2,KPP_COL3,USB_OTG1_PWR,FLEXIO1_IO20,GPIO1_IO14,ARM_NMI,ARM_TRACE0,,,ADC1_IN0,,ALT5 +GPIO_AD_01,LPUART4_RXD,LPSPI2_PCS1,WDOG1_ANY,LPI2C2_SDA,MQS_LEFT,GPIO1_IO15,USB_OTG1_OC,ARM_TRACE_SWO,,,ADC1_IN1,,ALT5 +GPIO_AD_02,LPUART4_TXD,LPSPI1_PCS1,WDOG2_B,LPI2C2_SCL,MQS_RIGHT,GPIO1_IO16,,ARM_TRACE_CLK,,,ADC1_IN2,,ALT5 +GPIO_AD_03,LPSPI1_SDI,PIT_TRIGGER3,FLEXPWM1_PWM2_B,KPP_ROW2,GPT2_CLK,GPIO1_IO17,SNVS_VIO_5_B,JTAG_DE_B,,,ADC1_IN3,,ALT5 +GPIO_AD_04,LPSPI1_SDO,PIT_TRIGGER2,FLEXPWM1_PWM2_A,KPP_COL2,GPT2_COMPARE1,GPIO1_IO18,SNVS_VIO_5_CTL,,,,ADC1_IN4,,ALT5 +GPIO_AD_05,LPSPI1_PCS0,PIT_TRIGGER1,FLEXPWM1_PWM3_B,KPP_ROW1,GPT2_CAPTURE1,GPIO1_IO19,,,,,ADC1_IN5,,ALT5 +GPIO_AD_06,LPSPI1_SCK,PIT_TRIGGER0,FLEXPWM1_PWM3_A,KPP_COL1,GPT2_COMPARE2,GPIO1_IO20,LPI2C1_HREQ,,,,ADC1_IN6,,ALT5 +GPIO_AD_07,LPI2C2_SDA,LPUART3_RXD,ARM_CM7_RXEV,LPUART2_RTS_B,GPT2_CAPTURE2,GPIO1_IO21,OCOTP_FUSE_LATCHED,XBAR1_INOUT03,,,ADC1_IN7,,ALT5 +GPIO_AD_08,LPI2C2_SCL,LPUART3_TXD,ARM_CM7_TXEV,LPUART2_CTS_B,GPT2_COMPARE3,GPIO1_IO22,EWM_OUT_B,JTAG_TRSTB,,,ADC1_IN8,,ALT7 +GPIO_AD_09,LPSPI2_SDI,FLEXPWM1_PWM3_X,KPP_ROW2,ARM_TRACE_SWO,FLEXIO1_IO21,GPIO1_IO23,REF_CLK_32K,JTAG_TDO,,,ADC1_IN9,,ALT7 +GPIO_AD_10,LPSPI2_SDO,FLEXPWM1_PWM2_X,KPP_COL2,PIT_TRIGGER3,FLEXIO1_IO22,GPIO1_IO24,USB_OTG1_ID,JTAG_TDI,,,ADC1_IN10,,ALT7 +GPIO_AD_11,LPSPI2_PCS0,FLEXPWM1_PWM1_X,KPP_ROW1,PIT_TRIGGER2,FLEXIO1_IO23,GPIO1_IO25,WDOG1_B,JTAG_MOD,,,ADC1_IN11,,ALT7 +GPIO_AD_12,LPSPI2_SCK,FLEXPWM1_PWM0_X,KPP_COL1,PIT_TRIGGER1,FLEXIO1_IO24,GPIO1_IO26,USB_OTG1_PWR,JTAG_TCK,,,ADC1_IN12,,ALT7 +GPIO_AD_13,LPI2C1_SDA,LPUART3_RTS_B,KPP_ROW0,LPUART4_RTS_B,FLEXIO1_IO25,GPIO1_IO27,ARM_NMI,JTAG_TMS,,,ADC1_IN13,,ALT7 +GPIO_AD_14,LPI2C1_SCL,LPUART3_CTS_B,KPP_COL0,LPUART4_CTS_B,FLEXIO1_IO26,GPIO1_IO28,REF_CLK_24M,XBAR1_INOUT02,,,ADC1_IN14,,ALT5 +GPIO_SD_00,FLEXSPI_B_SS0_B,SAI3_TX_SYNC,ARM_CM7_RXEV,CCM_STOP,FLEXIO1_IO06,GPIO2_IO00,SRC_BT_CFG2,,,,,,ALT5 +GPIO_SD_01,FLEXSPI_B_DATA1,SAI3_TX_BCLK,FLEXPWM1_PWM0_B,CCM_CLKO2,FLEXIO1_IO07,GPIO2_IO01,SRC_BT_CFG1,,,,,,ALT5 +GPIO_SD_02,FLEXSPI_B_DATA2,SAI3_TX_DATA,FLEXPWM1_PWM0_A,CCM_CLKO1,FLEXIO1_IO08,GPIO2_IO02,SRC_BT_CFG0,,,,,,ALT5 +GPIO_SD_03,FLEXSPI_B_DATA0,SAI3_RX_DATA,FLEXPWM1_PWM1_B,CCM_REF_EN_B,FLEXIO1_IO09,GPIO2_IO03,SRC_BOOT_MODE1,,,,,,ALT6 +GPIO_SD_04,FLEXSPI_B_DATA3,SAI3_RX_SYNC,FLEXPWM1_PWM1_A,CCM_WAIT,FLEXIO1_IO10,GPIO2_IO04,SRC_BOOT_MODE0,,,,,,ALT6 +GPIO_SD_05,FLEXSPI_A_SS1_B,LPI2C1_SDA,LPSPI1_SDI,,FLEXIO1_IO11,GPIO2_IO05,,,,,,,ALT5 +GPIO_SD_06,FLEXSPI_A_SS0_B,LPI2C1_SCL,LPSPI1_SDO,,FLEXIO1_IO12,GPIO2_IO06,,,,,,,ALT5 +GPIO_SD_07,FLEXSPI_A_DATA1,LPI2C2_SDA,LPSPI1_PCS0,,FLEXIO1_IO13,GPIO2_IO07,,,,,,,ALT5 +GPIO_SD_08,FLEXSPI_A_DATA2,LPI2C2_SCL,LPSPI1_SCK,,FLEXIO1_IO14,GPIO2_IO08,,,,,,,ALT5 +GPIO_SD_09,FLEXSPI_A_DATA0,LPSPI2_SDI,LPUART2_RXD,,FLEXIO1_IO15,GPIO2_IO09,,,,,,,ALT5 +GPIO_SD_10,FLEXSPI_A_SCLK,LPSPI2_SDO,LPUART2_TXD,,FLEXIO1_IO16,GPIO2_IO10,,,,,,,ALT5 +GPIO_SD_11,FLEXSPI_A_DATA3,LPSPI2_SCK,LPUART1_RXD,,FLEXIO1_IO17,GPIO2_IO11,WDOG1_RST_B_DEB,,,,,,ALT5 +GPIO_SD_12,FLEXSPI_A_DQS,LPSPI2_PCS0,LPUART1_TXD,,FLEXIO1_IO18,GPIO2_IO12,WDOG2_RST_B_DEB,,,,,,ALT5 +GPIO_SD_13,FLEXSPI_B_SCLK,SAI3_RX_BCLK,ARM_CM7_TXEV,CCM_PMIC_RDY,FLEXIO1_IO19,GPIO2_IO13,SRC_BT_CFG3,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h index 8598f76bf1..d8c0f00e27 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.h @@ -4,6 +4,7 @@ #define BOARD_FLASH_SIZE (8 * 1024 * 1024) // i.MX RT1020 EVK has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_05) +// Todo: think about replacing the define with searching in the generated pins? +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_05) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk index f3b1689524..0f5bb967af 100644 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/mpconfigboard.mk @@ -2,6 +2,24 @@ MCU_SERIES = MIMXRT1021 MCU_VARIANT = MIMXRT1021DAG5A JLINK_PATH ?= /media/RT1020-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c deleted file mode 100644 index 946b6efca8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_AD_B0_05_af[] = { - PIN_AF(GPIO1_IO05, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_05 = PIN(GPIO_AD_B0_05, GPIO1, 5, GPIO_AD_B0_05_af); diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv new file mode 100644 index 0000000000..8420bbd821 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.csv @@ -0,0 +1,33 @@ +D0,GPIO_AD_B1_09 +D1,GPIO_AD_B1_08 +D2,GPIO_AD_B0_09 +D3,GPIO_AD_B0_07 +D4,GPIO_AD_B0_05 +D5,GPIO_AD_B0_06 +D6,GPIO_AD_B0_14 +D7,GPIO_AD_B1_06 +D8,GPIO_AD_B1_07 +D9,GPIO_AD_B0_15 +D10,GPIO_AD_B0_11 +D11,GPIO_AD_B0_12 +D12,GPIO_AD_B0_13 +D13,GPIO_AD_B0_10 +D14,GPIO_SD_B1_03 +D15,GPIO_SD_B1_02 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_12 +A3,GPIO_AD_B1_13 +A4,GPIO_AD_B1_15 +A5,GPIO_AD_B1_14 +RX,GPIO_AD_B1_09 +TX,GPIO_AD_B1_08 +SDA,GPIO_AD_B1_15 +SCL,GPIO_AD_B1_14 +I2C_SCL,GPIO_SD_B1_02 +I2C_SDA,GPIO_SD_B1_03 +SCK,GPIO_AD_B0_10 +SDI,GPIO_AD_B0_13 +SDO,GPIO_AD_B0_12 +CS,GPIO_AD_B0_11 +LED_GREEN,GPIO_AD_B0_05 \ No newline at end of file diff --git a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h deleted file mode 100644 index 158929911c..0000000000 --- a/ports/mimxrt/boards/MIMXRT1020_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_05; diff --git a/ports/mimxrt/boards/MIMXRT1021_af.csv b/ports/mimxrt/boards/MIMXRT1021_af.csv new file mode 100644 index 0000000000..668b415f0b --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1021_af.csv @@ -0,0 +1,94 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,JTAG_TMS,,,,,GPIO1_IO00,USBPHY1_TSTI_TX_EN,GPT1_COMPARE1,,,,,ALT0 +GPIO_AD_B0_01,JTAG_TCK,,,,,GPIO1_IO01,USBPHY1_TSTI_TX_HIZ,GPT1_CAPTURE2,,,,,ALT0 +GPIO_AD_B0_02,JTAG_MOD,,,,,GPIO1_IO02,USBPHY1_TSTI_TX_LS_MODE,GPT1_CAPTURE1,,,,,ALT0 +GPIO_AD_B0_03,JTAG_TDI,USDHC2_CD_B,WDOG1_B,SAI1_MCLK,USDHC1_WP,GPIO1_IO03,USB_OTG1_OC,CCM_PMIC_RDY,,,,,ALT0 +GPIO_AD_B0_04,JTAG_TDO,FLEXCAN1_TX,USDHC1_WP,TMR2_TIMER0,ENET_MDIO,GPIO1_IO04,USB_OTG1_PWR,EWM_OUT_B,,,,,ALT0 +GPIO_AD_B0_05,JTAG_TRSTB,FLEXCAN1_RX,USDHC1_CD_B,TMR2_TIMER1,ENET_MDC,GPIO1_IO05,USB_OTG1_ID,ARM_NMI,,,,,ALT0 +GPIO_AD_B0_06,PIT_TRIGGER0,MQS_RIGHT,LPUART1_TXD,TMR2_TIMER2,FLEXPWM2_PWMA3,GPIO1_IO06,REF_32K_OUT,,,,,,ALT5 +GPIO_AD_B0_07,PIT_TRIGGER1,MQS_LEFT,LPUART1_RXD,TMR2_TIMER3,FLEXPWM2_PWMB3,GPIO1_IO07,REF_24M_OUT,,,,,,ALT5 +GPIO_AD_B0_08,ENET_TX_CLK,LPI2C3_SCL,LPUART1_CTS_B,KPP_COL0,ENET_REF_CLK,GPIO1_IO08,ARM_CM7_TXEV,,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_09,ENET_RX_DATA1,LPI2C3_SDA,LPUART1_RTS_B,KPP_ROW0,,GPIO1_IO09,ARM_CM7_RXEV,,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_10,ENET_RX_DATA0,LPSPI1_SCK,LPUART5_TXD,KPP_COL1,FLEXPWM2_PWMA2,GPIO1_IO10,ARM_TRACE_CLK,,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_11,ENET_RX_EN,LPSPI1_PCS0,LPUART5_RXD,KPP_ROW1,FLEXPWM2_PWMB2,GPIO1_IO11,ARM_TRACE_SWO,,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_12,ENET_RX_ER,LPSPI1_SDO,LPUART3_CTS_B,KPP_COL2,FLEXPWM2_PWMA1,GPIO1_IO12,ARM_TRACE0,SNVS_VIO_5_CTL,,,ADC1_IN0,,ALT5 +GPIO_AD_B0_13,ENET_TX_EN,LPSPI1_SDI,LPUART3_RTS_B,KPP_ROW2,FLEXPWM2_PWMB1,GPIO1_IO13,,SNVS_VIO_5_B,,,ADC2_IN0,,ALT5 +GPIO_AD_B0_14,ENET_TX_DATA0,FLEXCAN2_TX,LPUART3_TXD,KPP_COL3,FLEXPWM2_PWMA0,GPIO1_IO14,,WDOG1_ANY,,,"ADC1_IN1,ADC2_IN1","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B0_15,ENET_TX_DATA1,FLEXCAN2_RX,LPUART3_RXD,KPP_ROW3,FLEXPWM2_PWMB0,GPIO1_IO15,,,,,"ADC1_IN2,ADC2_IN2","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_00,SEMC_RDY,FLEXSPI_A_DATA3,FLEXCAN2_TX,SAI1_MCLK,FLEXIO1_D15,GPIO1_IO16,ENET_1588_EVENT2_OUT,KPP_COL4,,,,ACMP1_IN2,ALT5 +GPIO_AD_B1_01,SEMC_CSX0,FLEXSPI_A_SCLK,FLEXCAN2_RX,SAI1_TX_BCLK,FLEXIO1_D14,GPIO1_IO17,ENET_1588_EVENT2_IN,KPP_ROW4,,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B1_02,SEMC_CSX1,FLEXSPI_A_DATA0,LPSPI4_SCK,SAI1_TX_SYNC,FLEXIO1_D13,GPIO1_IO18,ENET_1588_EVENT3_OUT,KPP_COL5,,,ADC2_IN3,ACMP3_IN2,ALT5 +GPIO_AD_B1_03,SEMC_CSX2,FLEXSPI_A_DATA2,LPSPI4_PCS0,SAI1_TX_DATA0,FLEXIO1_D12,GPIO1_IO19,ENET_1588_EVENT3_IN,KPP_ROW5,,,ADC1_IN4,ACMP4_IN2,ALT5 +GPIO_AD_B1_04,SEMC_CSX3,FLEXSPI_A_DATA1,LPSPI4_SDO,SAI1_RX_SYNC,FLEXIO1_D11,GPIO1_IO20,LPSPI1_PCS1,KPP_COL6,,,ADC2_IN4,ACMP1_IN3,ALT5 +GPIO_AD_B1_05,USDHC1_WP,FLEXSPI_A_SS0_B,LPSPI4_SDI,SAI1_RX_DATA0,FLEXIO1_D10,GPIO1_IO21,LPSPI1_PCS2,KPP_ROW6,,,"ADC1_IN5,ADC2_IN5",ACMP2_IN3,ALT5 +GPIO_AD_B1_06,USDHC1_RESET_B,FLEXPWM1_PWMA0,LPUART2_CTS_B,SAI1_RX_BCLK,FLEXIO1_D09,GPIO1_IO22,LPSPI1_PCS3,KPP_COL7,,,"ADC1_IN6,ADC2_IN6",ACMP3_IN3,ALT5 +GPIO_AD_B1_07,USDHC1_VSELECT,FLEXPWM1_PWMB0,LPUART2_RTS_B,SAI1_TX_DATA1,FLEXIO1_D08,GPIO1_IO23,LPSPI3_PCS3,KPP_ROW7,,,"ADC1_IN7,ADC2_IN7",ACMP4_IN3,ALT5 +GPIO_AD_B1_08,LPI2C2_SCL,FLEXPWM1_PWMA1,LPUART2_TXD,SAI1_TX_DATA2,FLEXIO1_D07,GPIO1_IO24,LPSPI3_PCS2,XBAR_INOUT12,,,"ADC1_IN8,ADC2_IN8",ACMP1_IN5,ALT5 +GPIO_AD_B1_09,LPI2C2_SDA,FLEXPWM1_PWMB1,LPUART2_RXD,SAI1_TX_DATA3,FLEXIO1_D06,GPIO1_IO25,LPSPI3_PCS1,XBAR_INOUT13,,,"ADC1_IN9,ADC2_IN9",ACMP2_IN5,ALT5 +GPIO_AD_B1_10,USB_OTG1_PWR,FLEXPWM1_PWMA2,LPUART4_TXD,USDHC1_CD_B,FLEXIO1_D05,GPIO1_IO26,GPT2_CAPTURE1,,,,"ADC1_IN10,ADC2_IN10",ACMP3_IN5,ALT5 +GPIO_AD_B1_11,USB_OTG1_ID,FLEXPWM1_PWMB2,LPUART4_RXD,USDHC1_WP,FLEXIO1_D04,GPIO1_IO27,GPT2_COMPARE1,,,,"ADC1_IN11,ADC2_IN11",ACMP4_IN5,ALT5 +GPIO_AD_B1_12,USB_OTG1_OC,ACMP1_OUT,LPSPI3_SCK,USDHC2_CD_B,FLEXIO1_D03,GPIO1_IO28,FLEXPWM1_PWMA3,,,,"ADC1_IN12,ADC2_IN12","ACMP1_IN6,ACMP1_OUT",ALT5 +GPIO_AD_B1_13,LPI2C1_HREQ,ACMP2_OUT,LPSPI3_PCS0,USDHC2_WP,FLEXIO1_D02,GPIO1_IO29,FLEXPWM1_PWMB3,,,,"ADC1_IN13,ADC2_IN13","ACMP2_IN6,ACMP2_OUT",ALT5 +GPIO_AD_B1_14,LPI2C1_SCL,ACMP3_OUT,LPSPI3_SDO,ENET_1588_EVENT0_OUT,FLEXIO1_D01,GPIO1_IO30,,,,,"ADC1_IN14,ADC2_IN14","ACMP3_IN6,ACMP3_OUT",ALT5 +GPIO_AD_B1_15,LPI2C1_SDA,ACMP4_OUT,LPSPI3_SDI,ENET_1588_EVENT0_IN,FLEXIO1_D00,GPIO1_IO31,,,,,"ADC1_IN15,ADC2_IN15","ACMP4_IN6,ACMP4_OUT",ALT5 +GPIO_EMC_00,SEMC_DA00,TMR2_TIMER0,LPUART4_CTS_B,SPDIF_SR_CLK,LPSPI2_SCK,GPIO2_IO00,FLEXCAN1_TX,PIT_TRIGGER2,,,,,ALT5 +GPIO_EMC_01,SEMC_DA01,TMR2_TIMER1,LPUART4_RTS_B,SPDIF_OUT,LPSPI2_PCS0,GPIO2_IO01,FLEXCAN1_RX,PIT_TRIGGER3,,,,,ALT5 +GPIO_EMC_02,SEMC_DA02,TMR2_TIMER2,LPUART4_TXD,SPDIF_LOCK,LPSPI2_SDO,GPIO2_IO02,LPI2C1_SCL,,,,,,ALT5 +GPIO_EMC_03,SEMC_DA03,TMR2_TIMER3,LPUART4_RXD,SPDIF_EXT_CLK,LPSPI2_SDI,GPIO2_IO03,LPI2C1_SDA,,,,,,ALT5 +GPIO_EMC_04,SEMC_DA04,XBAR_INOUT04,SPDIF_OUT,SAI2_TX_BCLK,FLEXIO1_D16,GPIO2_IO04,USBPHY1_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_05,SEMC_DA05,XBAR_INOUT05,SPDIF_IN,SAI2_TX_SYNC,FLEXIO1_D17,GPIO2_IO05,USBPHY1_TSTI_TX_HS_MODE,,,,,,ALT5 +GPIO_EMC_06,SEMC_DA06,XBAR_INOUT06,LPUART3_TXD,SAI2_TX_DATA,FLEXIO1_D18,GPIO2_IO06,USBPHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_07,SEMC_DA07,XBAR_INOUT07,LPUART3_RXD,SAI2_RX_SYNC,FLEXIO1_D19,GPIO2_IO07,USBPHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,XBAR_INOUT08,FLEXCAN2_TX,SAI2_RX_DATA,FLEXIO1_D20,GPIO2_IO08,USBPHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_09,SEMC_WE,XBAR_INOUT09,FLEXCAN2_RX,SAI2_RX_BCLK,FLEXIO1_D21,GPIO2_IO09,USBPHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_10,SEMC_CAS,XBAR_INOUT10,LPI2C4_SDA,SAI1_TX_SYNC,LPSPI2_SCK,GPIO2_IO10,FLEXPWM2_PWMX0,,,,,,ALT5 +GPIO_EMC_11,SEMC_RAS,XBAR_INOUT11,LPI2C4_SCL,SAI1_TX_BCLK,LPSPI2_PCS0,GPIO2_IO11,FLEXPWM2_PWMX1,,,,,,ALT5 +GPIO_EMC_12,SEMC_CS0,XBAR_INOUT12,LPUART6_TXD,SAI1_TX_DATA0,LPSPI2_SDO,GPIO2_IO12,FLEXPWM2_PWMX2,,,,,,ALT5 +GPIO_EMC_13,SEMC_BA0,XBAR_INOUT13,LPUART6_RXD,SAI1_RX_DATA0,LPSPI2_SDI,GPIO2_IO13,FLEXPWM2_PWMX3,CCM_PMIC_RDY,,,,,ALT5 +GPIO_EMC_14,SEMC_BA1,XBAR_INOUT14,LPUART6_CTS_B,SAI1_RX_BCLK,LPSPI2_PCS1,GPIO2_IO14,FLEXCAN1_TX,,,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR10,XBAR_INOUT15,LPUART6_RTS_B,SAI1_RX_SYNC,WDOG1_B,GPIO2_IO15,FLEXCAN1_RX,,,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR00,,MQS_RIGHT,SAI2_MCLK,,GPIO2_IO16,SRC_BOOT_MODE0,,,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR01,,MQS_LEFT,SAI3_MCLK,,GPIO2_IO17,SRC_BOOT_MODE1,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR02,XBAR_INOUT16,LPI2C2_SDA,SAI1_RX_SYNC,FLEXIO1_D22,GPIO2_IO18,SRC_BT_CFG0,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR03,XBAR_INOUT17,LPI2C2_SCL,SAI1_RX_BCLK,FLEXIO1_D23,GPIO2_IO19,SRC_BT_CFG1,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR04,FLEXPWM1_PWMA3,LPUART2_CTS_B,SAI1_MCLK,FLEXIO1_D24,GPIO2_IO20,SRC_BT_CFG2,,,,,,ALT5 +GPIO_EMC_21,SEMC_ADDR05,FLEXPWM1_PWMB3,LPUART2_RTS_B,SAI1_RX_DATA0,FLEXIO1_D25,GPIO2_IO21,SRC_BT_CFG3,,,,,,ALT5 +GPIO_EMC_22,SEMC_ADDR06,FLEXPWM1_PWMA2,LPUART2_TXD,SAI1_TX_DATA3,FLEXIO1_D26,GPIO2_IO22,SRC_BT_CFG4,,,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR07,FLEXPWM1_PWMB2,LPUART2_RXD,SAI1_TX_DATA2,FLEXIO1_D27,GPIO2_IO23,SRC_BT_CFG5,,,,,,ALT5 +GPIO_EMC_24,SEMC_ADDR08,FLEXPWM1_PWMA1,LPUART8_CTS_B,SAI1_TX_DATA1,FLEXIO1_D28,GPIO2_IO24,SRC_BT_CFG6,,,,,,ALT5 +GPIO_EMC_25,SEMC_ADDR09,FLEXPWM1_PWMB1,LPUART8_RTS_B,SAI1_TX_DATA0,FLEXIO1_D29,GPIO2_IO25,SRC_BT_CFG7,,,,,,ALT5 +GPIO_EMC_26,SEMC_ADDR11,FLEXPWM1_PWMA0,LPUART8_TXD,SAI1_TX_BCLK,FLEXIO1_D30,GPIO2_IO26,SRC_BT_CFG8,,,,,,ALT5 +GPIO_EMC_27,SEMC_ADDR12,FLEXPWM1_PWMB0,LPUART8_RXD,SAI1_TX_SYNC,FLEXIO1_D31,GPIO2_IO27,SRC_BT_CFG9,,,,,,ALT5 +GPIO_EMC_28,SEMC_DQS,FLEXPWM2_PWMA3,XBAR_INOUT18,SAI3_MCLK,EWM_OUT_B,GPIO2_IO28,GPT2_CAPTURE2,FLEXPWM1_PWMX0,,,,,ALT5 +GPIO_EMC_29,SEMC_CKE,FLEXPWM2_PWMB3,XBAR_INOUT19,SAI3_RX_BCLK,WDOG2_RST_B_DEB,GPIO2_IO29,GPT2_COMPARE2,FLEXPWM1_PWMX1,,,,,ALT5 +GPIO_EMC_30,SEMC_CLK,FLEXPWM2_PWMA2,LPUART4_CTS_B,SAI3_RX_SYNC,WDOG1_RST_B_DEB,GPIO2_IO30,GPT2_COMPARE3,FLEXPWM1_PWMX2,,,,,ALT5 +GPIO_EMC_31,SEMC_DM1,FLEXPWM2_PWMB2,LPUART4_RTS_B,SAI3_RX_DATA,WDOG2_B,GPIO2_IO31,GPT2_CLK,FLEXPWM1_PWMX3,,,,,ALT5 +GPIO_EMC_32,SEMC_DA08,TMR1_TIMER0,LPUART4_TXD,SAI3_TX_DATA,LPSPI4_SCK,GPIO3_IO00,USBPHY1_TSTO_RX_FS_RXD,REF_24M_OUT,,,,,ALT5 +GPIO_EMC_33,SEMC_DA09,TMR1_TIMER1,LPUART4_RXD,SAI3_TX_BCLK,LPSPI4_PCS0,GPIO3_IO01,USBPHY1_TSTI_TX_DP,SRC_TESTER_ACK,,,,,ALT5 +GPIO_EMC_34,SEMC_DA10,TMR1_TIMER2,LPUART7_TXD,SAI3_TX_SYNC,LPSPI4_SDO,GPIO3_IO02,ENET_CRS,,,,,,ALT5 +GPIO_EMC_35,SEMC_DA11,TMR1_TIMER3,LPUART7_RXD,USDHC2_WP,LPSPI4_SDI,GPIO3_IO03,ENET_COL,,,,,,ALT5 +GPIO_EMC_36,SEMC_DA12,FLEXPWM2_PWMA1,LPUART5_CTS_B,CCM_PMIC_RDY,LPSPI4_PCS1,GPIO3_IO04,ENET_RX_CLK,USDHC1_WP,,,,,ALT5 +GPIO_EMC_37,SEMC_DA13,FLEXPWM2_PWMB1,LPUART5_RTS_B,MQS_RIGHT,LPSPI4_PCS2,GPIO3_IO05,ENET_RX_DATA3,USDHC1_VSELECT,,,,,ALT5 +GPIO_EMC_38,SEMC_DA14,FLEXPWM2_PWMA0,LPUART5_TXD,MQS_LEFT,LPSPI4_PCS3,GPIO3_IO06,ENET_RX_DATA2,USDHC1_CD_B,,,,,ALT5 +GPIO_EMC_39,SEMC_DA15,FLEXPWM2_PWMB0,LPUART5_RXD,USB_OTG1_OC,WDOG1_B,GPIO3_IO07,ENET_TX_ER,GPT1_CLK,,,,,ALT5 +GPIO_EMC_40,SEMC_CSX0,XBAR_INOUT18,SPDIF_OUT,USB_OTG1_ID,ENET_MDIO,GPIO3_IO08,ENET_TX_DATA3,GPT1_COMPARE3,,,,,ALT5 +GPIO_EMC_41,SEMC_RDY,XBAR_INOUT19,SPDIF_IN,USB_OTG1_PWR,ENET_MDC,GPIO3_IO09,ENET_TX_DATA2,GPT1_COMPARE2,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_DATA2,TMR1_TIMER0,SAI1_MCLK,SAI2_MCLK,LPI2C3_SCL,GPIO3_IO13,FLEXSPI_A_SS1_B,XBAR_INOUT14,,,,,ALT5 +GPIO_SD_B0_01,USDHC1_DATA3,TMR1_TIMER1,REF_24M_OUT,SAI2_RX_SYNC,LPI2C3_SDA,GPIO3_IO14,FLEXSPI_B_SS1_B,XBAR_INOUT15,,,,,ALT5 +GPIO_SD_B0_02,USDHC1_CMD,TMR1_TIMER2,LPUART7_CTS_B,SAI2_RX_BCLK,LPSPI1_SCK,GPIO3_IO15,ENET_MDIO,XBAR_INOUT16,,,,,ALT5 +GPIO_SD_B0_03,USDHC1_CLK,TMR1_TIMER3,LPUART7_RTS_B,SAI2_RX_DATA,LPSPI1_PCS0,GPIO3_IO16,ENET_MDC,,,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA0,FLEXCAN2_TX,LPUART7_TXD,SAI2_TX_DATA,LPSPI1_SDO,GPIO3_IO17,FLEXSPI_B_SS0_B,,,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA1,FLEXCAN2_RX,LPUART7_RXD,SAI2_TX_BCLK,LPSPI1_SDI,GPIO3_IO18,FLEXSPI_B_DQS,,,,,,ALT5 +GPIO_SD_B0_06,USDHC1_CD_B,USDHC1_RESET_B,REF_32K_OUT,SAI2_TX_SYNC,WDOG1_B,GPIO3_IO19,XBAR_INOUT17,,,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA2,FLEXSPI_B_DATA3,LPUART6_TXD,XBAR_INOUT10,FLEXCAN1_TX,GPIO3_IO20,,,,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA3,FLEXSPI_B_SCLK,LPUART6_RXD,FLEXSPI_A_SS1_B,FLEXCAN1_RX,GPIO3_IO21,,,,,,,ALT5 +GPIO_SD_B1_02,USDHC2_CMD,FLEXSPI_B_DATA0,LPUART8_TXD,LPI2C4_SCL,ENET_1588_EVENT1_OUT,GPIO3_IO22,CCM_CLKO1,,,,,,ALT5 +GPIO_SD_B1_03,USDHC2_CLK,FLEXSPI_B_DATA2,LPUART8_RXD,LPI2C4_SDA,ENET_1588_EVENT1_IN,GPIO3_IO23,CCM_CLKO2,,,,,,ALT5 +GPIO_SD_B1_04,USDHC2_DATA0,FLEXSPI_B_DATA1,ENET_TX_CLK,ENET_REF_CLK,EWM_OUT_B,GPIO3_IO24,CCM_WAIT,,,,,,ALT5 +GPIO_SD_B1_05,USDHC2_DATA1,FLEXSPI_A_DQS,ENET_RX_DATA1,SAI3_MCLK,FLEXSPI_B_SS0_B,GPIO3_IO25,CCM_PMIC_RDY,,,,,,ALT5 +GPIO_SD_B1_06,USDHC2_CD_B,FLEXSPI_A_DATA3,ENET_RX_DATA0,SAI3_TX_BCLK,LPSPI2_PCS0,GPIO3_IO26,CCM_STOP,,,,,,ALT5 +GPIO_SD_B1_07,USDHC2_RESET_B,FLEXSPI_A_SCLK,ENET_RX_EN,SAI3_TX_SYNC,LPSPI2_SCK,GPIO3_IO27,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,ENET_RX_ER,SAI3_TX_DATA,LPSPI2_SDO,GPIO3_IO28,,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA2,ENET_TX_EN,SAI3_RX_BCLK,LPSPI2_SDI,GPIO3_IO29,CCM_REF_EN_B,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA1,ENET_TX_DATA0,SAI3_RX_SYNC,LPSPI2_PCS2,GPIO3_IO30,SRC_SYSTEM_RESET,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_SS0_B,ENET_TX_DATA1,SAI3_RX_DATA,LPSPI2_PCS3,GPIO3_IO31,SRC_EARLY_RESET,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h index 5a733bbd97..2337496d2a 100644 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (64 * 1024 * 1024) // MIMXRT1050_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c deleted file mode 100644 index d5da9c6f99..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv new file mode 100644 index 0000000000..afd63d4f97 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h deleted file mode 100644 index baef51c6c8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1050_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1052_af.csv b/ports/mimxrt/boards/MIMXRT1052_af.csv new file mode 100644 index 0000000000..754bf4ab7b --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1052_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,,,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,,,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RST_B_DEB,,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,,,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,,,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,,,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,,,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,,,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,,,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,,,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,,,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,,,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,,,"ADC1_IN0,ADC2_IN0",ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP1_OUT,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,,,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP2_OUT,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,,,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP3_OUT,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,,,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,ACMP4_OUT,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,,,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RST_B_DEB,,,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_CM7_EVENT0,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,,,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_CM7_EVENT1,SAI1_RX_BCLK,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,,,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,,,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,,,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,,,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,,,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,,,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,,,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,,,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,,,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,,,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,,,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,,,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,,,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,,,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTI_TX_DP,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_PLL_CLK20DIV,,,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,,,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,,,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,,,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,,,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,,,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,,,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,CCM_REF_EN_B,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h index 8bd2a57917..c9e6d8bf2c 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (8 * 1024 * 1024) // MIMXRT1060_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk index b34169801b..32f87046b8 100644 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/mpconfigboard.mk @@ -2,6 +2,25 @@ MCU_SERIES = MIMXRT1062 MCU_VARIANT = MIMXRT1062DVJ6A JLINK_PATH ?= /media/RT1060-EVK/ +JLINK_COMMANDER_SCRIPT = $(BUILD)/script.jlink + + +ifdef JLINK_IP +JLINK_CONNECTION_SETTINGS = -IP $(JLINK_IP) +else +JLINK_CONNECTION_SETTINGS = -USB +endif + + +deploy_jlink: $(BUILD)/firmware.hex + $(Q)$(TOUCH) $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "ExitOnError 1" > $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "speed auto" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "r" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "st" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "loadfile \"$(realpath $(BUILD)/firmware.hex)\"" >> $(JLINK_COMMANDER_SCRIPT) + $(ECHO) "qc" >> $(JLINK_COMMANDER_SCRIPT) + $(JLINK_PATH)JLinkExe -device $(MCU_VARIANT) -if SWD $(JLINK_CONNECTION_SETTINGS) -CommanderScript $(JLINK_COMMANDER_SCRIPT) deploy: $(BUILD)/firmware.bin cp $< $(JLINK_PATH) diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c deleted file mode 100644 index d5da9c6f99..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv new file mode 100644 index 0000000000..afd63d4f97 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h deleted file mode 100644 index baef51c6c8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1060_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1062_af.csv b/ports/mimxrt/boards/MIMXRT1062_af.csv new file mode 100644 index 0000000000..9b83efeddc --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1062_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,FLEXCAN3_TX,,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,FLEXCAN3_RX,,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,FLEXCAN3_TX,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RESET_B_DEB,FLEXCAN3_RX,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,ENET2_1588_EVENT0_OUT,FLEXIO3_D00,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,ENET2_1588_EVENT0_IN,FLEXIO3_D01,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,GPT2_CLK,FLEXIO3_D02,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,GPT2_CAPTURE1,FLEXIO3_D03,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,GPT2_CAPTURE2,FLEXIO3_D04,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,GPT2_COMPARE1,FLEXIO3_D05,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,GPT2_COMPARE2,FLEXIO3_D06,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,GPT2_COMPARE3,FLEXIO3_D07,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,FLEXIO3_D08,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,FLEXIO3_D09,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,ENET2_1588_EVENT1_OUT,FLEXIO3_D10,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,ENET2_1588_EVENT1_IN,FLEXIO3_D11,ADC2_IN0,ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP_OUT00,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,ENET2_1588_EVENT2_OUT,FLEXIO3_D12,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP_OUT01,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,ENET2_1588_EVENT2_IN,FLEXIO3_D13,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP_OUT02,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,ENET2_1588_EVENT3_OUT,FLEXIO3_D14,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,ACMP_OUT03,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,ENET2_1588_EVENT3_IN,FLEXIO3_D15,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,ENET2_MDC,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,ENET2_MDIO,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,ENET2_1588_EVENT0_OUT,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RESET_B_DEB,,ENET2_1588_EVENT0_IN,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,ENET2_TDATA3,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,ENET2_TDATA2,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,ENET2_RX_CLK,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,ENET2_TX_ER,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,ENET2_RDATA3,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,ENET2_RDATA2,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,ENET2_CRS,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,ENET2_COL,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,ENET2_TDATA0,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,ENET2_TDATA1,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_TXEV,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,ENET2_TX_EN,,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_EVENT1,SAI1_RX_DATA0,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,ENET2_RX_ER,FLEXIO3_D16,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,ENET2_RDATA0,FLEXIO3_D17,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,ENET2_RDATA1,FLEXIO3_D18,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,ENET2_RX_EN,FLEXIO3_D19,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,GPT1_CLK,FLEXIO3_D20,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,GPT1_CAPTURE1,FLEXIO3_D21,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,GPT1_CAPTURE2,FLEXIO3_D22,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,GPT1_COMPARE1,FLEXIO3_D23,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,GPT1_COMPARE2,FLEXIO3_D24,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,GPT1_COMPARE3,FLEXIO3_D25,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,FLEXIO3_D26,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,FLEXIO3_D27,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,FLEXIO3_D28,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,SEMC_DQS4,FLEXIO3_D29,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,ENET2_TDATA0,FLEXIO3_D30,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,ENET2_TDATA1,FLEXIO3_D31,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,JTAG_DE_B,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTI_TX_DP,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,FLEXSPI2_B_SS1_B,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,FLEXSPI2_B_SS0_B,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_FS_RXD,,FLEXSPI2_B_DQS,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_SCLK,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_RX_FS_20DIV,,FLEXSPI2_B_DATA0,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_FS_ELCH,,FLEXSPI2_B_DATA1,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_FS_ON_DET,,FLEXSPI2_B_DATA2,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,FLEXSPI2_B_DATA3,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,FLEXSPI2_A_SS1_B,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,FLEXSPI2_A_DQS,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,FLEXSPI2_A_SS0_B,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,FLEXSPI2_A_SCLK,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,FLEXSPI2_A_DATA0,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,FLEXSPI2_A_DATA1,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,FLEXSPI2_A_DATA2,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,FLEXSPI2_A_DATA3,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,ENET2_TDATA0,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,ENET2_TDATA1,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,ENET2_TX_EN,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,ENET2_RX_ER,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,ENET2_RDATA0,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,ENET2_RDATA1,FLEXCAN3_TX,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,ENET2_RX_EN,FLEXCAN3_RX,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,ENET2_MDC,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,ENET2_MDIO,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,ENET2_TX_EN,,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,ENET2_RX_ER,,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,ENET2_RDATA0,,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,ENET2_RDATA1,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,ENET2_RX_EN,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,SAI3_RX_DATA,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,SAI3_TX_DATA,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,SAI3_TX_SYNC,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,SAI3_TX_BCLK,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,SAI3_MCLK,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,SAI3_RX_SYNC,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,SAI3_RX_BCLK,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h index e05c8824d2..3eddb41021 100644 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/mpconfigboard.h @@ -3,6 +3,6 @@ // MIMXRT1064_EVK has 1 user LED -#define MICROPY_HW_LED1_PIN (GPIO_AD_B0_09) +#define MICROPY_HW_LED1_PIN (pin_GPIO_AD_B0_09) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c deleted file mode 100644 index d5da9c6f99..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_AD_B0_09_af[] = { - PIN_AF(GPIO1_IO09, PIN_AF_MODE_ALT5, GPIO1, 0x10B0U), -}; - -pin_obj_t GPIO_AD_B0_09 = PIN(GPIO_AD_B0_09, GPIO1, 9, GPIO_AD_B0_09_af); diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv new file mode 100644 index 0000000000..afd63d4f97 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.csv @@ -0,0 +1,51 @@ +D0,GPIO_AD_B1_07 +D1,GPIO_AD_B1_06 +D2,GPIO_AD_B0_11 +D3,GPIO_AD_B1_08 +D4,GPIO_AD_B0_09 +D5,GPIO_AD_B0_10 +D6,GPIO_AD_B1_02 +D7,GPIO_AD_B1_03 +D8,GPIO_AD_B0_03 +D9,GPIO_AD_B0_02 +D10,GPIO_SD_B0_01 +D11,GPIO_SD_B0_02 +D12,GPIO_SD_B0_03 +D13,GPIO_SD_B0_00 +D14,GPIO_AD_B1_01 +D15,GPIO_AD_B1_00 +A0,GPIO_AD_B1_10 +A1,GPIO_AD_B1_11 +A2,GPIO_AD_B1_04 +A3,GPIO_AD_B1_05 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +RX,GPIO_AD_B1_07 +TX,GPIO_AD_B1_06 +SCL,GPIO_AD_B1_00 +SDA,GPIO_AD_B1_01 +SCK,GPIO_SD_B0_00 +SDI,GPIO_SD_B0_03 +SDO,GPIO_SD_B0_02 +CS,GPIO_SD_B0_01 +LED_GREEN,GPIO_AD_B0_09 +GPIO_AD_B1_07,GPIO_AD_B1_07 +GPIO_AD_B1_06,GPIO_AD_B1_06 +GPIO_AD_B0_11,GPIO_AD_B0_11 +GPIO_AD_B1_08,GPIO_AD_B1_08 +GPIO_AD_B0_09,GPIO_AD_B0_09 +GPIO_AD_B0_10,GPIO_AD_B0_10 +GPIO_AD_B1_02,GPIO_AD_B1_02 +GPIO_AD_B1_03,GPIO_AD_B1_03 +GPIO_AD_B0_03,GPIO_AD_B0_03 +GPIO_AD_B0_02,GPIO_AD_B0_02 +GPIO_SD_B0_01,GPIO_SD_B0_01 +GPIO_SD_B0_02,GPIO_SD_B0_02 +GPIO_SD_B0_03,GPIO_SD_B0_03 +GPIO_SD_B0_00,GPIO_SD_B0_00 +GPIO_AD_B1_01,GPIO_AD_B1_01 +GPIO_AD_B1_00,GPIO_AD_B1_00 +GPIO_AD_B1_10,GPIO_AD_B1_10 +GPIO_AD_B1_11,GPIO_AD_B1_11 +GPIO_AD_B1_04,GPIO_AD_B1_04 +GPIO_AD_B1_05,GPIO_AD_B1_05 diff --git a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h b/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h deleted file mode 100644 index baef51c6c8..0000000000 --- a/ports/mimxrt/boards/MIMXRT1064_EVK/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 NXP - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_AD_B0_09; diff --git a/ports/mimxrt/boards/MIMXRT1064_af.csv b/ports/mimxrt/boards/MIMXRT1064_af.csv new file mode 100644 index 0000000000..074a3f69ab --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1064_af.csv @@ -0,0 +1,125 @@ +Pad,ALT0, ALT1, ALT2, ALT3, ALT4, ALT5, ALT6, ALT7, ALT8, ALT9,ADC,ACMP,Default +GPIO_AD_B0_00,FLEXPWM2_PWM3_A,XBAR_INOUT14,REF_CLK_32K,USB_OTG2_ID,LPI2C1_SCLS,GPIO1_IO00,USDHC1_RESET_B,LPSPI3_SCK,,,,ACMP1_IN4,ALT5 +GPIO_AD_B0_01,FLEXPWM2_PWM3_B,XBAR_INOUT15,REF_CLK_24M,USB_OTG1_ID,LPI2C1_SDAS,GPIO1_IO01,EWM_OUT_B,LPSPI3_SOUT,,,,ACMP2_IN4,ALT5 +GPIO_AD_B0_02,FLEXCAN2_TX,XBAR_INOUT16,LPUART6_TXD,USB_OTG1_PWR,FLEXPWM1_PWM0_X,GPIO1_IO02,LPI2C1_HREQ,LPSPI3_SIN,,,,ACMP3_IN4,ALT5 +GPIO_AD_B0_03,FLEXCAN2_RX,XBAR_INOUT17,LPUART6_RXD,USB_OTG1_OC,FLEXPWM1_PWM1_X,GPIO1_IO03,REF_CLK_24M,LPSPI3_PCS0,,,,ACMP4_IN4,ALT5 +GPIO_AD_B0_04,SRC_BOOT_MODE0,MQS_RIGHT,ENET_TX_DATA3,SAI2_TX_SYNC,CSI_DATA09,GPIO1_IO04,PIT_TRIGGER0,LPSPI3_PCS1,,,,,ALT0 +GPIO_AD_B0_05,SRC_BOOT_MODE1,MQS_LEFT,ENET_TX_DATA2,SAI2_TX_BCLK,CSI_DATA08,GPIO1_IO05,XBAR_INOUT17,LPSPI3_PCS2,,,,,ALT0 +GPIO_AD_B0_06,"JTAG_TMS,SWD_DIO",GPT2_COMPARE1,ENET_RX_CLK,SAI2_RX_BCLK,CSI_DATA07,GPIO1_IO06,XBAR_INOUT18,LPSPI3_PCS3,,,,,ALT0 +GPIO_AD_B0_07,"JTAG_TCK,SWD_CLK",GPT2_COMPARE2,ENET_TX_ER,SAI2_RX_SYNC,CSI_DATA06,GPIO1_IO07,XBAR_INOUT19,ENET_1588_EVENT3_OUT,,,,,ALT0 +GPIO_AD_B0_08,JTAG_MOD,GPT2_COMPARE3,ENET_RX_DATA3,SAI2_RX_DATA,CSI_DATA05,GPIO1_IO08,XBAR_INOUT20,ENET_1588_EVENT3_IN,,,,,ALT0 +GPIO_AD_B0_09,JTAG_TDI,FLEXPWM2_PWM3_A,ENET_RX_DATA2,SAI2_TX_DATA,CSI_DATA04,GPIO1_IO09,XBAR_INOUT21,GPT2_CLK,,SEMC_DQS4,,,ALT0 +GPIO_AD_B0_10,JTAG_TDO,FLEXPWM1_PWM3_A,ENET_CRS,SAI2_MCLK,CSI_DATA03,GPIO1_IO10,XBAR_INOUT22,ENET_1588_EVENT0_OUT,FLEXCAN3_TX,ARM_TRACE_SWO,,,ALT0 +GPIO_AD_B0_11,JTAG_TRSTB,FLEXPWM1_PWM3_B,ENET_COL,WDOG1_B,CSI_DATA02,GPIO1_IO11,XBAR_INOUT23,ENET_1588_EVENT0_IN,FLEXCAN3_RX,SEMC_CLK6,,,ALT0 +GPIO_AD_B0_12,LPI2C4_SCL,CCM_PMIC_READY,LPUART1_TXD,WDOG2_B,FLEXPWM1_PWM2_X,GPIO1_IO12,ENET_1588_EVENT1_OUT,NMI_GLUE_NMI,,,ADC1_IN1,,ALT5 +GPIO_AD_B0_13,LPI2C4_SDA,GPT1_CLK,LPUART1_RXD,EWM_OUT_B,FLEXPWM1_PWM3_X,GPIO1_IO13,ENET_1588_EVENT1_IN,REF_CLK_24M,,,ADC1_IN2,ACMP1_IN2,ALT5 +GPIO_AD_B0_14,USB_OTG2_OC,XBAR_INOUT24,LPUART1_CTS_B,ENET_1588_EVENT0_OUT,CSI_VSYNC,GPIO1_IO14,FLEXCAN2_TX,WDOG1_ANY,FLEXCAN3_TX,,ADC1_IN3,ACMP2_IN2,ALT5 +GPIO_AD_B0_15,USB_OTG2_PWR,XBAR_INOUT25,LPUART1_RTS_B,ENET_1588_EVENT0_IN,CSI_HSYNC,GPIO1_IO15,FLEXCAN2_RX,WDOG1_RESET_B_DEB,FLEXCAN3_RX,,ADC1_IN4,ACMP3_IN2,ALT5 +GPIO_AD_B1_00,USB_OTG2_ID,TMR3_TIMER0,LPUART2_CTS_B,LPI2C1_SCL,WDOG1_B,GPIO1_IO16,USDHC1_WP,KPP_ROW7,ENET2_1588_EVENT0_OUT,FLEXIO3_D00,"ADC1_IN5,ADC2_IN5",ACMP4_IN2,ALT5 +GPIO_AD_B1_01,USB_OTG1_PWR,TMR3_TIMER1,LPUART2_RTS_B,LPI2C1_SDA,CCM_PMIC_READY,GPIO1_IO17,USDHC1_VSELECT,KPP_COL7,ENET2_1588_EVENT0_IN,FLEXIO3_D01,"ADC1_IN6,ADC2_IN6","ACMP1_IN0,ACMP2_IN0,ACMP3_IN0,ACMP4_IN0",ALT5 +GPIO_AD_B1_02,USB_OTG1_ID,TMR3_TIMER2,LPUART2_TXD,SPDIF_OUT,ENET_1588_EVENT2_OUT,GPIO1_IO18,USDHC1_CD_B,KPP_ROW6,GPT2_CLK,FLEXIO3_D02,"ADC1_IN7,ADC2_IN7",ACMP1_IN3,ALT5 +GPIO_AD_B1_03,USB_OTG1_OC,TMR3_TIMER3,LPUART2_RXD,SPDIF_IN,ENET_1588_EVENT2_IN,GPIO1_IO19,USDHC2_CD_B,KPP_COL6,GPT2_CAPTURE1,FLEXIO3_D03,"ADC1_IN8,ADC2_IN8",ACMP2_IN3,ALT5 +GPIO_AD_B1_04,FLEXSPI_B_DATA3,ENET_MDC,LPUART3_CTS_B,SPDIF_SR_CLK,CSI_PIXCLK,GPIO1_IO20,USDHC2_DATA0,KPP_ROW5,GPT2_CAPTURE2,FLEXIO3_D04,"ADC1_IN9,ADC2_IN9",ACMP3_IN3,ALT5 +GPIO_AD_B1_05,FLEXSPI_B_DATA2,ENET_MDIO,LPUART3_RTS_B,SPDIF_OUT,CSI_MCLK,GPIO1_IO21,USDHC2_DATA1,KPP_COL5,GPT2_COMPARE1,FLEXIO3_D05,"ADC1_IN10,ADC2_IN10",ACMP4_IN3,ALT5 +GPIO_AD_B1_06,FLEXSPI_B_DATA1,LPI2C3_SDA,LPUART3_TXD,SPDIF_LOCK,CSI_VSYNC,GPIO1_IO22,USDHC2_DATA2,KPP_ROW4,GPT2_COMPARE2,FLEXIO3_D06,"ADC1_IN11,ADC2_IN11","ACMP1_IN1,ACMP2_IN1,ACMP3_IN1,ACMP4_IN1",ALT5 +GPIO_AD_B1_07,FLEXSPI_B_DATA0,LPI2C3_SCL,LPUART3_RXD,SPDIF_EXT_CLK,CSI_HSYNC,GPIO1_IO23,USDHC2_DATA3,KPP_COL4,GPT2_COMPARE3,FLEXIO3_D07,"ADC1_IN12,ADC2_IN12",ACMP1_IN5,ALT5 +GPIO_AD_B1_08,FLEXSPI_A_SS1_B,FLEXPWM4_PWM0_A,FLEXCAN1_TX,CCM_PMIC_READY,CSI_DATA09,GPIO1_IO24,USDHC2_CMD,KPP_ROW3,,FLEXIO3_D08,"ADC1_IN13,ADC2_IN13",ACMP2_IN5,ALT5 +GPIO_AD_B1_09,FLEXSPI_A_DQS,FLEXPWM4_PWM1_A,FLEXCAN1_RX,SAI1_MCLK,CSI_DATA08,GPIO1_IO25,USDHC2_CLK,KPP_COL3,,FLEXIO3_D09,"ADC1_IN14,ADC2_IN14",ACMP3_IN5,ALT5 +GPIO_AD_B1_10,FLEXSPI_A_DATA3,WDOG1_B,LPUART8_TXD,SAI1_RX_SYNC,CSI_DATA07,GPIO1_IO26,USDHC2_WP,KPP_ROW2,ENET2_1588_EVENT1_OUT,FLEXIO3_D10,"ADC1_IN15,ADC2_IN15",ACMP4_IN5,ALT5 +GPIO_AD_B1_11,FLEXSPI_A_DATA2,EWM_OUT_B,LPUART8_RXD,SAI1_RX_BCLK,CSI_DATA06,GPIO1_IO27,USDHC2_RESET_B,KPP_COL2,ENET2_1588_EVENT1_IN,FLEXIO3_D11,"ADC1_IN0,ADC2_IN0",ACMP1_IN6,ALT5 +GPIO_AD_B1_12,FLEXSPI_A_DATA1,ACMP_OUT00,LPSPI3_PCS0,SAI1_RX_DATA0,CSI_DATA05,GPIO1_IO28,USDHC2_DATA4,KPP_ROW1,ENET2_1588_EVENT2_OUT,FLEXIO3_D12,ADC2_IN1,"ACMP1_OUT,ACMP2_IN6",ALT5 +GPIO_AD_B1_13,FLEXSPI_A_DATA0,ACMP_OUT01,LPSPI3_SIN,SAI1_TX_DATA0,CSI_DATA04,GPIO1_IO29,USDHC2_DATA5,KPP_COL1,ENET2_1588_EVENT2_IN,FLEXIO3_D13,ADC2_IN2,"ACMP2_OUT,ACMP3_IN6",ALT5 +GPIO_AD_B1_14,FLEXSPI_A_SCLK,ACMP_OUT02,LPSPI3_SOUT,SAI1_TX_BCLK,CSI_DATA03,GPIO1_IO30,USDHC2_DATA6,KPP_ROW0,ENET2_1588_EVENT3_OUT,FLEXIO3_D14,ADC2_IN3,"ACMP3_OUT,ACMP4_IN6",ALT5 +GPIO_AD_B1_15,FLEXSPI_A_SS0_B,AMCP_OUT03,LPSPI3_SCK,SAI1_TX_SYNC,CSI_DATA02,GPIO1_IO31,USDHC2_DATA7,KPP_COL0,ENET2_1588_EVENT3_IN,FLEXIO3_D15,ADC2_IN4,ACMP4_OUT,ALT5 +GPIO_B0_00,LCD_CLK,TMR1_TIMER0,MQS_RIGHT,LPSPI4_PCS0,FLEXIO2_D00,GPIO2_IO00,SEMC_CSX1,,ENET2_MDC,,,,ALT5 +GPIO_B0_01,LCD_ENABLE,TMR1_TIMER1,MQS_LEFT,LPSPI4_SIN,FLEXIO2_D01,GPIO2_IO01,SEMC_CSX2,,ENET2_MDIO,,,,ALT5 +GPIO_B0_02,LCD_HSYNC,TMR1_TIMER2,FLEXCAN1_TX,LPSPI4_SOUT,FLEXIO2_D02,GPIO2_IO02,SEMC_CSX3,,ENET2_1588_EVENT0_OUT,,,,ALT5 +GPIO_B0_03,LCD_VSYNC,TMR2_TIMER0,FLEXCAN1_RX,LPSPI4_SCK,FLEXIO2_D03,GPIO2_IO03,WDOG2_RESET_B_DEB,,ENET2_1588_EVENT0_IN,,,,ALT5 +GPIO_B0_04,LCD_DATA00,TMR2_TIMER1,LPI2C2_SCL,ARM_TRACE0,FLEXIO2_D04,GPIO2_IO04,SRC_BT_CFG00,,ENET2_TDATA3,,,,ALT5 +GPIO_B0_05,LCD_DATA01,TMR2_TIMER2,LPI2C2_SDA,ARM_TRACE1,FLEXIO2_D05,GPIO2_IO05,SRC_BT_CFG01,,ENET2_TDATA2,,,,ALT5 +GPIO_B0_06,LCD_DATA02,TMR3_TIMER0,FLEXPWM2_PWM0_A,ARM_TRACE2,FLEXIO2_D06,GPIO2_IO06,SRC_BT_CFG02,,ENET2_RX_CLK,,,,ALT5 +GPIO_B0_07,LCD_DATA03,TMR3_TIMER1,FLEXPWM2_PWM0_B,ARM_TRACE3,FLEXIO2_D07,GPIO2_IO07,SRC_BT_CFG03,,ENET2_TX_ER,,,,ALT5 +GPIO_B0_08,LCD_DATA04,TMR3_TIMER2,FLEXPWM2_PWM1_A,LPUART3_TXD,FLEXIO2_D08,GPIO2_IO08,SRC_BT_CFG04,,ENET2_RDATA3,,,,ALT5 +GPIO_B0_09,LCD_DATA05,TMR4_TIMER0,FLEXPWM2_PWM1_B,LPUART3_RXD,FLEXIO2_D09,GPIO2_IO09,SRC_BT_CFG05,,ENET2_RDATA2,,,,ALT5 +GPIO_B0_10,LCD_DATA06,TMR4_TIMER1,FLEXPWM2_PWM2_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",FLEXIO2_D10,GPIO2_IO10,SRC_BT_CFG06,,ENET2_CRS,,,,ALT5 +GPIO_B0_11,LCD_DATA07,TMR4_TIMER2,FLEXPWM2_PWM2_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",FLEXIO2_D11,GPIO2_IO11,SRC_BT_CFG07,,ENET2_COL,,,,ALT5 +GPIO_B0_12,LCD_DATA08,XBAR_INOUT10,ARM_TRACE_CLK,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXIO2_D12,GPIO2_IO12,SRC_BT_CFG08,,ENET2_TDATA0,,,,ALT5 +GPIO_B0_13,LCD_DATA09,XBAR_INOUT11,ARM_TRACE_SWO,SAI1_MCLK,FLEXIO2_D13,GPIO2_IO13,SRC_BT_CFG09,,ENET2_TDATA1,,,,ALT5 +GPIO_B0_14,LCD_DATA10,XBAR_INOUT12,ARM_EVENT0,SAI1_RX_SYNC,FLEXIO2_D14,GPIO2_IO14,SRC_BT_CFG10,,ENET2_TX_EN,ENET2_REF_CLK2,,,ALT5 +GPIO_B0_15,LCD_DATA11,XBAR_INOUT13,ARM_EVENT1,SAI1_RX_BCLK,FLEXIO2_D15,GPIO2_IO15,SRC_BT_CFG11,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_B1_00,LCD_DATA12,XBAR_INOUT14,LPUART4_TXD,SAI1_RX_DATA0,FLEXIO2_D16,GPIO2_IO16,FLEXPWM1_PWM3_A,,ENET2_RX_ER,FLEXIO3_D16,,,ALT5 +GPIO_B1_01,LCD_DATA13,XBAR_INOUT15,LPUART4_RXD,SAI1_TX_DATA0,FLEXIO2_D17,GPIO2_IO17,FLEXPWM1_PWM3_B,,ENET2_RDATA0,FLEXIO3_D17,,,ALT5 +GPIO_B1_02,LCD_DATA14,XBAR_INOUT16,LPSPI4_PCS2,SAI1_TX_BCLK,FLEXIO2_D18,GPIO2_IO18,FLEXPWM2_PWM3_A,,ENET2_RDATA1,FLEXIO3_D18,,,ALT5 +GPIO_B1_03,LCD_DATA15,XBAR_INOUT17,LPSPI4_PCS1,SAI1_TX_SYNC,FLEXIO2_D19,GPIO2_IO19,FLEXPWM2_PWM3_B,,ENET2_RX_EN,FLEXIO3_D19,,,ALT5 +GPIO_B1_04,LCD_DATA16,LPSPI4_PCS0,CSI_DATA15,ENET_RX_DATA0,FLEXIO2_D20,GPIO2_IO20,,,GPT1_CLK,FLEXIO3_D20,,,ALT5 +GPIO_B1_05,LCD_DATA17,LPSPI4_SIN,CSI_DATA14,ENET_RX_DATA1,FLEXIO2_D21,GPIO2_IO21,,,GPT1_CAPTURE1,FLEXIO3_D21,,,ALT5 +GPIO_B1_06,LCD_DATA18,LPSPI4_SOUT,CSI_DATA13,ENET_RX_EN,FLEXIO2_D22,GPIO2_IO22,,,GPT1_CAPTURE2,FLEXIO3_D22,,,ALT5 +GPIO_B1_07,LCD_DATA19,LPSPI4_SCK,CSI_DATA12,ENET_TX_DATA0,FLEXIO2_D23,GPIO2_IO23,,,GPT1_COMPARE1,FLEXIO3_D23,,,ALT5 +GPIO_B1_08,LCD_DATA20,TMR1_TIMER3,CSI_DATA11,ENET_TX_DATA1,FLEXIO2_D24,GPIO2_IO24,FLEXCAN2_TX,,GPT1_COMPARE2,FLEXIO3_D24,,,ALT5 +GPIO_B1_09,LCD_DATA21,TMR2_TIMER3,CSI_DATA10,ENET_TX_EN,FLEXIO2_D25,GPIO2_IO25,FLEXCAN2_RX,,GPT1_COMPARE3,FLEXIO3_D25,,,ALT5 +GPIO_B1_10,LCD_DATA22,TMR3_TIMER3,CSI_DATA00,ENET_TX_CLK,FLEXIO2_D26,GPIO2_IO26,ENET_REF_CLK,,,FLEXIO3_D26,,,ALT5 +GPIO_B1_11,LCD_DATA23,TMR4_TIMER3,CSI_DATA01,ENET_RX_ER,FLEXIO2_D27,GPIO2_IO27,LPSPI4_PCS3,,,FLEXIO3_D27,,,ALT5 +GPIO_B1_12,,LPUART5_TXD,CSI_PIXCLK,ENET_1588_EVENT0_IN,FLEXIO2_D28,GPIO2_IO28,USDHC1_CD_B,,,FLEXIO3_D28,,,ALT5 +GPIO_B1_13,WDOG1_B,LPUART5_RXD,CSI_VSYNC,ENET_1588_EVENT0_OUT,FLEXIO2_D29,GPIO2_IO29,USDHC1_WP,,,FLEXIO3_D29,,,ALT5 +GPIO_B1_14,ENET_MDC,FLEXPWM4_PWM2_A,CSI_HSYNC,XBAR_INOUT02,FLEXIO2_D30,GPIO2_IO30,USDHC1_VSELECT,,ENET2_TDATA0,FLEXIO3_D30,,,ALT5 +GPIO_B1_15,ENET_MDIO,FLEXPWM4_PWM3_A,CSI_MCLK,XBAR_INOUT03,FLEXIO2_D31,GPIO2_IO31,USDHC1_RESET_B,,ENET2_TDATA1,FLEXIO3_D31,,,ALT5 +GPIO_EMC_00,SEMC_DATA00,FLEXPWM4_PWM0_A,LPSPI2_SCK,XBAR_INOUT02,FLEXIO1_D00,GPIO4_IO0,USB_PHY1_TSTI_TX_LS_MODE,,,,,,ALT5 +GPIO_EMC_01,SEMC_DATA01,FLEXPWM4_PWM0_B,LPSPI2_PCS0,XBAR_INOUT03,FLEXIO1_D01,GPIO4_IO1,USB_PHY1_TSTI_TX_HS_MODE,JTAG_DE_B,,,,,ALT5 +GPIO_EMC_02,SEMC_DATA02,FLEXPWM4_PWM1_A,LPSPI2_SOUT,XBAR_INOUT04,FLEXIO1_D02,GPIO4_IO2,USB_PHY1_TSTI_TX_DN,,,,,,ALT5 +GPIO_EMC_03,SEMC_DATA03,FLEXPWM4_PWM1_B,LPSPI2_SIN,XBAR_INOUT05,FLEXIO1_D03,GPIO4_IO3,USB_PHY1_TSTO_RX_SQUELCH,,,,,,ALT5 +GPIO_EMC_04,SEMC_DATA04,FLEXPWM4_PWM2_A,SAI2_TX_DATA,XBAR_INOUT06,FLEXIO1_D04,GPIO4_IO4,USB_PHY1_TSTO_RX_DISCON_DET,,,,,,ALT5 +GPIO_EMC_05,SEMC_DATA05,FLEXPWM4_PWM2_B,SAI2_TX_SYNC,XBAR_INOUT07,FLEXIO1_D05,GPIO4_IO5,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_06,SEMC_DATA06,FLEXPWM2_PWM0_A,SAI2_TX_BCLK,XBAR_INOUT08,FLEXIO1_D06,GPIO4_IO6,USB_PHY2_TSTO_RX_FS_RXD,,,,,,ALT5 +GPIO_EMC_07,SEMC_DATA07,FLEXPWM2_PWM0_B,SAI2_MCLK,XBAR_INOUT09,FLEXIO1_D07,GPIO4_IO7,USB_PHY1_TSTO_RX_HS_RXD,,,,,,ALT5 +GPIO_EMC_08,SEMC_DM0,FLEXPWM2_PWM1_A,SAI2_RX_DATA,XBAR_INOUT17,FLEXIO1_D08,GPIO4_IO8,USB_PHY1_TSTO_RX_HS_,,,,,,ALT5 +GPIO_EMC_09,SEMC_ADDR00,FLEXPWM2_PWM1_B,SAI2_RX_SYNC,FLEXCAN2_TX,FLEXIO1_D09,GPIO4_IO9,USB_PHY1_TSTI_TX_EN,,FLEXSPI2_B_SS1_B,,,,ALT5 +GPIO_EMC_10,SEMC_ADDR01,FLEXPWM2_PWM2_A,SAI2_RX_BCLK,FLEXCAN2_RX,FLEXIO1_D10,GPIO4_IO10,USB_PHY1_TSTI_TX_HIZ,,FLEXSPI2_B_SS0_B,,,,ALT5 +GPIO_EMC_11,SEMC_ADDR02,FLEXPWM2_PWM2_B,LPI2C4_SDA,USDHC2_RESET_B,FLEXIO1_D11,GPIO4_IO11,USB_PHY2_TSTO_RX_HS_RXD,,FLEXSPI2_B_DQS,,,,ALT5 +GPIO_EMC_12,SEMC_ADDR03,XBAR_INOUT24,LPI2C4_SCL,USDHC1_WP,FLEXPWM1_PWM3_A,GPIO4_IO12,USB_PHY1_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_SCLK,,,,ALT5 +GPIO_EMC_13,SEMC_ADDR04,XBAR_INOUT25,LPUART3_TXD,MQS_RIGHT,FLEXPWM1_PWM3_B,GPIO4_IO13,USB_PHY2_TSTO_PLL_CLK20DIV,,FLEXSPI2_B_DATA0,,,,ALT5 +GPIO_EMC_14,SEMC_ADDR05,XBAR_INOUT19,LPUART3_RXD,MQS_LEFT,LPSPI2_PCS1,GPIO4_IO14,USB_PHY2_TSTO_RX_SQUELCH,,FLEXSPI2_B_DATA1,,,,ALT5 +GPIO_EMC_15,SEMC_ADDR06,XBAR_INOUT20,LPUART3_CTS_B,SPDIF_OUT,TMR3_TIMER0,GPIO4_IO15,USB_PHY2_TSTO_RX_DISCON_DET,,FLEXSPI2_B_DATA2,,,,ALT5 +GPIO_EMC_16,SEMC_ADDR07,XBAR_INOUT21,LPUART3_RTS_B,SPDIF_IN,TMR3_TIMER1,GPIO4_IO16,,,FLEXSPI2_B_DATA3,,,,ALT5 +GPIO_EMC_17,SEMC_ADDR08,FLEXPWM4_PWM3_A,LPUART4_CTS_B,FLEXCAN1_TX,TMR3_TIMER2,GPIO4_IO17,,,,,,,ALT5 +GPIO_EMC_18,SEMC_ADDR09,FLEXPWM4_PWM3_B,LPUART4_RTS_B,FLEXCAN1_RX,TMR3_TIMER3,GPIO4_IO18,SNVS_VIO_5_CTL,,,,,,ALT5 +GPIO_EMC_19,SEMC_ADDR11,FLEXPWM2_PWM3_A,LPUART4_TXD,ENET_RX_DATA1,TMR2_TIMER0,GPIO4_IO19,SNVS_VIO_5_B,,,,,,ALT5 +GPIO_EMC_20,SEMC_ADDR12,FLEXPWM2_PWM3_B,LPUART4_RXD,ENET_RX_DATA0,TMR2_TIMER1,GPIO4_IO20,,,,,,,ALT5 +GPIO_EMC_21,SEMC_BA0,FLEXPWM3_PWM3_A,LPI2C3_SDA,ENET_TX_DATA1,TMR2_TIMER2,GPIO4_IO21,,,,,,,ALT5 +GPIO_EMC_22,SEMC_BA1,FLEXPWM3_PWM3_B,LPI2C3_SCL,ENET_TX_DATA0,TMR2_TIMER3,GPIO4_IO22,,,FLEXSPI2_A_SS1_B,,,,ALT5 +GPIO_EMC_23,SEMC_ADDR10,FLEXPWM1_PWM0_A,LPUART5_TXD,ENET_RX_EN,GPT1_CAPTURE2,GPIO4_IO23,,,FLEXSPI2_A_DQS,,,,ALT5 +GPIO_EMC_24,SEMC_CAS,FLEXPWM1_PWM0_B,LPUART5_RXD,ENET_TX_EN,GPT1_CAPTURE1,GPIO4_IO24,,,FLEXSPI2_A_SS0_B,,,,ALT5 +GPIO_EMC_25,SEMC_RAS,FLEXPWM1_PWM1_A,LPUART6_TXD,ENET_TX_CLK,ENET_REF_CLK,GPIO4_IO25,,,FLEXSPI2_A_SCLK,,,,ALT5 +GPIO_EMC_26,SEMC_CLK,FLEXPWM1_PWM1_B,LPUART6_RXD,ENET_RX_ER,FLEXIO1_D12,GPIO4_IO26,,,FLEXSPI2_A_DATA0,,,,ALT5 +GPIO_EMC_27,SEMC_CKE,FLEXPWM1_PWM2_A,LPUART5_RTS_B,LPSPI1_SCK,FLEXIO1_D13,GPIO4_IO27,,,FLEXSPI2_A_DATA1,,,,ALT5 +GPIO_EMC_28,SEMC_WE,FLEXPWM1_PWM2_B,LPUART5_CTS_B,LPSPI1_SOUT,FLEXIO1_D14,GPIO4_IO28,,,FLEXSPI2_A_DATA2,,,,ALT5 +GPIO_EMC_29,SEMC_CS0,FLEXPWM3_PWM0_A,LPUART6_RTS_B,LPSPI1_SIN,FLEXIO1_D15,GPIO4_IO29,,,FLEXSPI2_A_DATA3,,,,ALT5 +GPIO_EMC_30,SEMC_DATA08,FLEXPWM3_PWM0_B,LPUART6_CTS_B,LPSPI1_PCS0,CSI_DATA23,GPIO4_IO30,,,ENET2_TDATA0,,,,ALT5 +GPIO_EMC_31,SEMC_DATA09,FLEXPWM3_PWM1_A,LPUART7_TXD,LPSPI1_PCS1,CSI_DATA22,GPIO4_IO31,,,ENET2_TDATA1,,,,ALT5 +GPIO_EMC_32,SEMC_DATA10,FLEXPWM3_PWM1_B,LPUART7_RXD,CCM_PMIC_READY,CSI_DATA21,GPIO3_IO18,,,ENET2_TX_EN,,,,ALT5 +GPIO_EMC_33,SEMC_DATA11,FLEXPWM3_PWM2_A,USDHC1_RESET_B,SAI3_RX_DATA,CSI_DATA20,GPIO3_IO19,,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_EMC_34,SEMC_DATA12,FLEXPWM3_PWM2_B,USDHC1_VSELECT,SAI3_RX_SYNC,CSI_DATA19,GPIO3_IO20,,,ENET2_RX_ER,,,,ALT5 +GPIO_EMC_35,SEMC_DATA13,XBAR_INOUT18,GPT1_COMPARE1,SAI3_RX_BCLK,CSI_DATA18,GPIO3_IO21,USDHC1_CD_B,,ENET2_RDATA0,,,,ALT5 +GPIO_EMC_36,SEMC_DATA14,XBAR_INOUT22,GPT1_COMPARE2,SAI3_TX_DATA,CSI_DATA17,GPIO3_IO22,USDHC1_WP,,ENET2_RDATA1,FLEXCAN3_TX,,,ALT5 +GPIO_EMC_37,SEMC_DATA15,XBAR_INOUT23,GPT1_COMPARE3,SAI3_MCLK,CSI_DATA16,GPIO3_IO23,USDHC2_WP,,ENET2_RX_EN,FLEXCAN3_RX,,,ALT5 +GPIO_EMC_38,SEMC_DM1,FLEXPWM1_PWM3_A,LPUART8_TXD,SAI3_TX_BCLK,CSI_FIELD,GPIO3_IO24,USDHC2_VSELECT,,ENET2_MDC,,,,ALT5 +GPIO_EMC_39,SEMC_DQS,FLEXPWM1_PWM3_B,LPUART8_RXD,SAI3_TX_SYNC,WDOG1_B,GPIO3_IO25,USDHC2_CD_B,,ENET2_MDIO,,,,ALT5 +GPIO_EMC_40,SEMC_RDY,GPT2_CAPTURE2,LPSPI1_PCS2,USB_OTG2_OC,ENET_MDC,GPIO3_IO26,USDHC2_RESET_B,,,SEMC_CLK5,,,ALT5 +GPIO_EMC_41,SEMC_CSX0,GPT2_CAPTURE1,LPSPI1_PCS3,USB_OTG2_PWR,ENET_MDIO,GPIO3_IO27,USDHC1_VSELECT,,,,,,ALT5 +GPIO_SD_B0_00,USDHC1_CMD,FLEXPWM1_PWM0_A,LPI2C3_SCL,XBAR_INOUT04,LPSPI1_SCK,GPIO3_IO12,FLEXSPI_A_SS1_B,,ENET2_TX_EN,SEMC_DQS4,,,ALT5 +GPIO_SD_B0_01,USDHC1_CLK,FLEXPWM1_PWM0_B,LPI2C3_SDA,XBAR_INOUT05,LPSPI1_PCS0,GPIO3_IO13,FLEXSPI_B_SS1_B,,ENET2_TX_CLK,ENET2_REF_CLK2,,,ALT5 +GPIO_SD_B0_02,USDHC1_DATA0,FLEXPWM1_PWM1_A,LPUART8_CTS_B,XBAR_INOUT06,LPSPI1_SOUT,GPIO3_IO14,,,ENET2_RX_ER,SEMC_CLK5,,,ALT5 +GPIO_SD_B0_03,USDHC1_DATA1,FLEXPWM1_PWM1_B,LPUART8_RTS_B,XBAR_INOUT07,LPSPI1_SIN,GPIO3_IO15,,,ENET2_RDATA0,SEMC_CLK6,,,ALT5 +GPIO_SD_B0_04,USDHC1_DATA2,FLEXPWM1_PWM2_A,LPUART8_TXD,XBAR_INOUT08,FLEXSPI_B_SS0_B,GPIO3_IO16,CCM_CLKO1,,ENET2_RDATA1,,,,ALT5 +GPIO_SD_B0_05,USDHC1_DATA3,FLEXPWM1_PWM2_B,LPUART8_RXD,XBAR_INOUT09,FLEXSPI_B_DQS,GPIO3_IO17,CCM_CLKO2,,ENET2_RX_EN,,,,ALT5 +GPIO_SD_B1_00,USDHC2_DATA3,FLEXSPI_B_DATA3,FLEXPWM1_PWM3_A,"SAI1_TX_DATA3,SAI1_RX_DATA1",LPUART4_TXD,GPIO3_IO00,,,SAI3_RX_DATA,,,,ALT5 +GPIO_SD_B1_01,USDHC2_DATA2,FLEXSPI_B_DATA2,FLEXPWM1_PWM3_B,"SAI1_TX_DATA2,SAI1_RX_DATA2",LPUART4_RXD,GPIO3_IO01,,,SAI3_TX_DATA,,,,ALT5 +GPIO_SD_B1_02,USDHC2_DATA1,FLEXSPI_B_DATA1,FLEXPWM2_PWM3_A,"SAI1_TX_DATA1,SAI1_RX_DATA3",FLEXCAN1_TX,GPIO3_IO02,CCM_WAIT,,SAI3_TX_SYNC,,,,ALT5 +GPIO_SD_B1_03,USDHC2_DATA0,FLEXSPI_B_DATA0,FLEXPWM2_PWM3_B,SAI1_MCLK,FLEXCAN1_RX,GPIO3_IO03,CCM_PMIC_READY,,SAI3_TX_BCLK,,,,ALT5 +GPIO_SD_B1_04,USDHC2_CLK,FLEXSPI_B_SCLK,LPI2C1_SCL,SAI1_RX_SYNC,FLEXSPI_A_SS1_B,GPIO3_IO04,CCM_STOP,,SAI3_MCLK,,,,ALT5 +GPIO_SD_B1_05,USDHC2_CMD,FLEXSPI_A_DQS,LPI2C1_SDA,SAI1_RX_BCLK,FLEXSPI_B_SS0_B,GPIO3_IO05,,,SAI3_RX_SYNC,,,,ALT5 +GPIO_SD_B1_06,USDHC2_RESET_B,FLEXSPI_A_SS0_B,LPUART7_CTS_B,SAI1_RX_DATA0,LPSPI2_PCS0,GPIO3_IO06,,,SAI3_RX_BCLK,,,,ALT5 +GPIO_SD_B1_07,SEMC_CSX1,FLEXSPI_A_SCLK,LPUART7_RTS_B,SAI1_TX_DATA0,LPSPI2_SCK,GPIO3_IO07,,,,,,,ALT5 +GPIO_SD_B1_08,USDHC2_DATA4,FLEXSPI_A_DATA0,LPUART7_TXD,SAI1_TX_BCLK,LPSPI2_SOUT,GPIO3_IO08,SEMC_CSX2,,,,,,ALT5 +GPIO_SD_B1_09,USDHC2_DATA5,FLEXSPI_A_DATA1,LPUART7_RXD,SAI1_TX_SYNC,LPSPI2_SIN,GPIO3_IO09,,,,,,,ALT5 +GPIO_SD_B1_10,USDHC2_DATA6,FLEXSPI_A_DATA2,LPUART2_RXD,LPI2C2_SDA,LPSPI2_PCS2,GPIO3_IO10,,,,,,,ALT5 +GPIO_SD_B1_11,USDHC2_DATA7,FLEXSPI_A_DATA3,LPUART2_TXD,LPI2C2_SCL,LPSPI2_PCS3,GPIO3_IO11,,,,,,,ALT5 diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h index 7d56478579..e3d7c6a129 100644 --- a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -4,6 +4,6 @@ #define BOARD_FLASH_SIZE (2 * 1024 * 1024) // Teensy 4.0 has 1 board LED -#define MICROPY_HW_LED1_PIN (GPIO_B0_03) +#define MICROPY_HW_LED1_PIN (pin_GPIO_B0_03) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) diff --git a/ports/mimxrt/boards/TEENSY40/pins.c b/ports/mimxrt/boards/TEENSY40/pins.c deleted file mode 100644 index c7bfc102d4..0000000000 --- a/ports/mimxrt/boards/TEENSY40/pins.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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 "pin.h" - -static pin_af_obj_t GPIO_B0_03_af[] = { - PIN_AF(GPIO2_IO03, PIN_AF_MODE_ALT5, GPIO2, 0x10B0U), -}; - -pin_obj_t GPIO_B0_03 = PIN(GPIO_B0_03, GPIO2, 3, GPIO_B0_03_af); diff --git a/ports/mimxrt/boards/TEENSY40/pins.csv b/ports/mimxrt/boards/TEENSY40/pins.csv new file mode 100644 index 0000000000..c9d7c9856d --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/pins.csv @@ -0,0 +1,55 @@ +D0,GPIO_AD_B0_03 +D1,GPIO_AD_B0_02 +D2,GPIO_EMC_04 +D3,GPIO_EMC_05 +D4,GPIO_EMC_06 +D5,GPIO_EMC_08 +D6,GPIO_B0_10 +D7,GPIO_B1_01 +D8,GPIO_B1_00 +D9,GPIO_B0_11 +D10,GPIO_B0_00 +D11,GPIO_B0_02 +D12,GPIO_B0_01 +D13,GPIO_B0_03 +D14,GPIO_AD_B1_02 +D15,GPIO_AD_B1_03 +D16,GPIO_AD_B1_07 +D17,GPIO_AD_B1_06 +D18,GPIO_AD_B1_01 +D19,GPIO_AD_B1_00 +D20,GPIO_AD_B1_10 +D21,GPIO_AD_B1_11 +D22,GPIO_AD_B1_08 +D23,GPIO_AD_B1_09 +D24,GPIO_AD_B0_12 +D25,GPIO_AD_B0_13 +D26,GPIO_AD_B1_14 +D27,GPIO_AD_B1_15 +D28,GPIO_EMC_32 +D29,GPIO_EMC_31 +D30,GPIO_EMC_37 +D31,GPIO_EMC_36 +D32,GPIO_B0_12 +D33,GPIO_EMC_07 +DAT1,GPIO_AD_B0_03 +DAT0,GPIO_AD_B0_02 +CLK,GPIO_AD_B0_01 +CMD,GPIO_ASD_B0_00 +DAT3,GPIO_SD_B0_05 +DAT2,GPIO_SD_B0_04 +A0,GPIO_AD_B1_02 +A1,GPIO_AD_B1_03 +A2,GPIO_AD_B1_07 +A3,GPIO_AD_B1_06 +A4,GPIO_AD_B1_01 +A5,GPIO_AD_B1_00 +A6,GPIO_AD_B1_10 +A7,GPIO_AD_B1_11 +A8,GPIO_AD_B1_08 +A9,GPIO_AD_B1_09 +A10,GPIO_AD_B0_12 +A11,GPIO_AD_B0_13 +A12,GPIO_AD_B1_14 +A13,GPIO_AD_B1_15 +LED,GPIO_B0_03 \ No newline at end of file diff --git a/ports/mimxrt/boards/TEENSY40/pins.h b/ports/mimxrt/boards/TEENSY40/pins.h deleted file mode 100644 index c0b6dcdfa9..0000000000 --- a/ports/mimxrt/boards/TEENSY40/pins.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Philipp Ebensberger - * - * 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. - */ - -// NOTE: pins.h shall only be included in in pin.h -// hence no include guards are needed since they will be provided by pin.h - -extern pin_obj_t GPIO_B0_03; diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py new file mode 100644 index 0000000000..5e5b81e31e --- /dev/null +++ b/ports/mimxrt/boards/make-pins.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +"""Creates the pin file for the MIMXRT10xx.""" + +from __future__ import print_function + +import argparse +import sys +import csv + +SUPPORTED_AFS = {"GPIO"} +MAX_AF = 10 # AF0 .. AF9 + + +def parse_pad(pad_str): + """Parses a string and returns a (port, gpio_bit) tuple.""" + if len(pad_str) < 4: + raise ValueError("Expecting pad name to be at least 4 characters") + if pad_str[:4] != "GPIO": + raise ValueError("Expecting pad name to start with GPIO") + return pad_str + + +def af_supported(af_str): + for supported_af in SUPPORTED_AFS: + if af_str.startswith(supported_af): + return True + else: + return False + + +class Pin(object): + """Holds the information associated with a pin.""" + + def __init__(self, pad, gpio, pin, idx=0): + self.idx = idx + self.name = pad + self.pad = pad + self.gpio = gpio + self.pin = pin + self.alt_fn = [] + self.adc_channel = 0 + self.board_pin = False + + def set_is_board_pin(self): + self.board_pin = True + + def is_board_pin(self): + return self.board_pin + + def parse_adc(self, adc_str): + pass + + def parse_af(self, af_idx, af_strs_in): + pass + + def add_af(self, af): + self.alt_fn.append(af) + + def print_pin_af(self): + if self.alt_fn: + print( + "static const machine_pin_af_obj_t pin_{0}_af[{1}] = {{".format( + self.name, len(self.alt_fn) + ) + ) + for af in self.alt_fn: + af.print() + print("};") + else: + raise ValueError("Pin '{}' has no alternative functions".format(self.name)) + + def print(self): + if self.alt_fn: + self.print_pin_af() + print( + "const machine_pin_obj_t pin_{0} = PIN({0}, {1}, {2}, pin_{3});\n".format( + self.name, self.gpio, int(self.pin), self.name + "_af" + ) + ) + else: + raise ValueError("Pin '{}' has no alternative functions".format(self.name)) + + def print_header(self, hdr_file): + pass + + +class AlternateFunction(object): + """Holds the information associated with a pins alternate function.""" + + def __init__(self, idx, af_str): + self.idx = idx + self.af_str = af_str + self.instance = self.af_str.split("_")[0] + + def print(self): + """Prints the C representation of this AF.""" + print( + " PIN_AF({0}, PIN_AF_MODE_ALT{1}, {2}, {3}),".format( + self.af_str, self.idx, self.instance, "0x10B0U" + ) + ) + + +class NamedPin(object): + def __init__(self, name, pad, idx): + self.name = name + self.pad = pad + self.idx = idx + + +class Pins(object): + def __init__(self): + self.cpu_pins = [] + self.board_pins = [] + + def find_pin_by_num(self, pin_num): + for pin in self.cpu_pins: + if pin.pin_num == pin_num: + return pin + + def find_pin_by_name(self, pad): + for pin in self.cpu_pins: + if pin.pad == pad: + return pin + + def parse_board_file(self, filename): + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + for row in rows: + pin = self.find_pin_by_name(row[1]) + if pin and row[0]: # Only add board pins that have a name + self.board_pins.append(NamedPin(row[0], pin.pad, pin.idx)) + + def parse_af_file(self, filename, pad_col, af_start_col): + af_end_col = af_start_col + MAX_AF + with open(filename, "r") as csvfile: + rows = csv.reader(csvfile) + header = next(rows) + for idx, row in enumerate(rows): + pad = row[pad_col] + gpio, pin = row[6].split("_") + pin_number = pin.lstrip("IO") + + pin = Pin(pad, gpio, pin_number, idx=idx) + + # Parse alternate functions + af_idx = 0 + for af_idx, af in enumerate(row[af_start_col:af_end_col]): + if af and af_supported(af): + pin.add_af(AlternateFunction(af_idx, af)) + + self.cpu_pins.append(pin) + + @staticmethod + def print_named(label, pins): + print("") + print( + "STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{".format(label) + ) + for pin in pins: + print( + " {{ MP_ROM_QSTR(MP_QSTR_{}), MP_ROM_PTR(&pin_{}) }},".format(pin.name, pin.pad) + ) + print("};") + print( + "MP_DEFINE_CONST_DICT(machine_pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);".format( + label, label + ) + ) + + def print(self): + # Print Pin Object declarations + for pin in self.cpu_pins: + pin.print() + + print("") + print("const machine_pin_obj_t* machine_pin_board_pins [] = {") + for pin in self.board_pins: + print(" &pin_{},".format(pin.pad)) + print("};") + print("const uint32_t num_board_pins = {:d};".format(len(self.board_pins))) + # Print Pin mapping dictionaries + self.print_named("cpu", self.cpu_pins) + self.print_named("board", self.board_pins) + print("") + + def print_header(self, hdr_filename): + with open(hdr_filename, "w") as hdr_file: + for pin in self.cpu_pins: + hdr_file.write("extern const machine_pin_obj_t pin_{};\n".format(pin.name)) + hdr_file.write("extern const machine_pin_obj_t* machine_pin_board_pins[];\n") + hdr_file.write("extern const uint32_t num_board_pins;\n") + hdr_file.write("extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict;\n") + hdr_file.write("extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;\n") + + +def main(): + parser = argparse.ArgumentParser( + prog="make-pins.py", + usage="%(prog)s [options] [command]", + description="Generate board specific pin file", + ) + parser.add_argument( + "-a", + "--af", + dest="af_filename", + help="Specifies the alternate function file for the chip", + default="mimxrt1021_af.csv", + ) + parser.add_argument( + "-b", + "--board", + dest="board_filename", + help="Specifies the board file", + default="MIMXRT1020_EVK/pins.csv", + ) + parser.add_argument( + "-p", + "--prefix", + dest="prefix_filename", + help="Specifies beginning portion of generated pins file", + default="mimxrt_prefix.c", + ) + parser.add_argument( + "-r", + "--hdr", + dest="hdr_filename", + help="Specifies name of generated pin header file", + default="build/pins.h", + ) + + pins = Pins() + + # test code + args = parser.parse_args() + # + + if args.af_filename: + print("// --af {:s}".format(args.af_filename)) + pins.parse_af_file(args.af_filename, 0, 1) + + if args.board_filename: + print("// --board {:s}".format(args.board_filename)) + pins.parse_board_file(args.board_filename) + + if args.hdr_filename: + print("// --hdr {:s}".format(args.hdr_filename)) + + if args.prefix_filename: + print("// --prefix {:s}".format(args.prefix_filename)) + with open(args.prefix_filename, "r") as prefix_file: + print(prefix_file.read()) + + pins.print() + pins.print_header(args.hdr_filename) + + +if __name__ == "__main__": + main() diff --git a/ports/mimxrt/boards/mimxrt_prefix.c b/ports/mimxrt/boards/mimxrt_prefix.c new file mode 100644 index 0000000000..59e338976e --- /dev/null +++ b/ports/mimxrt/boards/mimxrt_prefix.c @@ -0,0 +1,26 @@ +#include + +#include "py/obj.h" +#include "py/mphal.h" +#include "pin.h" + +#define PIN_AF(_name, _af_mode, _instance, _pad_config) \ + { \ + .base = { &machine_pin_af_type }, \ + .name = MP_QSTR_##_name, \ + .af_mode = (uint32_t)(_af_mode), \ + .instance = (void *)(_instance), \ + .pad_config = (uint32_t)(_pad_config), \ + } \ + +#define PIN(_name, _gpio, _pin, _af_list) \ + { \ + .base = { &machine_pin_type }, \ + .name = MP_QSTR_##_name, \ + .gpio = (_gpio), \ + .pin = (uint32_t)(_pin), \ + .muxRegister = (uint32_t)&(IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_##_name]), \ + .configRegister = (uint32_t)&(IOMUXC->SW_PAD_CTL_PAD[kIOMUXC_SW_PAD_CTL_PAD_##_name]), \ + .af_list_len = (size_t)(sizeof((_af_list)) / sizeof(machine_pin_af_obj_t)), \ + .af_list = (_af_list), \ + } \ diff --git a/ports/mimxrt/led.c b/ports/mimxrt/led.c index bec97dd8f7..cb9f985464 100644 --- a/ports/mimxrt/led.c +++ b/ports/mimxrt/led.c @@ -44,7 +44,7 @@ const machine_led_obj_t machine_led_obj[NUM_LEDS] = { void led_init(void) { // Turn off LEDs and initialize for (mp_int_t led = 0; led < NUM_LEDS; led++) { - const pin_obj_t *led_pin = machine_led_obj[led].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led].led_pin; gpio_pin_config_t pin_config = { .outputLogic = 1U, @@ -67,7 +67,7 @@ void led_state(machine_led_t led, int state) { return; } - const pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; if (state == 0) { // turn LED off @@ -83,7 +83,7 @@ void led_toggle(machine_led_t led) { return; } - const pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; + const machine_pin_obj_t *led_pin = machine_led_obj[led - 1].led_pin; mp_hal_pin_toggle(led_pin); } diff --git a/ports/mimxrt/led.h b/ports/mimxrt/led.h index 35418321d1..a0628e90ed 100644 --- a/ports/mimxrt/led.h +++ b/ports/mimxrt/led.h @@ -42,7 +42,7 @@ typedef enum { typedef struct _machine_led_obj_t { mp_obj_base_t base; mp_uint_t led_id; - const pin_obj_t *led_pin; + const machine_pin_obj_t *led_pin; } machine_led_obj_t; void led_init(void); diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c new file mode 100644 index 0000000000..583ee4a265 --- /dev/null +++ b/ports/mimxrt/machine_pin.c @@ -0,0 +1,273 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Philipp Ebensberger + * + * 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 "fsl_gpio.h" +#include "fsl_iomuxc.h" + +#include "py/runtime.h" +#include "py/mphal.h" +#include "pin.h" +#include "mphalport.h" + +// Local functions +STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); + +// Class Methods +STATIC void machine_pin_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind); +STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); +STATIC mp_obj_t machine_pin_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); + +// Instance Methods +STATIC mp_obj_t machine_pin_off(mp_obj_t self_in); +STATIC mp_obj_t machine_pin_on(mp_obj_t self_in); +STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t machine_pin_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); + +// Local data +enum { + PIN_INIT_ARG_MODE = 0, + PIN_INIT_ARG_PULL, + PIN_INIT_ARG_VALUE, + PIN_INIT_ARG_DRIVE, +}; + +// Pin mapping dictionaries +const mp_obj_type_t machine_pin_cpu_pins_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_cpu, + .locals_dict = (mp_obj_t)&machine_pin_cpu_pins_locals_dict, +}; + +const mp_obj_type_t machine_pin_board_pins_obj_type = { + { &mp_type_type }, + .name = MP_QSTR_board, + .locals_dict = (mp_obj_t)&machine_pin_board_pins_locals_dict, +}; + +STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + machine_pin_obj_t *self = self_in; + + if (n_args == 0) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self)); + } else { + mp_hal_pin_write(self, mp_obj_is_true(args[0])); + return mp_const_none; + } +} + +STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + [PIN_INIT_ARG_MODE] { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, + [PIN_INIT_ARG_PULL] { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + [PIN_INIT_ARG_VALUE] { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + [PIN_INIT_ARG_DRIVE] { MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PIN_DRIVE_POWER_3}}, + // TODO: Implement additional arguments + /* + { MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy + { MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},*/ + }; + + // Parse args + 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); + + // Get io mode + uint mode = args[PIN_INIT_ARG_MODE].u_int; + if (!IS_GPIO_MODE(mode)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode); + } + + // Handle configuration for GPIO + if ((mode == PIN_MODE_IN) || (mode == PIN_MODE_OUT) || (mode == PIN_MODE_OPEN_DRAIN)) { + gpio_pin_config_t pin_config; + const machine_pin_af_obj_t *af_obj; + uint32_t pad_config = 0UL; + uint8_t pull = PIN_PULL_DISABLED; + + // Generate pin configuration + if ((args[PIN_INIT_ARG_VALUE].u_obj != MP_OBJ_NULL) && (mp_obj_is_true(args[PIN_INIT_ARG_VALUE].u_obj))) { + pin_config.outputLogic = 1U; + } else { + pin_config.outputLogic = 0U; + } + pin_config.direction = mode == PIN_MODE_IN ? kGPIO_DigitalInput : kGPIO_DigitalOutput; + pin_config.interruptMode = kGPIO_NoIntmode; + + af_obj = pin_find_af(self, PIN_AF_MODE_ALT5); // GPIO is always ALT5 + if (af_obj == NULL) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("requested AF %d not available for pin %d"), PIN_AF_MODE_ALT5, mode); + } + + // Generate pad configuration + if (args[PIN_INIT_ARG_PULL].u_obj != mp_const_none) { + pull = (uint8_t)mp_obj_get_int(args[PIN_INIT_ARG_PULL].u_obj); + } + + pad_config |= IOMUXC_SW_PAD_CTL_PAD_SRE(0U); // Slow Slew Rate + pad_config |= IOMUXC_SW_PAD_CTL_PAD_SPEED(0b01); // medium(100MHz) + + if (mode == PIN_MODE_OPEN_DRAIN) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1); // Open Drain Enabled + } else { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b0); // Open Drain Disabled + } + + if (pull == PIN_PULL_DISABLED) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(0); // Pull/Keeper Disabled + } else if (pull == PIN_PULL_HOLD) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled + IOMUXC_SW_PAD_CTL_PAD_PUE(0); // Keeper selected + } else { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_PKE(1) | // Pull/Keeper Enabled + IOMUXC_SW_PAD_CTL_PAD_PUE(1) | // Pull selected + IOMUXC_SW_PAD_CTL_PAD_PUS(pull); + } + + if (mode == PIN_MODE_IN) { + pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(0b000) | // output driver disabled + IOMUXC_SW_PAD_CTL_PAD_HYS(1U); // Hysteresis enabled + } else { + uint drive = args[PIN_INIT_ARG_DRIVE].u_int; + if (!IS_GPIO_DRIVE(drive)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength: %d"), drive); + } + + pad_config |= IOMUXC_SW_PAD_CTL_PAD_DSE(drive) | + IOMUXC_SW_PAD_CTL_PAD_HYS(0U); // Hysteresis disabled + } + + // Configure PAD as GPIO + IOMUXC_SetPinMux(self->muxRegister, af_obj->af_mode, 0, 0, self->configRegister, 1U); // Software Input On Field: Input Path is determined by functionality + IOMUXC_SetPinConfig(self->muxRegister, af_obj->af_mode, 0, 0, self->configRegister, pad_config); + GPIO_PinInit(self->gpio, self->pin, &pin_config); + } + + return mp_const_none; +} + +STATIC void machine_pin_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { + (void)kind; + const machine_pin_obj_t *self = MP_OBJ_TO_PTR(o); + mp_printf(print, "Pin(%s)", qstr_str(self->name)); +} + +// pin(id, mode, pull, ...) +STATIC mp_obj_t machine_pin_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + const machine_pin_obj_t *pin = pin_find(args[0]); + + if (n_args > 1 || n_kw > 0) { + // pin mode given, so configure this GPIO + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args); + } + + return (mp_obj_t)pin; +} + +// pin.off() +STATIC mp_obj_t machine_pin_off(mp_obj_t self_in) { + machine_pin_obj_t *self = self_in; + mp_hal_pin_low(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off); + +// pin.on() +STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { + machine_pin_obj_t *self = self_in; + mp_hal_pin_high(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); + +// pin.value([value]) +STATIC mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) { + return machine_pin_obj_call(args[0], (n_args - 1), 0, args + 1); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); + +// pin.init(mode, pull, [kwargs]) +STATIC mp_obj_t machine_pin_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_init); + +STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) }, + { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) }, + { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_off_obj) }, + { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_on_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) }, + // class attributes + { MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&machine_pin_board_pins_obj_type) }, + { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&machine_pin_cpu_pins_obj_type) }, + // class constants + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(PIN_MODE_IN) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(PIN_MODE_OUT) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(PIN_MODE_OPEN_DRAIN) }, + + { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(PIN_PULL_UP_100K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP_47K), MP_ROM_INT(PIN_PULL_UP_47K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP_22K), MP_ROM_INT(PIN_PULL_UP_22K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(PIN_PULL_DOWN_100K) }, + { MP_ROM_QSTR(MP_QSTR_PULL_HOLD), MP_ROM_INT(PIN_PULL_HOLD) }, + + { MP_ROM_QSTR(MP_QSTR_DRIVER_OFF), MP_ROM_INT(PIN_DRIVE_OFF) }, + { MP_ROM_QSTR(MP_QSTR_POWER_0), MP_ROM_INT(PIN_DRIVE_POWER_0) }, // R0 (150 Ohm @3.3V / 260 Ohm @ 1.8V) + { MP_ROM_QSTR(MP_QSTR_POWER_1), MP_ROM_INT(PIN_DRIVE_POWER_1) }, // R0/2 + { MP_ROM_QSTR(MP_QSTR_POWER_2), MP_ROM_INT(PIN_DRIVE_POWER_2) }, // R0/3 + { MP_ROM_QSTR(MP_QSTR_POWER_3), MP_ROM_INT(PIN_DRIVE_POWER_3) }, // R0/4 + { MP_ROM_QSTR(MP_QSTR_POWER_4), MP_ROM_INT(PIN_DRIVE_POWER_4) }, // R0/5 + { MP_ROM_QSTR(MP_QSTR_POWER_5), MP_ROM_INT(PIN_DRIVE_POWER_5) }, // R0/6 + { MP_ROM_QSTR(MP_QSTR_POWER_6), MP_ROM_INT(PIN_DRIVE_POWER_6) }, // R0/7 + +}; +STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); + +const mp_obj_type_t machine_pin_type = { + {&mp_type_type}, + .name = MP_QSTR_Pin, + .print = machine_pin_obj_print, + .call = machine_pin_obj_call, + .make_new = machine_pin_obj_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, +}; + +// FIXME: Create actual pin_af type!!! +const mp_obj_type_t machine_pin_af_type = { + {&mp_type_type}, + .name = MP_QSTR_PinAF, + .print = machine_pin_obj_print, + .make_new = machine_pin_obj_make_new, + .locals_dict = (mp_obj_dict_t *)&machine_pin_locals_dict, +}; diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c index a6aab7b4ab..1bb6b6a352 100644 --- a/ports/mimxrt/modmachine.c +++ b/ports/mimxrt/modmachine.c @@ -28,6 +28,7 @@ #include "py/runtime.h" #include "extmod/machine_mem.h" #include "led.h" +#include "pin.h" #include CPU_HEADER_H @@ -52,6 +53,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #if NUM_LEDS { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&machine_led_type) }, #endif + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 993e151566..a6a28ab4a5 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -29,10 +29,14 @@ #include #include "ticks.h" +#include "pin.h" +#define mp_hal_pin_obj_t const machine_pin_obj_t * #define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) #define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) +#define mp_hal_pin_write(p, value) (GPIO_PinWrite(p->gpio, p->pin, value)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) +#define mp_hal_pin_read(p) (GPIO_PinRead(p->gpio, p->pin)) void mp_hal_set_interrupt_char(int c); diff --git a/ports/mimxrt/pin.c b/ports/mimxrt/pin.c index b30f4be41c..7a437661e3 100644 --- a/ports/mimxrt/pin.c +++ b/ports/mimxrt/pin.c @@ -24,14 +24,104 @@ * THE SOFTWARE. */ +#include "py/runtime.h" #include "pin.h" -const mp_obj_type_t pin_type = { - .base = {&mp_type_type}, - .name = MP_QSTR_Pin, -}; -const mp_obj_type_t pin_af_type = { - {&mp_type_type}, - .name = MP_QSTR_PinAF, -}; +void pin_init(void) { + return; +} + +uint32_t pin_get_mode(const machine_pin_obj_t *pin) { + uint32_t pin_mode = PIN_MODE_ALT; + uint32_t config_register = *((volatile uint32_t *)pin->configRegister); + uint8_t af_mode = pin_get_af(pin); + + if (af_mode == PIN_AF_MODE_ALT5) { + bool open_drain_enabled = (config_register & IOMUXC_SW_PAD_CTL_PAD_ODE_MASK) >> IOMUXC_SW_PAD_CTL_PAD_ODE_SHIFT; + + if (open_drain_enabled) { + pin_mode = PIN_MODE_OPEN_DRAIN; + } else { + // Check pin direction + if ((pin->gpio->GDIR & (1U << pin->pin)) >> pin->pin) { + pin_mode = PIN_MODE_OUT; + } else { + pin_mode = PIN_MODE_IN; + } + } + } + + return pin_mode; +} + +uint32_t pin_get_af(const machine_pin_obj_t *pin) { + uint32_t mux_register = *((volatile uint32_t *)pin->muxRegister); + + // Read configured AF-Mode of pin + return (uint32_t)(mux_register & IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_MASK) >> IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_SHIFT; +} + +const machine_pin_obj_t *pin_find(mp_obj_t user_obj) { + const machine_pin_obj_t *pin_obj; + + // If a pin was provided, then use it + if (mp_obj_is_type(user_obj, &machine_pin_type)) { + pin_obj = user_obj; + return pin_obj; + } + + // If pin is SMALL_INT + if (mp_obj_is_small_int(user_obj)) { + uint8_t value = MP_OBJ_SMALL_INT_VALUE(user_obj); + if (value < num_board_pins) { + return machine_pin_board_pins[value]; + } + } + + // See if the pin name matches a board pin + pin_obj = pin_find_named_pin(&machine_pin_board_pins_locals_dict, user_obj); + if (pin_obj) { + return pin_obj; + } + + // See if the pin name matches a cpu pin + pin_obj = pin_find_named_pin(&machine_pin_cpu_pins_locals_dict, user_obj); + if (pin_obj) { + return pin_obj; + } + + mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't exist")); +} + +const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP); + if (named_elem != NULL && named_elem->value != NULL) { + return named_elem->value; + } + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn) { + const machine_pin_af_obj_t *af_obj = NULL; + + for (int i = 0; i < pin->af_list_len; ++i) { + af_obj = &pin->af_list[i]; + if (af_obj->af_mode == fn) { + return af_obj; + } + } + + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx) { + // TODO: Implement pin_find_af_by_index function + return NULL; +} + +const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name) { + // TODO: Implement pin_find_af_by_name function + return NULL; +} diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index cfb1e6b572..268b505b38 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -27,12 +27,32 @@ #ifndef MICROPY_INCLUDED_MIMXRT_PIN_H #define MICROPY_INCLUDED_MIMXRT_PIN_H -#include "fsl_gpio.h" +#include #include "py/obj.h" +#include "fsl_gpio.h" + +// ------------------------------------------------------------------------------------------------------------------ // + +#define IS_GPIO_MODE(MODE) (((MODE) == PIN_MODE_IN) || \ + ((MODE) == PIN_MODE_OUT) || \ + ((MODE) == PIN_MODE_OPEN_DRAIN) || \ + ((MODE) == PIN_MODE_ALT)) + +#define IS_GPIO_DRIVE(DRIVE) (((DRIVE) == PIN_DRIVE_OFF) || \ + ((DRIVE) == PIN_DRIVE_POWER_0) || \ + ((DRIVE) == PIN_DRIVE_POWER_1) || \ + ((DRIVE) == PIN_DRIVE_POWER_2) || \ + ((DRIVE) == PIN_DRIVE_POWER_3) || \ + ((DRIVE) == PIN_DRIVE_POWER_4) || \ + ((DRIVE) == PIN_DRIVE_POWER_5) || \ + ((DRIVE) == PIN_DRIVE_POWER_6)) + +// ------------------------------------------------------------------------------------------------------------------ // enum { PIN_MODE_IN = 0, PIN_MODE_OUT, + PIN_MODE_OPEN_DRAIN, PIN_MODE_ALT, }; @@ -47,13 +67,38 @@ enum { PIN_AF_MODE_ALT8, }; +enum { + PIN_PULL_DOWN_100K = 0, + PIN_PULL_UP_47K, + PIN_PULL_UP_100K, + PIN_PULL_UP_22K, + PIN_PULL_DISABLED, + PIN_PULL_HOLD, +}; + +enum { + PIN_DRIVE_OFF = 0b000, + PIN_DRIVE_POWER_0, // R0 (150 Ohm @3.3V / 260 Ohm @ 1.8V) + PIN_DRIVE_POWER_1, // R0/2 + PIN_DRIVE_POWER_2, // R0/3 + PIN_DRIVE_POWER_3, // R0/4 + PIN_DRIVE_POWER_4, // R0/5 + PIN_DRIVE_POWER_5, // R0/6 + PIN_DRIVE_POWER_6, // R0/7 +}; + + + + +// ------------------------------------------------------------------------------------------------------------------ // + typedef struct { mp_obj_base_t base; qstr name; // port name - uint32_t af_mode; // alternate function + uint8_t af_mode; // alternate function void *instance; // pointer to peripheral instance for alternate function uint32_t pad_config; // pad configuration for alternate function -} pin_af_obj_t; +} machine_pin_af_obj_t; typedef struct { mp_obj_base_t base; @@ -62,39 +107,38 @@ typedef struct { uint32_t pin; // pin number uint32_t muxRegister; uint32_t configRegister; - uint32_t mode; // current pin mode - uint32_t af_mode; // current alternate function mode size_t af_list_len; // length of available alternate functions list - const pin_af_obj_t *af_list; // pointer tolist with alternate functions -} pin_obj_t; + const machine_pin_af_obj_t *af_list; // pointer tolist with alternate functions +} machine_pin_obj_t; -extern const mp_obj_type_t pin_type; -extern const mp_obj_type_t pin_af_type; +// ------------------------------------------------------------------------------------------------------------------ // -#define PIN_AF(_name, _af_mode, _instance, _pad_config) \ - { \ - .base = { &pin_af_type }, \ - .name = MP_QSTR_##_name, \ - .af_mode = (uint32_t)(_af_mode), \ - .instance = (void *)(_instance), \ - .pad_config = (uint32_t)(_pad_config), \ - } \ +extern const mp_obj_type_t machine_pin_type; +extern const mp_obj_type_t machine_pin_af_type; -#define PIN(_name, _gpio, _pin, _af_list) \ - { \ - .base = { &pin_type }, \ - .name = MP_QSTR_##_name, \ - .gpio = (_gpio), \ - .pin = (uint32_t)(_pin), \ - .muxRegister = (uint32_t)&(IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_##_name]), \ - .configRegister = (uint32_t)&(IOMUXC->SW_PAD_CTL_PAD[kIOMUXC_SW_PAD_CTL_PAD_##_name]), \ - .mode = PIN_MODE_IN, \ - .af_mode = PIN_AF_MODE_ALT5, \ - .af_list_len = (size_t)(sizeof((_af_list)) / sizeof(pin_af_obj_t)), \ - .af_list = (_af_list), \ - } \ +// ------------------------------------------------------------------------------------------------------------------ // // Include board specific pins -#include "pins.h" +#include "genhdr/pins.h" // pins.h must included at this location + +extern const machine_pin_obj_t *machine_pin_board_pins[]; +extern const uint32_t num_board_pins; + +extern const mp_obj_type_t machine_pin_board_pins_obj_type; +extern const mp_obj_type_t machine_pin_cpu_pins_obj_type; + +extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict; +extern const mp_obj_dict_t machine_pin_board_pins_locals_dict; + +// ------------------------------------------------------------------------------------------------------------------ // + +void pin_init(void); +uint32_t pin_get_mode(const machine_pin_obj_t *pin); +uint32_t pin_get_af(const machine_pin_obj_t *pin); +const machine_pin_obj_t *pin_find(mp_obj_t user_obj); +const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name); +const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn); +const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx); +const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name); #endif // MICROPY_INCLUDED_MIMXRT_PIN_H diff --git a/ports/mimxrt/tusb_port.c b/ports/mimxrt/tusb_port.c index 0d73b09235..2b1ccabbe7 100644 --- a/ports/mimxrt/tusb_port.c +++ b/ports/mimxrt/tusb_port.c @@ -76,7 +76,7 @@ static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = { static const char *const usbd_desc_str[] = { [USBD_STR_MANUF] = "MicroPython", - [USBD_STR_PRODUCT] = "Board in FS mode", + [USBD_STR_PRODUCT] = "Board in FS mode", // Todo: fix string to indicate that product is running in High Speed mode [USBD_STR_SERIAL] = "000000000000", // TODO [USBD_STR_CDC] = "Board CDC", }; From c326d9a67ba1846bba38f284fa9b8f712dd2d48a Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Sat, 24 Apr 2021 22:15:12 +0200 Subject: [PATCH 144/349] mimxrt: Enable built-in help. --- ports/mimxrt/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 65b91675a5..e6b15e1b71 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -58,6 +58,7 @@ #define MICROPY_PY_BUILTINS_FILTER (0) #define MICROPY_PY_BUILTINS_REVERSED (1) #define MICROPY_PY_BUILTINS_MIN_MAX (0) +#define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) From 5f68f0d08ab1effd0fae8a00bdda46dbc788d9db Mon Sep 17 00:00:00 2001 From: Philipp Ebensberger Date: Sat, 24 Apr 2021 21:34:07 +0200 Subject: [PATCH 145/349] github/workflows: Add CI workflow for mimxrt port. --- .github/workflows/ports_mimxrt.yml | 23 +++++++++++++++++++++++ tools/ci.sh | 13 +++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .github/workflows/ports_mimxrt.yml diff --git a/.github/workflows/ports_mimxrt.yml b/.github/workflows/ports_mimxrt.yml new file mode 100644 index 0000000000..8fbc2209e4 --- /dev/null +++ b/.github/workflows/ports_mimxrt.yml @@ -0,0 +1,23 @@ +name: mimxrt port + +on: + push: + pull_request: + paths: + - '.github/workflows/*.yml' + - 'tools/**' + - 'py/**' + - 'extmod/**' + - 'lib/**' + - 'drivers/**' + - 'ports/mimxrt/**' + +jobs: + build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install packages + run: source tools/ci.sh && ci_mimxrt_setup + - name: Build + run: source tools/ci.sh && ci_mimxrt_build diff --git a/tools/ci.sh b/tools/ci.sh index 7b38ce0df0..df812141f5 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -138,6 +138,19 @@ function ci_esp8266_build { make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_1M } +######################################################################################## +# ports/mimxrt + +function ci_mimxrt_setup { + ci_gcc_arm_setup +} + +function ci_mimxrt_build { + make ${MAKEOPTS} -C ports/mimxrt submodules + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK + make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 +} + ######################################################################################## # ports/nrf From c732b80f0584156b6ff98e8baa90c011539bf88a Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 25 May 2021 14:49:21 +0200 Subject: [PATCH 146/349] mimxrt: Extend the Pin module for SoftI2C, SoftSPI support. This change consists mostly of changing and extending the required definitions in mphalport.h. --- ports/mimxrt/machine_pin.c | 14 ++++++++++++++ ports/mimxrt/mphalport.h | 14 +++++++++++++- ports/mimxrt/pin.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index 583ee4a265..f63778cbe5 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -68,6 +68,20 @@ const mp_obj_type_t machine_pin_board_pins_obj_type = { .locals_dict = (mp_obj_t)&machine_pin_board_pins_locals_dict, }; +// Simplified mode setting used by the extmod modules +void machine_pin_set_mode(const machine_pin_obj_t *self, uint8_t mode) { + gpio_pin_config_t pin_config = {kGPIO_DigitalInput, 1, kGPIO_NoIntmode}; + + pin_config.direction = (mode == PIN_MODE_IN ? kGPIO_DigitalInput : kGPIO_DigitalOutput); + GPIO_PinInit(self->gpio, self->pin, &pin_config); + if (mode == PIN_MODE_OPEN_DRAIN) { + uint32_t pad_config = *(uint32_t *)self->configRegister; + pad_config |= IOMUXC_SW_PAD_CTL_PAD_ODE(0b1) | IOMUXC_SW_PAD_CTL_PAD_DSE(0b110); + IOMUXC_SetPinMux(self->muxRegister, PIN_AF_MODE_ALT5, 0, 0, self->configRegister, 1U); // Software Input On Field: Input Path is determined by functionality + IOMUXC_SetPinConfig(self->muxRegister, PIN_AF_MODE_ALT5, 0, 0, self->configRegister, pad_config); + } +} + STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); machine_pin_obj_t *self = self_in; diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index a6a28ab4a5..78b390b4eb 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -31,12 +31,22 @@ #include "ticks.h" #include "pin.h" +#define MP_HAL_PIN_FMT "%q" + #define mp_hal_pin_obj_t const machine_pin_obj_t * +#define mp_hal_get_pin_obj(o) pin_find(o) +#define mp_hal_pin_name(p) ((p)->name) +#define mp_hal_pin_input(p) machine_pin_set_mode(p, PIN_MODE_IN); +#define mp_hal_pin_output(p) machine_pin_set_mode(p, PIN_MODE_OUT); +#define mp_hal_pin_open_drain(p) machine_pin_set_mode(p, PIN_MODE_OPEN_DRAIN); #define mp_hal_pin_high(p) (GPIO_PinWrite(p->gpio, p->pin, 1U)) #define mp_hal_pin_low(p) (GPIO_PinWrite(p->gpio, p->pin, 0U)) #define mp_hal_pin_write(p, value) (GPIO_PinWrite(p->gpio, p->pin, value)) #define mp_hal_pin_toggle(p) (GPIO_PortToggle(p->gpio, (1 << p->pin))) -#define mp_hal_pin_read(p) (GPIO_PinRead(p->gpio, p->pin)) +#define mp_hal_pin_read(p) (GPIO_PinReadPadStatus(p->gpio, p->pin)) + +#define mp_hal_pin_od_low(p) mp_hal_pin_low(p) +#define mp_hal_pin_od_high(p) mp_hal_pin_high(p) void mp_hal_set_interrupt_char(int c); @@ -57,6 +67,8 @@ static inline void mp_hal_delay_us(mp_uint_t us) { ticks_delay_us64(us); } +#define mp_hal_delay_us_fast(us) mp_hal_delay_us(us) + static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 268b505b38..6afedd1f59 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -140,5 +140,6 @@ const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_ const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn); const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx); const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name); +void machine_pin_set_mode(const machine_pin_obj_t *pin, uint8_t mode); #endif // MICROPY_INCLUDED_MIMXRT_PIN_H From 4ee8ec6931e6a5958d2a5710c6a8f7cd7c0f3862 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:15:58 +1000 Subject: [PATCH 147/349] py/asmarm: Use builtin func to flush I- and D-cache on ARM 7 archs. The inline assembler code does not work for __ARM_ARCH == 7. Signed-off-by: Damien George --- py/asmarm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/py/asmarm.c b/py/asmarm.c index e91421578b..5662d75e19 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -40,7 +40,7 @@ void asm_arm_end_pass(asm_arm_t *as) { if (as->base.pass == MP_ASM_PASS_EMIT) { - #if defined(__linux__) && defined(__GNUC__) + #if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7 char *start = mp_asm_base_get_code(&as->base); char *end = start + mp_asm_base_get_code_size(&as->base); __builtin___clear_cache(start, end); @@ -48,10 +48,10 @@ void asm_arm_end_pass(asm_arm_t *as) { // flush I- and D-cache asm volatile ( "0:" - "mrc p15, 0, r15, c7, c10, 3\n" + "mrc p15, 0, r15, c7, c10, 3\n" // test and clean D-cache "bne 0b\n" "mov r0, #0\n" - "mcr p15, 0, r0, c7, c7, 0\n" + "mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache : : : "r0", "cc"); #endif } From 2c1a6a237d4e68c077c175d16f4d76518c00e4d2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:06 +1000 Subject: [PATCH 148/349] tools/mpy-tool.py: Support relocating ARMv6 arch. Signed-off-by: Damien George --- tools/mpy-tool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index ea756d3ee2..bfc3cf27e3 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -532,6 +532,7 @@ class RawCodeNative(RawCode): if config.native_arch in ( MP_NATIVE_ARCH_X86, MP_NATIVE_ARCH_X64, + MP_NATIVE_ARCH_ARMV6, MP_NATIVE_ARCH_XTENSA, MP_NATIVE_ARCH_XTENSAWIN, ): From f5cba77e50c9b3ae73d01cb373ad3226247ccd7b Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:11 +1000 Subject: [PATCH 149/349] tools/tinytest-codegen.py: Add command-line option to exclude tests. Signed-off-by: Damien George --- tools/tinytest-codegen.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py index 116a217b4b..cba0b94480 100755 --- a/tools/tinytest-codegen.py +++ b/tools/tinytest-codegen.py @@ -108,9 +108,12 @@ argparser = argparse.ArgumentParser( description="Convert native MicroPython tests to tinytest/upytesthelper C code" ) argparser.add_argument("--stdin", action="store_true", help="read list of tests from stdin") +argparser.add_argument("--exclude", action="append", help="exclude test by name") args = argparser.parse_args() if not args.stdin: + if args.exclude: + exclude_tests += tuple(args.exclude) for group in test_dirs: tests += [test for test in glob("{}/*.py".format(group)) if test not in exclude_tests] else: From b84406f3133a36a703a1506d754fc046dd955922 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:16:08 +1000 Subject: [PATCH 150/349] qemu-arm: Add support for Cortex-A9 via sabrelite board. Signed-off-by: Damien George --- ports/qemu-arm/Makefile | 21 ++++++++++++---- ports/qemu-arm/Makefile.test | 7 +++++- ports/qemu-arm/imx6.ld | 47 +++++++++++++++++++++++++++++++++++ ports/qemu-arm/mpconfigport.h | 11 +++++--- ports/qemu-arm/startup.c | 27 ++++++++++++++++++++ ports/qemu-arm/uart.c | 27 ++++++++++++++++++++ 6 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 ports/qemu-arm/imx6.ld diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index aebc5afaeb..22d0bf39cd 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -16,7 +16,8 @@ ifeq ($(BOARD),netduino2) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_STM32 LDSCRIPT = stm32.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),microbit) @@ -24,14 +25,26 @@ CFLAGS += -mthumb -mcpu=cortex-m0 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_NRF51 LDSCRIPT = nrf51.ld QEMU_EXTRA = -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144 -SRC_BOARD_O = lib/utils/gchelper_m0.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m0.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),mps2-an385) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_MPS2 LDSCRIPT = mps2.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m +endif + +ifeq ($(BOARD),sabrelite) +CFLAGS += -mcpu=cortex-a9 +CFLAGS += -DQEMU_SOC_IMX6 +LDSCRIPT = imx6.ld +QEMU_EXTRA = -m 128M +SRC_BOARD_O = lib/utils/gchelper_generic.o +# It's really armv7a but closest supported value is armv6. +MPY_CROSS_FLAGS += -march=armv6 endif CROSS_COMPILE ?= arm-none-eabi- @@ -95,7 +108,6 @@ LIB_SRC_C += $(addprefix lib/,\ libm/atanf.c \ libm/atan2f.c \ libm/roundf.c \ - utils/gchelper_native.c \ utils/sys_stdio_mphal.c \ ) @@ -125,7 +137,6 @@ ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -MPY_CROSS_FLAGS += -march=armv7m endif all: run diff --git a/ports/qemu-arm/Makefile.test b/ports/qemu-arm/Makefile.test index 6b7f1dc7ab..b4ad6114b8 100644 --- a/ports/qemu-arm/Makefile.test +++ b/ports/qemu-arm/Makefile.test @@ -4,6 +4,11 @@ FROZEN_MANIFEST ?= "freeze('test-frzmpy')" include Makefile +ifeq ($(BOARD),sabrelite) +# These don't work on Cortex-A9. +TESTS_EXCLUDE = inlineasm/asmdiv.py inlineasm/asmspecialregs.py +endif + CFLAGS += -DTEST .PHONY: $(BUILD)/genhdr/tests.h @@ -11,7 +16,7 @@ CFLAGS += -DTEST $(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h $(BUILD)/genhdr/tests.h: (cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp) - $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@ + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ $(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING diff --git a/ports/qemu-arm/imx6.ld b/ports/qemu-arm/imx6.ld new file mode 100644 index 0000000000..7155956f15 --- /dev/null +++ b/ports/qemu-arm/imx6.ld @@ -0,0 +1,47 @@ +/* Vector table is at 0x00000000, entry point is 0x10000000. */ + +MEMORY +{ + ROM : ORIGIN = 0x00000000, LENGTH = 96K + RAM : ORIGIN = 0x10000000, LENGTH = 128M +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); + +SECTIONS +{ + .rom : { + . = ALIGN(4); + KEEP(*(.isr_vector)) + . = ALIGN(4); + } > ROM + + .text : { + . = ALIGN(4); + *(.text.Reset_Handler) + *(.text*) + *(.rodata*) + . = ALIGN(4); + _etext = .; + _sidata = _etext; + } > RAM + + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; + *(.data*) + . = ALIGN(4); + _edata = .; + } > RAM + + .bss : + { + . = ALIGN(4); + _sbss = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } > RAM +} diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index 498ab3ed2c..1f05719caa 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -3,9 +3,16 @@ // options to control how MicroPython is built #define MICROPY_ALLOC_PATH_MAX (512) -#define MICROPY_EMIT_X64 (0) + +#if defined(__ARM_ARCH_ISA_ARM) +#define MICROPY_EMIT_ARM (1) +#define MICROPY_EMIT_INLINE_THUMB (1) +#elif defined(__ARM_ARCH_ISA_THUMB) #define MICROPY_EMIT_THUMB (1) #define MICROPY_EMIT_INLINE_THUMB (1) +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) +#endif + #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (0) @@ -43,8 +50,6 @@ // type definitions for the specific machine -#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) - #define MP_SSIZE_MAX (0x7fffffff) #define UINT_FMT "%lu" diff --git a/ports/qemu-arm/startup.c b/ports/qemu-arm/startup.c index 58bdf7af9e..a52b068c33 100644 --- a/ports/qemu-arm/startup.c +++ b/ports/qemu-arm/startup.c @@ -28,6 +28,27 @@ void Default_Handler(void) { } } +#if defined(__ARM_ARCH_ISA_ARM) + +// ARM architecture with standard ARM ISA. + +__attribute__((naked, section(".isr_vector"))) void isr_vector(void) { + __asm volatile ( + "b Reset_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "nop\n" + "b Default_Handler\n" + "b Default_Handler\n" + ); +} + +#elif defined(__ARM_ARCH_ISA_THUMB) + +// ARM architecture with Thumb-only ISA. + const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&_estack, (uint32_t)&Reset_Handler, @@ -47,6 +68,8 @@ const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&Default_Handler, // SysTick_Handler }; +#endif + void _start(void) { // Enable the UART uart_init(); @@ -68,7 +91,11 @@ __attribute__((naked)) void exit(int status) { "ldr r1, =0x20026\n" // ADP_Stopped_ApplicationExit, a clean exit ".notclean:\n" "movs r0, #0x18\n" // SYS_EXIT + #if defined(__ARM_ARCH_ISA_ARM) + "svc 0x00123456\n" + #elif defined(__ARM_ARCH_ISA_THUMB) "bkpt 0xab\n" + #endif ); for (;;) { } diff --git a/ports/qemu-arm/uart.c b/ports/qemu-arm/uart.c index 8710e9e9f6..828398cd17 100644 --- a/ports/qemu-arm/uart.c +++ b/ports/qemu-arm/uart.c @@ -75,4 +75,31 @@ void uart_tx_strn(const char *buf, size_t len) { } } +#elif defined(QEMU_SOC_IMX6) + +#define UART_UCR1_UARTEN (1 << 0) +#define UART_UCR2_TXEN (1 << 2) + +typedef struct _UART_t { + volatile uint32_t URXD; // 0x00 + volatile uint32_t r0[15]; + volatile uint32_t UTXD; // 0x40 + volatile uint32_t r1[15]; + volatile uint32_t UCR1; // 0x80 + volatile uint32_t UCR2; // 0x84 +} UART_t; + +#define UART1 ((UART_t *)(0x02020000)) + +void uart_init(void) { + UART1->UCR1 = UART_UCR1_UARTEN; + UART1->UCR2 = UART_UCR2_TXEN; +} + +void uart_tx_strn(const char *buf, size_t len) { + for (size_t i = 0; i < len; ++i) { + UART1->UTXD = buf[i]; + } +} + #endif From e7c0a8bca31063c295afdaf8e49c8ab24b70a90d Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 22:14:56 +1000 Subject: [PATCH 151/349] tools/ci.sh: Build Cortex-A9 sabrelite board as part of qemu-arm CI. Signed-off-by: Damien George --- tools/ci.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/ci.sh b/tools/ci.sh index df812141f5..c986c9fef8 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -194,6 +194,8 @@ function ci_qemu_arm_build { make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 make ${MAKEOPTS} -C ports/qemu-arm clean make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test } ######################################################################################## From dc86e044761a132ddd7026f0f9555f958ba8046a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 20 May 2021 10:02:57 +1000 Subject: [PATCH 152/349] tests: Make float and framebuf tests skip or run on big-endian archs. Signed-off-by: Damien George --- tests/extmod/framebuf16.py | 7 ++++++- tests/extmod/framebuf_subclass.py | 7 ++++++- ...ytearray_construct.py => bytearray_construct_endian.py} | 0 .../{bytes_construct.py => bytes_construct_endian.py} | 2 +- tests/float/float_array.py | 2 +- 5 files changed, 14 insertions(+), 4 deletions(-) rename tests/float/{bytearray_construct.py => bytearray_construct_endian.py} (100%) rename tests/float/{bytes_construct.py => bytes_construct_endian.py} (77%) diff --git a/tests/extmod/framebuf16.py b/tests/extmod/framebuf16.py index e658f1345a..cd7f5ec015 100644 --- a/tests/extmod/framebuf16.py +++ b/tests/extmod/framebuf16.py @@ -1,9 +1,14 @@ try: - import framebuf + import framebuf, usys except ImportError: print("SKIP") raise SystemExit +# This test and its .exp file is based on a little-endian architecture. +if usys.byteorder != "little": + print("SKIP") + raise SystemExit + def printbuf(): print("--8<--") diff --git a/tests/extmod/framebuf_subclass.py b/tests/extmod/framebuf_subclass.py index aad5d2a1e9..a9e3c5efc7 100644 --- a/tests/extmod/framebuf_subclass.py +++ b/tests/extmod/framebuf_subclass.py @@ -1,11 +1,16 @@ # test subclassing framebuf.FrameBuffer try: - import framebuf + import framebuf, usys except ImportError: print("SKIP") raise SystemExit +# This test and its .exp file is based on a little-endian architecture. +if usys.byteorder != "little": + print("SKIP") + raise SystemExit + class FB(framebuf.FrameBuffer): def __init__(self, n): diff --git a/tests/float/bytearray_construct.py b/tests/float/bytearray_construct_endian.py similarity index 100% rename from tests/float/bytearray_construct.py rename to tests/float/bytearray_construct_endian.py diff --git a/tests/float/bytes_construct.py b/tests/float/bytes_construct_endian.py similarity index 77% rename from tests/float/bytes_construct.py rename to tests/float/bytes_construct_endian.py index 0806087b0e..208f56162f 100644 --- a/tests/float/bytes_construct.py +++ b/tests/float/bytes_construct_endian.py @@ -1,4 +1,4 @@ -# test construction of bytearray from array with float type +# test construction of bytes from array with float type try: from uarray import array diff --git a/tests/float/float_array.py b/tests/float/float_array.py index 3c2189869b..219b6b86ae 100644 --- a/tests/float/float_array.py +++ b/tests/float/float_array.py @@ -22,4 +22,4 @@ def test(a): test(array("f")) test(array("d")) -print("{:.4f}".format(array("f", b"\xcc\xcc\xcc=")[0])) +print("{:.4f}".format(array("f", bytes(array("I", [0x3DCCCCCC])))[0])) From ef16834887de02cbddf414b560e5a2af9cae4b16 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 18 May 2021 13:20:02 +1000 Subject: [PATCH 153/349] github/workflows: Add workflow to build and run unix port on MIPS. This adds a coverage build and running of the test suite on a MIPS 32-bit big endian architecture. It uses the feature of qemu to execute foreign code as though it were native to the system (using qemu user mode). The code compiled for MIPS will run under the qemu VM, but all syscalls made by this code go to the host (Linux) system. See related #7268 and #7273. Signed-off-by: Damien George --- .github/workflows/ports_unix.yml | 14 ++++++++++++++ tools/ci.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index aa4b8abdc9..5c4a4f3047 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -186,3 +186,17 @@ jobs: - name: Print failures if: failure() run: tests/run-tests.py --print-failures + + qemu_mips: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install packages + run: source tools/ci.sh && ci_unix_qemu_mips_setup + - name: Build + run: source tools/ci.sh && ci_unix_qemu_mips_build + - name: Run main test suite + run: source tools/ci.sh && ci_unix_qemu_mips_run_tests + - name: Print failures + if: failure() + run: tests/run-tests.py --print-failures diff --git a/tools/ci.sh b/tools/ci.sh index c986c9fef8..23e529e5e1 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -292,6 +292,13 @@ CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS=( CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" ) +CI_UNIX_OPTS_QEMU_MIPS=( + CROSS_COMPILE=mips-linux-gnu- + VARIANT=coverage + MICROPY_STANDALONE=1 + LDFLAGS_EXTRA="-static" +) + function ci_unix_build_helper { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix "$@" submodules @@ -478,6 +485,26 @@ function ci_unix_macos_run_tests { (cd tests && ./run-tests.py --exclude 'uasyncio_(basic|heaplock|lock|wait_task)' --exclude 'import_pkg7.py' --exclude 'urandom_basic.py') } +function ci_unix_qemu_mips_setup { + sudo apt-get update + sudo apt-get install gcc-mips-linux-gnu g++-mips-linux-gnu + sudo apt-get install qemu-user + qemu-mips --version +} + +function ci_unix_qemu_mips_build { + # qemu-mips on GitHub Actions will seg-fault if not linked statically + ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_MIPS[@]}" +} + +function ci_unix_qemu_mips_run_tests { + # Issues with MIPS tests: + # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) + # - ffi tests do not work + file ./ports/unix/micropython-coverage + (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') +} + ######################################################################################## # ports/windows From 0abf6f830cd390e2e5dbd4a2c68f611f5c9507dc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 26 May 2021 16:57:39 +1000 Subject: [PATCH 154/349] esp8266/boards/GENERIC_512K: Add custom manifest without FS modules. The 512k build does not have a filesystem so there is no reason to include the filesystem-related modules. This commit provides a custom manifest.py for this board which no longer includes: _boot.py, flashbdev.py, inisetup.py, upip.py, upip_utarfile.py. This cuts the build down by about 9k of flash. Signed-off-by: Damien George --- ports/esp8266/boards/GENERIC_512K/manifest.py | 4 ++++ ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 ports/esp8266/boards/GENERIC_512K/manifest.py diff --git a/ports/esp8266/boards/GENERIC_512K/manifest.py b/ports/esp8266/boards/GENERIC_512K/manifest.py new file mode 100644 index 0000000000..e7ab8ad535 --- /dev/null +++ b/ports/esp8266/boards/GENERIC_512K/manifest.py @@ -0,0 +1,4 @@ +freeze("$(PORT_DIR)/modules", ("apa102.py", "neopixel.py", "ntptime.py", "port_diag.py")) +freeze("$(MPY_DIR)/drivers/dht", "dht.py") +freeze("$(MPY_DIR)/drivers/onewire") +include("$(MPY_DIR)/extmod/webrepl/manifest.py") diff --git a/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk b/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk index a7566f9f19..120351909b 100644 --- a/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk +++ b/ports/esp8266/boards/GENERIC_512K/mpconfigboard.mk @@ -1 +1,3 @@ LD_FILES = boards/esp8266_512k.ld + +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py From 6a127810c03d7666f1866f5e48df3c102805dbe8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 May 2021 16:48:29 +1000 Subject: [PATCH 155/349] extmod/moduhashlib: Put hash obj in final state after digest is called. If digest is called then the hash object is put in a "final" state and calling update() or digest() again will raise a ValueError (instead of silently producing the wrong result). See issue #4119. Signed-off-by: Damien George --- extmod/moduhashlib.c | 33 +++++++++++++++++++++++++++- tests/extmod/uhashlib_final.py | 35 ++++++++++++++++++++++++++++++ tests/extmod/uhashlib_final.py.exp | 1 + 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/extmod/uhashlib_final.py create mode 100644 tests/extmod/uhashlib_final.py.exp diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index 195a24334b..b170de9e58 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -60,9 +60,16 @@ typedef struct _mp_obj_hash_t { mp_obj_base_t base; - char state[0]; + bool final; // if set, update and digest raise an exception + uintptr_t state[0]; // must be aligned to a machine word } mp_obj_hash_t; +static void uhashlib_ensure_not_final(mp_obj_hash_t *self) { + if (self->final) { + mp_raise_ValueError(MP_ERROR_TEXT("hash is final")); + } +} + #if MICROPY_PY_UHASHLIB_SHA256 STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); @@ -78,6 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); o->base.type = type; + o->final = false; mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); if (n_args == 1) { @@ -88,6 +96,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len); @@ -96,6 +105,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 32); mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf); @@ -110,6 +121,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); o->base.type = type; + o->final = false; sha256_init((CRYAL_SHA256_CTX *)o->state); if (n_args == 1) { uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -119,6 +131,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -127,6 +140,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, SHA256_BLOCK_SIZE); sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf); @@ -160,6 +175,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); o->base.type = type; + o->final = false; SHA1_Init((SHA1_CTX *)o->state); if (n_args == 1) { uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -169,6 +185,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -177,6 +194,8 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, SHA1_SIZE); SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state); @@ -196,6 +215,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); o->base.type = type; + o->final = false; mbedtls_sha1_init((mbedtls_sha1_context *)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); if (n_args == 1) { @@ -206,6 +226,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len); @@ -214,6 +235,8 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 20); mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf); @@ -247,6 +270,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX)); o->base.type = type; + o->final = false; MD5_Init((MD5_CTX *)o->state); if (n_args == 1) { uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]); @@ -256,6 +280,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len); @@ -264,6 +289,8 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, MD5_SIZE); MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state); @@ -283,6 +310,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context)); o->base.type = type; + o->final = false; mbedtls_md5_init((mbedtls_md5_context *)o->state); mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); if (n_args == 1) { @@ -293,6 +321,7 @@ STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len); @@ -301,6 +330,8 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); + uhashlib_ensure_not_final(self); + self->final = true; vstr_t vstr; vstr_init_len(&vstr, 16); mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf); diff --git a/tests/extmod/uhashlib_final.py b/tests/extmod/uhashlib_final.py new file mode 100644 index 0000000000..f562cc1780 --- /dev/null +++ b/tests/extmod/uhashlib_final.py @@ -0,0 +1,35 @@ +try: + import uhashlib +except ImportError: + print("SKIP") + raise SystemExit + + +for algo_name in ("md5", "sha1", "sha256"): + algo = getattr(uhashlib, algo_name, None) + if not algo: + continue + + # Running .digest() several times in row is not supported. + h = algo(b"123") + h.digest() + try: + h.digest() + print("fail") + except ValueError: + # Expected path, don't print anything so test output is the + # same even if the algorithm is not implemented on the port. + pass + + # Partial digests are not supported. + h = algo(b"123") + h.digest() + try: + h.update(b"456") + print("fail") + except ValueError: + # Expected path, don't print anything so test output is the + # same even if the algorithm is not implemented on the port. + pass + +print("done") diff --git a/tests/extmod/uhashlib_final.py.exp b/tests/extmod/uhashlib_final.py.exp new file mode 100644 index 0000000000..19f86f493a --- /dev/null +++ b/tests/extmod/uhashlib_final.py.exp @@ -0,0 +1 @@ +done From 62f75376dd6932a694569e2b7a8701b3a6b13a77 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 26 May 2021 22:37:27 +1000 Subject: [PATCH 156/349] stm32/boards/NUCLEO_L432KC: Fix FS size and enable LFS1 filesystem. Signed-off-by: Damien George --- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h | 2 +- ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk | 1 + ports/stm32/boards/stm32l432.ld | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h index 0a3ac1f185..0f1134491f 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.h @@ -13,13 +13,13 @@ #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UTIMEQ (0) -#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_ADC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (0) // requires a custom USB connector on PA11/PA12 #define MICROPY_HW_ENABLE_TIMER (1) #define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_FLASH (1) // MSI is used and is 4MHz #define MICROPY_HW_CLK_PLLM (1) diff --git a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk index 6e220a4370..a87b4710e7 100644 --- a/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk +++ b/ports/stm32/boards/NUCLEO_L432KC/mpconfigboard.mk @@ -6,6 +6,7 @@ OPENOCD_CONFIG = boards/openocd_stm32l4.cfg # MicroPython settings MICROPY_VFS_FAT = 0 +MICROPY_VFS_LFS1 ?= 1 # Don't include default frozen modules because MCU is tight on flash space FROZEN_MANIFEST ?= diff --git a/ports/stm32/boards/stm32l432.ld b/ports/stm32/boards/stm32l432.ld index 4699543d66..469e834f91 100644 --- a/ports/stm32/boards/stm32l432.ld +++ b/ports/stm32/boards/stm32l432.ld @@ -6,7 +6,7 @@ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 230K /* sectors 0-114 */ - FLASH_FS (r) : ORIGIN = 0x08060000, LENGTH = 26K /* sectors 115-127 */ + FLASH_FS (r) : ORIGIN = 0x08039800, LENGTH = 26K /* sectors 115-127 */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* SRAM1, 48K + SRAM2, 16K */ } From 211c3e41f12295f08a883ac326386ecb5bc8d68e Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 27 May 2021 23:57:51 +1000 Subject: [PATCH 157/349] stm32/boards/PYBD_SF2: Disable GCC 11 warnings for array bounds. With GCC 11 there is now a warning about array bounds of OTP-mac, due to the OTP being a literal address. Signed-off-by: Damien George --- ports/stm32/boards/PYBD_SF2/board_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/stm32/boards/PYBD_SF2/board_init.c b/ports/stm32/boards/PYBD_SF2/board_init.c index d1a0a09e7a..c3b54fa2f1 100644 --- a/ports/stm32/boards/PYBD_SF2/board_init.c +++ b/ports/stm32/boards/PYBD_SF2/board_init.c @@ -64,7 +64,15 @@ void board_sleep(int value) { void mp_hal_get_mac(int idx, uint8_t buf[6]) { // Check if OTP region has a valid MAC address, and use it if it does if (OTP->series == 0x00d1 && OTP->mac[0] == 'H' && OTP->mac[1] == 'J' && OTP->mac[2] == '0') { + #if __GNUC__ >= 11 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #pragma GCC diagnostic ignored "-Wstringop-overread" + #endif memcpy(buf, OTP->mac, 6); + #if __GNUC__ >= 11 + #pragma GCC diagnostic pop + #endif buf[5] += idx; return; } From 8e1892ac6f2f1acfcb257507d8350a8719fcb36f Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Mon, 26 Apr 2021 17:52:49 -0400 Subject: [PATCH 158/349] Implement RP2040 Alarm module Adds light and deep sleep functionality for the TimeAlarm and PinAlarm alarm categories. Adds board deinit for all platforms. --- locale/circuitpython.pot | 6 + .../boards/adafruit_feather_rp2040/board.c | 3 + .../boards/adafruit_itsybitsy_rp2040/board.c | 3 + .../boards/adafruit_qtpy_rp2040/board.c | 3 + .../boards/pimoroni_keybow2040/board.c | 6 + .../boards/pimoroni_picolipo_16mb/board.c | 6 + .../boards/pimoroni_picolipo_4mb/board.c | 6 + .../boards/pimoroni_picosystem/board.c | 6 + .../boards/raspberry_pi_pico/board.c | 3 + .../boards/sparkfun_pro_micro_rp2040/board.c | 3 + .../boards/sparkfun_thing_plus_rp2040/board.c | 3 + .../common-hal/alarm/SleepMemory.c | 63 +++++ .../common-hal/alarm/SleepMemory.h | 53 ++++ ports/raspberrypi/common-hal/alarm/__init__.c | 241 ++++++++++++++++++ ports/raspberrypi/common-hal/alarm/__init__.h | 42 +++ .../common-hal/alarm/pin/PinAlarm.c | 157 ++++++++++++ .../common-hal/alarm/pin/PinAlarm.h | 44 ++++ .../common-hal/alarm/time/TimeAlarm.c | 125 +++++++++ .../common-hal/alarm/time/TimeAlarm.h | 40 +++ .../common-hal/alarm/touch/TouchAlarm.c | 32 +++ .../common-hal/alarm/touch/TouchAlarm.h | 38 +++ ports/raspberrypi/mpconfigport.mk | 2 + 22 files changed, 885 insertions(+) create mode 100644 ports/raspberrypi/common-hal/alarm/SleepMemory.c create mode 100644 ports/raspberrypi/common-hal/alarm/SleepMemory.h create mode 100644 ports/raspberrypi/common-hal/alarm/__init__.c create mode 100644 ports/raspberrypi/common-hal/alarm/__init__.h create mode 100644 ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c create mode 100644 ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h create mode 100644 ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c create mode 100644 ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h create mode 100644 ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c create mode 100644 ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1da8b1783c..c44573edd7 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -611,6 +611,10 @@ msgstr "" msgid "Can't set CCCD on local Characteristic" msgstr "" +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Cannot alarm from RTC in deep sleep" +msgstr "" + #: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c msgid "Cannot change USB devices now" @@ -1685,6 +1689,7 @@ msgstr "" #: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c #: ports/nrf/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set." msgstr "" @@ -2165,6 +2170,7 @@ msgstr "" msgid "Total data to write is larger than %q" msgstr "" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c #: ports/stm/common-hal/alarm/touch/TouchAlarm.c msgid "Touch alarms not available" msgstr "" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c index c4021a83e9..eac54ce460 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c @@ -38,3 +38,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c index e05589883d..0b44184082 100644 --- a/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/board.c @@ -42,3 +42,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c index 332145ab84..431b1ad0e7 100644 --- a/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/board.c @@ -42,3 +42,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/board.c b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c index 67486d4c23..492703e3a1 100644 --- a/ports/raspberrypi/boards/pimoroni_keybow2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c @@ -35,3 +35,9 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c index 67486d4c23..492703e3a1 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/board.c @@ -35,3 +35,9 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c index 67486d4c23..492703e3a1 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/board.c @@ -35,3 +35,9 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c index 67486d4c23..492703e3a1 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/board.c +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -35,3 +35,9 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/board.c b/ports/raspberrypi/boards/raspberry_pi_pico/board.c index 67486d4c23..de6e424ed9 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/board.c +++ b/ports/raspberrypi/boards/raspberry_pi_pico/board.c @@ -35,3 +35,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c index c4021a83e9..eac54ce460 100644 --- a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c +++ b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/board.c @@ -38,3 +38,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c index c4021a83e9..eac54ce460 100644 --- a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/board.c @@ -38,3 +38,6 @@ bool board_requests_safe_mode(void) { void reset_board(void) { } + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.c b/ports/raspberrypi/common-hal/alarm/SleepMemory.c new file mode 100644 index 0000000000..4cf7abe305 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/SleepMemory.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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" + +// Data storage for singleton instance of SleepMemory. +// Might be RTC_SLOW_MEM or RTC_FAST_MEM, depending on setting of CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM. +// static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; + +void alarm_sleep_memory_reset(void) { + // ESP-IDF build system takes care of doing esp_sleep_pd_config() or the equivalentwith + // the correct settings, depending on which RTC mem we are using. + // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/sleep_modes.html#power-down-of-rtc-peripherals-and-memories +} + +uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { + return 0;//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) { + + // if (start_index + len > sizeof(_sleep_mem)) { + // return false; + // } + + // memcpy((uint8_t *)(_sleep_mem + start_index), values, len); + // return true; + 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) { + + // if (start_index + len > sizeof(_sleep_mem)) { + // return; + // } + // memcpy(values, (uint8_t *)(_sleep_mem + start_index), len); +} diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.h b/ports/raspberrypi/common-hal/alarm/SleepMemory.h new file mode 100644 index 0000000000..427fe30a8c --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/SleepMemory.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H + +#include "py/obj.h" + +// There are several places we could store persistent data for SleepMemory: +// +// RTC registers: There are a few 32-bit registers maintained during deep sleep. +// We are already using one for saving sleep information during deep sleep. +// +// RTC Fast Memory: 8kB, also used for deep-sleep power-on stub. +// RTC Slow Memory: 8kB, also used for the ULP (tiny co-processor available during sleep). +// +// The ESP-IDF build system takes care of the power management of these regions. +// RTC_DATA_ATTR will allocate storage in RTC_SLOW_MEM unless CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM +// is set. Any memory not allocated by us can be used by the ESP-IDF for heap or other purposes. + +// Use half of RTC_SLOW_MEM or RTC_FAST_MEM. +#define SLEEP_MEMORY_LENGTH (4096) + +typedef struct { + mp_obj_base_t base; +} alarm_sleep_memory_obj_t; + +extern void alarm_sleep_memory_reset(void); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/raspberrypi/common-hal/alarm/__init__.c b/ports/raspberrypi/common-hal/alarm/__init__.c new file mode 100644 index 0000000000..ebed6286cd --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/__init__.c @@ -0,0 +1,241 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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 "lib/utils/interrupt_char.h" + +#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/microcontroller/__init__.h" + +#include "supervisor/port.h" +#include "supervisor/shared/workflow.h" + +#include "pico/stdlib.h" +#include "hardware/sync.h" +#include "hardware/clocks.h" +#include "hardware/xosc.h" +#include "hardware/structs/scb.h" +#include "hardware/watchdog.h" +#include "hardware/structs/watchdog.h" + +// XOSC shutdown +#include "hardware/rtc.h" +#include "hardware/pll.h" +#include "hardware/regs/io_bank0.h" + +// Watchdog scratch register +// Not used elsewhere in the SDK for now, keep an eye on it +#define RP_WKUP_SCRATCH_REG 0 + +// Turn off nonvolatile Busio and other wake-only peripherals +// TODO: this only saves about 2mA right now, expand with other non-essentials +const uint32_t RP_LIGHTSLEEP_EN0_MASK = ~( + CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS & + CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS & + CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS & + CLOCKS_SLEEP_EN0_CLK_ADC_ADC_BITS + ); + +// This bank has the USB clocks in it, leave it for now +const uint32_t RP_LIGHTSLEEP_EN1_MASK = CLOCKS_SLEEP_EN1_RESET; + +STATIC void prepare_for_dormant_xosc(void); + +// 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(); + + // Reset the scratch source + watchdog_hw->scratch[RP_WKUP_SCRATCH_REG] = RP_SLEEP_WAKEUP_UNDEF; +} + +STATIC uint8_t _get_wakeup_cause(void) { + // First check if the modules remember what last woke up + if (alarm_pin_pinalarm_woke_this_cycle()) { + return RP_SLEEP_WAKEUP_GPIO; + } + if (alarm_time_timealarm_woke_this_cycle()) { + return RP_SLEEP_WAKEUP_RTC; + } + // If waking from true deep sleep, modules will have lost their state, + // so check the deep wakeup cause manually + if (watchdog_hw->scratch[RP_WKUP_SCRATCH_REG] != RP_SLEEP_WAKEUP_UNDEF) { + return watchdog_hw->scratch[RP_WKUP_SCRATCH_REG]; + } + return RP_SLEEP_WAKEUP_UNDEF; +} + +// 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); +} + +bool common_hal_alarm_woken_from_sleep(void) { + return _get_wakeup_cause() != RP_SLEEP_WAKEUP_UNDEF; +} + +mp_obj_t common_hal_alarm_create_wake_alarm(void) { + // If woken from deep sleep, create a copy alarm similar to what would have + // been passed in originally. Otherwise, just return none + uint8_t cause = _get_wakeup_cause(); + switch (cause) { + case RP_SLEEP_WAKEUP_RTC: { + return alarm_time_timealarm_create_wakeup_alarm(); + } + + case RP_SLEEP_WAKEUP_GPIO: { + return alarm_pin_pinalarm_create_wakeup_alarm(); + } + + case RP_SLEEP_WAKEUP_UNDEF: + default: + // Not a deep sleep reset. + break; + } + return mp_const_none; +} + +mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + _setup_sleep_alarms(false, n_alarms, alarms); + // alarm_pin_pinalarm_light_reset(); + + mp_obj_t wake_alarm = mp_const_none; + + while (!mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + // Detect if interrupt was alarm or ctrl-C interrupt. + if (common_hal_alarm_woken_from_sleep()) { + uint8_t cause = _get_wakeup_cause(); + switch (cause) { + case RP_SLEEP_WAKEUP_RTC: { + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + break; + } + case RP_SLEEP_WAKEUP_GPIO: { + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + break; + } + default: + // Should not reach this, if all light sleep types are covered correctly + break; + } + shared_alarm_save_wake_alarm(wake_alarm); + break; + } + + // Prune the clock for sleep + clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK; + clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK; + // port_idle_until_interrupt(); + + // Enable System Control Block (SCB) deep sleep + uint save = scb_hw->scr; + scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS; + + __wfi(); + } + + if (mp_hal_is_interrupted()) { + return mp_const_none; // Shouldn't be given to python code because exception handling should kick in. + } + + alarm_reset(); + return wake_alarm; +} + +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 NORETURN common_hal_alarm_enter_deep_sleep(void) { + prepare_for_dormant_xosc(); + xosc_dormant(); + // // TODO: support ROSC when available in SDK + // rosc_set_dormant(); + + // Reset uses the watchdog. Use scratch registers to store wake reason + watchdog_hw->scratch[RP_WKUP_SCRATCH_REG] = _get_wakeup_cause(); + reset_cpu(); +} + +void common_hal_alarm_gc_collect(void) { + gc_collect_ptr(shared_alarm_get_wake_alarm()); +} + +STATIC void prepare_for_dormant_xosc(void) { + // TODO: add ROSC support with sleep_run_from_dormant_source when it's added to SDK + uint src_hz = XOSC_MHZ * MHZ; + uint clk_ref_src = CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC; + clock_configure(clk_ref, + clk_ref_src, + 0, // No aux mux + src_hz, + src_hz); + clock_configure(clk_sys, + CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF, + 0, // Using glitchless mux + src_hz, + src_hz); + clock_stop(clk_usb); + clock_stop(clk_adc); + uint clk_rtc_src = CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC; + clock_configure(clk_rtc, + 0, // No GLMUX + clk_rtc_src, + src_hz, + 46875); + clock_configure(clk_peri, + 0, + CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, + src_hz, + src_hz); + pll_deinit(pll_sys); + pll_deinit(pll_usb); +} diff --git a/ports/raspberrypi/common-hal/alarm/__init__.h b/ports/raspberrypi/common-hal/alarm/__init__.h new file mode 100644 index 0000000000..3d5d86f8dc --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/__init__.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H + +#include "common-hal/alarm/SleepMemory.h" + +#include "hardware/regs/clocks.h" + +#define RP_SLEEP_WAKEUP_UNDEF 0 +#define RP_SLEEP_WAKEUP_GPIO 1 +#define RP_SLEEP_WAKEUP_RTC 2 + +extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; + +extern void alarm_reset(void); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM__INIT__H diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c new file mode 100644 index 0000000000..72958ced87 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c @@ -0,0 +1,157 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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 "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "pico/stdlib.h" +#include "hardware/gpio.h" +#include "hardware/structs/iobank0.h" + +STATIC bool woke_up; +STATIC uint64_t alarm_triggered_pins; // 36 actual pins +STATIC uint64_t alarm_reserved_pins; // 36 actual pins + +#define GPIO_IRQ_ALL_EVENTS 0x15u + +void gpio_callback(uint gpio, uint32_t events) { + alarm_triggered_pins |= (1 << gpio); + woke_up = true; + + // does this need to be called, to prevent IRQ from constantly going off? + gpio_acknowledge_irq(gpio, events); + + // Disable IRQ automatically + gpio_set_irq_enabled(gpio, events, false); + gpio_set_dormant_irq_enabled(gpio, events, false); +} + +void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, const mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { + self->pin = pin; + self->value = value; + self->edge = edge; + self->pull = pull; +} + +const 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 self->edge; +} + +bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) { + return self->pull; +} + +bool alarm_pin_pinalarm_woke_this_cycle(void) { + return woke_up; +} + +mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *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_triggered_pins & (1 << alarm->pin->number)) { + return alarms[i]; + } + } + return mp_const_none; +} + +mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) { + alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t); + alarm->base.type = &alarm_pin_pinalarm_type; + // TODO: how to obtain the correct pin from memory? + return alarm; +} + +void alarm_pin_pinalarm_reset(void) { + alarm_triggered_pins = 0; + woke_up = false; + + // Clear all GPIO interrupts + for (uint8_t i = 0; i < 4; i++) { + iobank0_hw->intr[i] = 0; + } + + // Reset pins and pin IRQs + for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) { + if (alarm_reserved_pins & (1 << i)) { + gpio_set_irq_enabled(i, GPIO_IRQ_ALL_EVENTS, false); + reset_pin_number(i); + } + } + alarm_reserved_pins = 0; +} + +void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + for (size_t i = 0; i < n_alarms; i++) { + if (mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) { + alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); + + gpio_init(alarm->pin->number); + if (alarm->pull) { + // If value is high, the pullup should be off, and vice versa + gpio_set_pulls(alarm->pin->number, !alarm->value, alarm->value); + } else { + // Clear in case the pulls are already on + gpio_set_pulls(alarm->pin->number, false, false); + } + gpio_set_dir(alarm->pin->number, GPIO_IN); + // Don't reset at end of VM (instead, pinalarm_reset will reset before next VM) + common_hal_never_reset_pin(alarm->pin); + alarm_reserved_pins |= (1 << alarm->pin->number); + + uint32_t event; + if (alarm->value == true && alarm->edge == true) { + event = GPIO_IRQ_EDGE_RISE; + } else if (alarm->value == false && alarm->edge == true) { + event = GPIO_IRQ_EDGE_FALL; + } else if (alarm->value == true && alarm->edge == false) { + event = GPIO_IRQ_LEVEL_HIGH; + } else { // both false + event = GPIO_IRQ_LEVEL_LOW; + } + + gpio_set_irq_enabled_with_callback((uint)alarm->pin->number, event, true, &gpio_callback); + if (deep_sleep) { + gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true); + } + } + } +} diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h new file mode 100644 index 0000000000..cd1a21fd0d --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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; + const mcu_pin_obj_t *pin; + bool value; + bool pull; + bool edge; +} alarm_pin_pinalarm_obj_t; + +mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); +mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void); + +void alarm_pin_pinalarm_reset(void); +void alarm_pin_pinalarm_light_reset(void); +void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); +bool alarm_pin_pinalarm_woke_this_cycle(void); diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c new file mode 100644 index 0000000000..cb09b2a306 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -0,0 +1,125 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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 "shared-bindings/alarm/time/TimeAlarm.h" +#include "shared-bindings/time/__init__.h" + +#include "lib/timeutils/timeutils.h" + +#include "hardware/gpio.h" +#include "hardware/rtc.h" + +STATIC bool woke_up = false; + +void timer_callback(void) { + woke_up = true; +} + +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_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) { + for (size_t i = 0; i < n_alarms; i++) { + if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) { + return alarms[i]; + } + } + return mp_const_none; +} + +mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) { + 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; +} + +bool alarm_time_timealarm_woke_this_cycle(void) { + return woke_up; +} + +void alarm_time_timealarm_reset(void) { + rtc_disable_alarm(); + woke_up = false; +} + +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; + } + if (deep_sleep) { + mp_raise_ValueError(translate("Cannot alarm from RTC in deep sleep")); + } + + // Compute how long to actually sleep, considering the time now. + mp_float_t mono_seconds_to_date = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; + mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - mono_seconds_to_date); + datetime_t t; + + rtc_get_datetime(&t); + + uint32_t rtc_seconds_to_date = timeutils_seconds_since_2000(t.year, t.month, + t.day, t.hour, t.min, t.sec); + + // The float value is always slightly under, so add 1 to compensate + uint32_t alarm_seconds = rtc_seconds_to_date + (uint32_t)wakeup_in_secs + 1; + timeutils_struct_time_t tm; + timeutils_seconds_since_2000_to_struct_time(alarm_seconds, &tm); + + // reuse t + t.hour = tm.tm_hour; + t.min = tm.tm_min; + t.sec = tm.tm_sec; + t.day = tm.tm_mday; + t.month = tm.tm_mon; + t.year = tm.tm_year; + t.dotw = (tm.tm_wday + 1) % 7; + + rtc_set_alarm(&t, &timer_callback); + + woke_up = false; +} diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h new file mode 100644 index 0000000000..233a881e6e --- /dev/null +++ b/ports/raspberrypi/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) 2021 Lucian Copeland 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; +} alarm_time_timealarm_obj_t; + +mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms); +mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); + +void alarm_time_timealarm_reset(void); +void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); +bool alarm_time_timealarm_woke_this_cycle(void); diff --git a/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c new file mode 100644 index 0000000000..88c73726ee --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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 "shared-bindings/alarm/touch/TouchAlarm.h" +#include "shared-bindings/microcontroller/__init__.h" + +void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { + mp_raise_NotImplementedError(translate("Touch alarms not available")); +} diff --git a/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h new file mode 100644 index 0000000000..f631293511 --- /dev/null +++ b/ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Lucian Copeland 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_RASPBERRYPI_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H +#define MICROPY_INCLUDED_RASPBERRYPI_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; + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 8bc70ed638..cdb8769bfc 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -17,6 +17,8 @@ endif # All raspberrypi ports have longints. LONGINT_IMPL = MPZ +CIRCUITPY_ALARM ?= 1 + CIRCUITPY_RP2PIO ?= 1 CIRCUITPY_NEOPIXEL_WRITE ?= $(CIRCUITPY_RP2PIO) CIRCUITPY_FRAMEBUFFERIO ?= 1 From db8704ecbd910e598fba4bc1817acf91d9da79e3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 28 May 2021 00:09:34 +1000 Subject: [PATCH 159/349] esp8266,esp32: Update manifest to point to new dirs in micropython-lib. Following a refactoring of micropython-lib. Signed-off-by: Damien George --- ports/esp32/boards/manifest_release.py | 9 +++++---- ports/esp8266/boards/GENERIC/manifest.py | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ports/esp32/boards/manifest_release.py b/ports/esp32/boards/manifest_release.py index b5c7cd111b..8b9bcde6ff 100644 --- a/ports/esp32/boards/manifest_release.py +++ b/ports/esp32/boards/manifest_release.py @@ -1,6 +1,7 @@ include("manifest.py") -freeze("$(MPY_LIB_DIR)/upysh", "upysh.py") -freeze("$(MPY_LIB_DIR)/urequests", "urequests.py") -freeze("$(MPY_LIB_DIR)/umqtt.simple", "umqtt/simple.py") -freeze("$(MPY_LIB_DIR)/umqtt.robust", "umqtt/robust.py") +freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") + +freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") +freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") diff --git a/ports/esp8266/boards/GENERIC/manifest.py b/ports/esp8266/boards/GENERIC/manifest.py index 46f3b837be..9ce3ffe3aa 100644 --- a/ports/esp8266/boards/GENERIC/manifest.py +++ b/ports/esp8266/boards/GENERIC/manifest.py @@ -10,12 +10,12 @@ freeze("$(MPY_DIR)/drivers/display", "ssd1306.py") # Libraries from micropython-lib, include only if the library directory exists if os.path.isdir(convert_path("$(MPY_LIB_DIR)")): # file utilities - freeze("$(MPY_LIB_DIR)/upysh", "upysh.py") + freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py") # requests - freeze("$(MPY_LIB_DIR)/urequests", "urequests.py") - freeze("$(MPY_LIB_DIR)/urllib.urequest", "urllib/urequest.py") + freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py") + freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py") # umqtt - freeze("$(MPY_LIB_DIR)/umqtt.simple", "umqtt/simple.py") - freeze("$(MPY_LIB_DIR)/umqtt.robust", "umqtt/robust.py") + freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py") + freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py") From feff243e8fe84be080a8265c21d79606b2437a65 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Fri, 28 May 2021 13:52:05 -0400 Subject: [PATCH 160/349] Add RTC deep sleep alarm support --- locale/circuitpython.pot | 4 -- .../common-hal/alarm/SleepMemory.c | 2 +- ports/raspberrypi/common-hal/alarm/__init__.c | 49 +++++++++++++------ .../common-hal/alarm/pin/PinAlarm.c | 7 +++ .../common-hal/alarm/pin/PinAlarm.h | 1 + .../common-hal/alarm/time/TimeAlarm.c | 7 ++- .../common-hal/alarm/time/TimeAlarm.h | 1 + 7 files changed, 49 insertions(+), 22 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5198c7d924..a710b1effb 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -611,10 +611,6 @@ msgstr "" msgid "Can't set CCCD on local Characteristic" msgstr "" -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Cannot alarm from RTC in deep sleep" -msgstr "" - #: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c msgid "Cannot change USB devices now" diff --git a/ports/raspberrypi/common-hal/alarm/SleepMemory.c b/ports/raspberrypi/common-hal/alarm/SleepMemory.c index 4cf7abe305..a444cbf207 100644 --- a/ports/raspberrypi/common-hal/alarm/SleepMemory.c +++ b/ports/raspberrypi/common-hal/alarm/SleepMemory.c @@ -40,7 +40,7 @@ void alarm_sleep_memory_reset(void) { } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - return 0;//sizeof(_sleep_mem); + return 0;// 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) { diff --git a/ports/raspberrypi/common-hal/alarm/__init__.c b/ports/raspberrypi/common-hal/alarm/__init__.c index ebed6286cd..7f22242e9f 100644 --- a/ports/raspberrypi/common-hal/alarm/__init__.c +++ b/ports/raspberrypi/common-hal/alarm/__init__.c @@ -58,25 +58,31 @@ // Not used elsewhere in the SDK for now, keep an eye on it #define RP_WKUP_SCRATCH_REG 0 -// Turn off nonvolatile Busio and other wake-only peripherals +// Light sleep turns off nonvolatile Busio and other wake-only peripherals // TODO: this only saves about 2mA right now, expand with other non-essentials const uint32_t RP_LIGHTSLEEP_EN0_MASK = ~( - CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS & - CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS & - CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS & - CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS & + CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS | + CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS | + CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS | CLOCKS_SLEEP_EN0_CLK_ADC_ADC_BITS ); - // This bank has the USB clocks in it, leave it for now const uint32_t RP_LIGHTSLEEP_EN1_MASK = CLOCKS_SLEEP_EN1_RESET; +// Light sleeps used for TimeAlarm deep sleep turn off almost everything +const uint32_t RP_LIGHTSLEEP_EN0_MASK_HARSH = ( + CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS | + CLOCKS_SLEEP_EN0_CLK_SYS_PADS_BITS + ); +const uint32_t RP_LIGHTSLEEP_EN1_MASK_HARSH = 0x0; + STATIC void prepare_for_dormant_xosc(void); // Singleton instance of SleepMemory. @@ -144,7 +150,6 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) { mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { _setup_sleep_alarms(false, n_alarms, alarms); - // alarm_pin_pinalarm_light_reset(); mp_obj_t wake_alarm = mp_const_none; @@ -173,7 +178,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj // Prune the clock for sleep clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK; clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK; - // port_idle_until_interrupt(); // Enable System Control Block (SCB) deep sleep uint save = scb_hw->scr; @@ -195,8 +199,21 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala } void NORETURN common_hal_alarm_enter_deep_sleep(void) { - prepare_for_dormant_xosc(); - xosc_dormant(); + bool timealarm_set = alarm_time_timealarm_is_set(); + + // If there's a timealarm, just enter a very deep light sleep + if (timealarm_set) { + // Prune the clock for sleep + clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK_HARSH; + clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK_HARSH; + // Enable System Control Block (SCB) deep sleep + uint save = scb_hw->scr; + scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS; + __wfi(); + } else { + prepare_for_dormant_xosc(); + xosc_dormant(); + } // // TODO: support ROSC when available in SDK // rosc_set_dormant(); diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c index 72958ced87..276e2e409a 100644 --- a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c @@ -38,6 +38,7 @@ STATIC bool woke_up; STATIC uint64_t alarm_triggered_pins; // 36 actual pins STATIC uint64_t alarm_reserved_pins; // 36 actual pins +STATIC bool _pinalarm_set = false; #define GPIO_IRQ_ALL_EVENTS 0x15u @@ -152,6 +153,12 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (deep_sleep) { gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true); } + + _pinalarm_set = true; } } } + +bool alarm_pin_pinalarm_is_set(void) { + return _pinalarm_set; +} diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h index cd1a21fd0d..d31ac6c878 100644 --- a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h @@ -42,3 +42,4 @@ void alarm_pin_pinalarm_reset(void); void alarm_pin_pinalarm_light_reset(void); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); bool alarm_pin_pinalarm_woke_this_cycle(void); +bool alarm_pin_pinalarm_is_set(void); diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c index cb09b2a306..4302e9e8cd 100644 --- a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +++ b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c @@ -35,6 +35,7 @@ #include "hardware/rtc.h" STATIC bool woke_up = false; +STATIC bool _timealarm_set = false; void timer_callback(void) { woke_up = true; @@ -92,7 +93,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ return; } if (deep_sleep) { - mp_raise_ValueError(translate("Cannot alarm from RTC in deep sleep")); + _timealarm_set = true; } // Compute how long to actually sleep, considering the time now. @@ -123,3 +124,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ woke_up = false; } + +bool alarm_time_timealarm_is_set(void) { + return _timealarm_set; +} diff --git a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h index 233a881e6e..d5248551ae 100644 --- a/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h +++ b/ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h @@ -38,3 +38,4 @@ mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void); void alarm_time_timealarm_reset(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); bool alarm_time_timealarm_woke_this_cycle(void); +bool alarm_time_timealarm_is_set(void); From 4982d0920ebd247758aa6321bb36a5eede0bd775 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 11:04:01 +1000 Subject: [PATCH 161/349] tools/pyboard.py: Track raw REPL state via in_raw_repl variable. Signed-off-by: Damien George --- tools/pyboard.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/pyboard.py b/tools/pyboard.py index 29a15f7eae..220c010937 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -255,6 +255,7 @@ class Pyboard: def __init__( self, device, baudrate=115200, user="micro", password="python", wait=0, exclusive=True ): + self.in_raw_repl = False self.use_raw_paste = True if device.startswith("exec:"): self.serial = ProcessToSerial(device[len("exec:") :]) @@ -348,8 +349,11 @@ class Pyboard: print(data) raise PyboardError("could not enter raw repl") + self.in_raw_repl = True + def exit_raw_repl(self): self.serial.write(b"\r\x02") # ctrl-B: enter friendly REPL + self.in_raw_repl = False def follow(self, timeout, data_consumer=None): # wait for normal output From e4ba57c5cd6f68306726891c45f36b5129b633ec Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 11:21:19 +1000 Subject: [PATCH 162/349] tools/pyboard.py: Add "soft_reset" option to Pyboard.enter_raw_repl(). Signed-off-by: Damien George --- tools/pyboard.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tools/pyboard.py b/tools/pyboard.py index 220c010937..7d06aa847d 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -322,7 +322,7 @@ class Pyboard: time.sleep(0.01) return data - def enter_raw_repl(self): + def enter_raw_repl(self, soft_reset=True): self.serial.write(b"\r\x03\x03") # ctrl-C twice: interrupt any running program # flush input (without relying on serial.flushInput()) @@ -332,18 +332,23 @@ class Pyboard: n = self.serial.inWaiting() self.serial.write(b"\r\x01") # ctrl-A: enter raw REPL - data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n>") - if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"): - print(data) - raise PyboardError("could not enter raw repl") - self.serial.write(b"\x04") # ctrl-D: soft reset - data = self.read_until(1, b"soft reboot\r\n") - if not data.endswith(b"soft reboot\r\n"): - print(data) - raise PyboardError("could not enter raw repl") - # By splitting this into 2 reads, it allows boot.py to print stuff, - # which will show up after the soft reboot and before the raw REPL. + if soft_reset: + data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n>") + if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"): + print(data) + raise PyboardError("could not enter raw repl") + + self.serial.write(b"\x04") # ctrl-D: soft reset + + # Waiting for "soft reboot" independently to "raw REPL" (done below) + # allows boot.py to print, which will show up after "soft reboot" + # and before "raw REPL". + data = self.read_until(1, b"soft reboot\r\n") + if not data.endswith(b"soft reboot\r\n"): + print(data) + raise PyboardError("could not enter raw repl") + data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n") if not data.endswith(b"raw REPL; CTRL-B to exit\r\n"): print(data) From a60ad3364132b9c4a30b20cd91fd5cd1ac965618 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 29 May 2021 17:12:54 +1000 Subject: [PATCH 163/349] tools/mpremote: Add new CLI utility to interact with remote device. This has been under development since April 2017. See #3034 and #6375. Signed-off-by: Damien George --- tools/mpremote/LICENSE | 21 + tools/mpremote/README.md | 71 +++ tools/mpremote/mpremote.py | 6 + tools/mpremote/mpremote/__init__.py | 1 + tools/mpremote/mpremote/console.py | 162 ++++++ tools/mpremote/mpremote/main.py | 477 ++++++++++++++++ tools/mpremote/mpremote/pyboardextended.py | 621 +++++++++++++++++++++ tools/mpremote/pyproject.toml | 6 + tools/mpremote/setup.cfg | 25 + 9 files changed, 1390 insertions(+) create mode 100644 tools/mpremote/LICENSE create mode 100644 tools/mpremote/README.md create mode 100755 tools/mpremote/mpremote.py create mode 100644 tools/mpremote/mpremote/__init__.py create mode 100644 tools/mpremote/mpremote/console.py create mode 100644 tools/mpremote/mpremote/main.py create mode 100644 tools/mpremote/mpremote/pyboardextended.py create mode 100644 tools/mpremote/pyproject.toml create mode 100644 tools/mpremote/setup.cfg diff --git a/tools/mpremote/LICENSE b/tools/mpremote/LICENSE new file mode 100644 index 0000000000..5ec904cca1 --- /dev/null +++ b/tools/mpremote/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2021 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. diff --git a/tools/mpremote/README.md b/tools/mpremote/README.md new file mode 100644 index 0000000000..a6aaa1755d --- /dev/null +++ b/tools/mpremote/README.md @@ -0,0 +1,71 @@ +# mpremote -- MicroPython remote control + +This CLI tool provides an integrated set of utilities to remotely interact with +and automate a MicroPython device over a serial connection. + +The simplest way to use this tool is: + + mpremote + +This will automatically connect to the device and provide an interactive REPL. + +The full list of supported commands are: + + mpremote connect -- connect to given device + device may be: list, auto, id:x, port:x + or any valid device name/path + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run -- run the given local script + mpremote fs -- execute filesystem commands on the device + command may be: cat, ls, cp, rm, mkdir, rmdir + use ":" as a prefix to specify a file on the device + mpremote repl -- enter REPL + options: + --capture + --inject-code + --inject-file + +Multiple commands can be specified and they will be run sequentially. Connection +and disconnection will be done automatically at the start and end of the execution +of the tool, if such commands are not explicitly given. Automatic connection will +search for the first available serial device. If no action is specified then the +REPL will be entered. + +Shortcuts can be defined using the macro system. Built-in shortcuts are: + +- a0, a1, a2, a3: connect to `/dev/ttyACM?` +- u0, u1, u2, u3: connect to `/dev/ttyUSB?` +- c0, c1, c2, c3: connect to `COM?` +- cat, ls, cp, rm, mkdir, rmdir, df: filesystem commands +- reset: reset the device +- bootloader: make the device enter its bootloader + +Any user configuration, including user-defined shortcuts, can be placed in +.config/mpremote/config.py. For example: + + # Custom macro commands + commands = { + "c33": "connect id:334D335C3138", + "bl": "bootloader", + "double x=4": "eval x*2", + } + +Examples: + + mpremote + mpremote a1 + mpremote connect /dev/ttyUSB0 repl + mpremote ls + mpremote a1 ls + mpremote exec "import micropython; micropython.mem_info()" + mpremote eval 1/2 eval 3/4 + mpremote mount . + mpremote mount . exec "import local_script" + mpremote ls + mpremote cat boot.py + mpremote cp :main.py . + mpremote cp main.py : + mpremote cp -r dir/ : diff --git a/tools/mpremote/mpremote.py b/tools/mpremote/mpremote.py new file mode 100755 index 0000000000..a91ff67b15 --- /dev/null +++ b/tools/mpremote/mpremote.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import sys +from mpremote import main + +sys.exit(main.main()) diff --git a/tools/mpremote/mpremote/__init__.py b/tools/mpremote/mpremote/__init__.py new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/tools/mpremote/mpremote/__init__.py @@ -0,0 +1 @@ +# empty diff --git a/tools/mpremote/mpremote/console.py b/tools/mpremote/mpremote/console.py new file mode 100644 index 0000000000..646bbfa22e --- /dev/null +++ b/tools/mpremote/mpremote/console.py @@ -0,0 +1,162 @@ +import sys + +try: + import select, termios +except ImportError: + termios = None + select = None + import msvcrt + + +class ConsolePosix: + def __init__(self): + self.infd = sys.stdin.fileno() + self.infile = sys.stdin.buffer.raw + self.outfile = sys.stdout.buffer.raw + self.orig_attr = termios.tcgetattr(self.infd) + + def enter(self): + # attr is: [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] + attr = termios.tcgetattr(self.infd) + attr[0] &= ~( + termios.BRKINT | termios.ICRNL | termios.INPCK | termios.ISTRIP | termios.IXON + ) + attr[1] = 0 + attr[2] = attr[2] & ~(termios.CSIZE | termios.PARENB) | termios.CS8 + attr[3] = 0 + attr[6][termios.VMIN] = 1 + attr[6][termios.VTIME] = 0 + termios.tcsetattr(self.infd, termios.TCSANOW, attr) + + def exit(self): + termios.tcsetattr(self.infd, termios.TCSANOW, self.orig_attr) + + def waitchar(self): + # TODO pyb.serial might not have fd + select.select([console_in.infd, pyb.serial.fd], [], []) + + def readchar(self): + res = select.select([self.infd], [], [], 0) + if res[0]: + return self.infile.read(1) + else: + return None + + def write(self, buf): + self.outfile.write(buf) + + +class ConsoleWindows: + KEY_MAP = { + b"H": b"A", # UP + b"P": b"B", # DOWN + b"M": b"C", # RIGHT + b"K": b"D", # LEFT + b"G": b"H", # POS1 + b"O": b"F", # END + b"Q": b"6~", # PGDN + b"I": b"5~", # PGUP + b"s": b"1;5D", # CTRL-LEFT, + b"t": b"1;5C", # CTRL-RIGHT, + b"\x8d": b"1;5A", # CTRL-UP, + b"\x91": b"1;5B", # CTRL-DOWN, + b"w": b"1;5H", # CTRL-POS1 + b"u": b"1;5F", # CTRL-END + b"\x98": b"1;3A", # ALT-UP, + b"\xa0": b"1;3B", # ALT-DOWN, + b"\x9d": b"1;3C", # ALT-RIGHT, + b"\x9b": b"1;3D", # ALT-LEFT, + b"\x97": b"1;3H", # ALT-POS1, + b"\x9f": b"1;3F", # ALT-END, + b"S": b"3~", # DEL, + b"\x93": b"3;5~", # CTRL-DEL + b"R": b"2~", # INS + b"\x92": b"2;5~", # CTRL-INS + b"\x94": b"Z", # Ctrl-Tab = BACKTAB, + } + + def enter(self): + pass + + def exit(self): + pass + + def inWaiting(self): + return 1 if msvcrt.kbhit() else 0 + + def waitchar(self): + while not (self.inWaiting() or pyb.serial.inWaiting()): + time.sleep(0.01) + + def readchar(self): + if msvcrt.kbhit(): + ch = msvcrt.getch() + while ch in b"\x00\xe0": # arrow or function key prefix? + if not msvcrt.kbhit(): + return None + ch = msvcrt.getch() # second call returns the actual key code + try: + ch = b"\x1b[" + self.KEY_MAP[ch] + except KeyError: + return None + return ch + + def write(self, buf): + buf = buf.decode() if isinstance(buf, bytes) else buf + sys.stdout.write(buf) + sys.stdout.flush() + # for b in buf: + # if isinstance(b, bytes): + # msvcrt.putch(b) + # else: + # msvcrt.putwch(b) + + +if termios: + Console = ConsolePosix + VT_ENABLED = True +else: + Console = ConsoleWindows + + # Windows VT mode ( >= win10 only) + # https://bugs.python.org/msg291732 + import ctypes + from ctypes import wintypes + + kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + + ERROR_INVALID_PARAMETER = 0x0057 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + def _check_bool(result, func, args): + if not result: + raise ctypes.WinError(ctypes.get_last_error()) + return args + + LPDWORD = ctypes.POINTER(wintypes.DWORD) + kernel32.GetConsoleMode.errcheck = _check_bool + kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD) + kernel32.SetConsoleMode.errcheck = _check_bool + kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) + + def set_conout_mode(new_mode, mask=0xFFFFFFFF): + # don't assume StandardOutput is a console. + # open CONOUT$ instead + fdout = os.open("CONOUT$", os.O_RDWR) + try: + hout = msvcrt.get_osfhandle(fdout) + old_mode = wintypes.DWORD() + kernel32.GetConsoleMode(hout, ctypes.byref(old_mode)) + mode = (new_mode & mask) | (old_mode.value & ~mask) + kernel32.SetConsoleMode(hout, mode) + return old_mode.value + finally: + os.close(fdout) + + # def enable_vt_mode(): + mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING + try: + set_conout_mode(mode, mask) + VT_ENABLED = True + except WindowsError as e: + VT_ENABLED = False diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py new file mode 100644 index 0000000000..1ce00305eb --- /dev/null +++ b/tools/mpremote/mpremote/main.py @@ -0,0 +1,477 @@ +""" +MicroPython Remote - Interaction and automation tool for MicroPython +MIT license; Copyright (c) 2019-2021 Damien P. George + +This program provides a set of utilities to interact with and automate a +MicroPython device over a serial connection. Commands supported are: + + mpremote -- auto-detect, connect and enter REPL + mpremote -- connect to given device + mpremote connect -- connect to given device + mpremote disconnect -- disconnect current device + mpremote mount -- mount local directory on device + mpremote eval -- evaluate and print the string + mpremote exec -- execute the string + mpremote run