From fb90b580507c318b8ec602babe60df3783a7c7fd Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 13:27:09 +0100 Subject: [PATCH 01/45] py: Add NLR raise hook. Signed-off-by: iabdalkader --- py/mpconfig.h | 4 ++++ py/nlr.h | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/py/mpconfig.h b/py/mpconfig.h index 798d4089aa1..ef2baed915b 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -764,6 +764,10 @@ typedef uint64_t mp_uint_t; #define MICROPY_GC_HOOK_LOOP(i) #endif +#ifndef MICROPY_NLR_RAISE_HOOK +#define MICROPY_NLR_RAISE_HOOK +#endif + // Whether to provide m_tracked_calloc, m_tracked_free functions #ifndef MICROPY_TRACKED_ALLOC #define MICROPY_TRACKED_ALLOC (0) diff --git a/py/nlr.h b/py/nlr.h index 47447c5d174..c097fbd15ab 100644 --- a/py/nlr.h +++ b/py/nlr.h @@ -192,7 +192,11 @@ MP_NORETURN void nlr_jump_fail(void *val); // use nlr_raise instead of nlr_jump so that debugging is easier #ifndef MICROPY_DEBUG_NLR -#define nlr_raise(val) nlr_jump(MP_OBJ_TO_PTR(val)) +#define nlr_raise(val) \ + do { \ + MICROPY_NLR_RAISE_HOOK \ + nlr_jump(MP_OBJ_TO_PTR(val)); \ + } while (0) #else #define nlr_raise(val) \ @@ -200,6 +204,7 @@ MP_NORETURN void nlr_jump_fail(void *val); void *_val = MP_OBJ_TO_PTR(val); \ assert(_val != NULL); \ assert(mp_obj_is_exception_instance(val)); \ + MICROPY_NLR_RAISE_HOOK \ nlr_jump(_val); \ } while (0) From cec713bb8f765b764a38516d79a065193fc96905 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 13:34:30 +0100 Subject: [PATCH 02/45] py/makeversionhdr: Add OpenMV tag. --- py/makeversionhdr.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index 249ec1830c1..1b1617ea44a 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -96,16 +96,17 @@ def get_version_info_from_mpconfig(repo_path): def make_version_header(repo_path, filename): git_tag = None - git_hash = None + omv_repo = "../../../" if os.path.exists("../../../micropython") else "../../" + if "MICROPY_GIT_TAG" in os.environ: - git_tag = os.environ["MICROPY_GIT_TAG"] - git_hash = os.environ.get("MICROPY_GIT_HASH") + git_tag = [os.environ["MICROPY_GIT_TAG"], os.environ["MICROPY_GIT_HASH"]] if git_tag is None: - git_tag = get_version_info_from_git(repo_path) - git_hash = get_hash_from_git(repo_path) + git_tag = get_version_info_from_git(os.path.join(omv_repo, "micropython")) if git_tag is None: git_tag = get_version_info_from_mpconfig(repo_path) + omv_git_tag = get_version_info_from_git(omv_repo) + if not git_tag: print("makeversionhdr.py: Error: No version information available.") sys.exit(1) @@ -121,11 +122,11 @@ def make_version_header(repo_path, filename): file_data = """\ // This file was generated by py/makeversionhdr.py #define MICROPY_GIT_TAG "%s" -#define MICROPY_GIT_HASH "%s" +#define OPENMV_GIT_TAG "%s" #define MICROPY_BUILD_DATE "%s" """ % ( git_tag, - git_hash or "", + omv_git_tag, build_date.strftime("%Y-%m-%d"), ) From ab40baa23c70b774bc230845f36e8b2246b162e7 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 15:18:36 +0100 Subject: [PATCH 03/45] lib/oofatfs: Update config. - Enable FF_USE_STRFUNC. - Use hard-coded ffconf header (not easy to set/override). --- lib/oofatfs/ff.h | 2 +- lib/oofatfs/ffconf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/oofatfs/ff.h b/lib/oofatfs/ff.h index a8aa00e9afb..93516d6edb5 100644 --- a/lib/oofatfs/ff.h +++ b/lib/oofatfs/ff.h @@ -30,7 +30,7 @@ extern "C" { #endif -#include FFCONF_H /* FatFs configuration options */ +#include "ffconf.h" /* FatFs configuration options */ #if FF_DEFINED != FFCONF_DEF #error Wrong configuration file (ffconf.h). diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index 4a8015668f4..bb50f76223a 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -56,7 +56,7 @@ / 3: f_lseek() function is removed in addition to 2. */ -#define FF_USE_STRFUNC 0 +#define FF_USE_STRFUNC 1 /* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). / / 0: Disable string functions. From 770ac815f51f09ea8d8f38b9f3206bb447905769 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 13:49:05 +0100 Subject: [PATCH 04/45] extmod/modopenamp: Make modopenamp extensible. --- extmod/modopenamp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extmod/modopenamp.c b/extmod/modopenamp.c index 7d5841c4000..81e581a86a2 100644 --- a/extmod/modopenamp.c +++ b/extmod/modopenamp.c @@ -422,6 +422,6 @@ const mp_obj_module_t openamp_module = { }; MP_REGISTER_ROOT_POINTER(struct _virtio_dev_obj_t *virtio_device); -MP_REGISTER_MODULE(MP_QSTR_openamp, openamp_module); +MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_openamp, openamp_module); #endif // MICROPY_PY_OPENAMP From db9f6237997e4ea2de5c7c381e10dd4f680a0d43 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 13:56:22 +0100 Subject: [PATCH 05/45] extmod/modmachine: Add machine.CAN. --- extmod/modmachine.c | 3 +++ extmod/modmachine.h | 1 + 2 files changed, 4 insertions(+) diff --git a/extmod/modmachine.c b/extmod/modmachine.c index 28b60683b1e..60107a9020c 100644 --- a/extmod/modmachine.c +++ b/extmod/modmachine.c @@ -213,6 +213,9 @@ static const mp_rom_map_elem_t machine_module_globals_table[] = { #if MICROPY_PY_MACHINE_ADC_BLOCK { MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adc_block_type) }, #endif + #if MICROPY_PY_MACHINE_CAN + { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&machine_can_type) }, + #endif #if MICROPY_PY_MACHINE_DAC { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) }, #endif diff --git a/extmod/modmachine.h b/extmod/modmachine.h index ef507aca740..4031d68524c 100644 --- a/extmod/modmachine.h +++ b/extmod/modmachine.h @@ -203,6 +203,7 @@ extern const machine_mem_obj_t machine_mem32_obj; // is provided by a port. extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_adc_block_type; +extern const mp_obj_type_t machine_can_type; extern const mp_obj_type_t machine_i2c_type; extern const mp_obj_type_t machine_i2c_target_type; extern const mp_obj_type_t machine_i2s_type; From 61cb8832ce74401e49549a7774125861dc88299b Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 14:15:15 +0100 Subject: [PATCH 06/45] extmod/modtime: Add clock type. --- extmod/modtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extmod/modtime.c b/extmod/modtime.c index ee898828a4a..297dd6f8efb 100644 --- a/extmod/modtime.c +++ b/extmod/modtime.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "py/smallint.h" #include "extmod/modtime.h" +#include "py_clock.h" #if MICROPY_PY_TIME @@ -219,6 +220,7 @@ static const mp_rom_map_elem_t mp_module_time_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_time_ticks_cpu_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_time_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_time_ticks_diff_obj) }, + { MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&py_clock_type) }, #ifdef MICROPY_PY_TIME_EXTRA_GLOBALS MICROPY_PY_TIME_EXTRA_GLOBALS From b8b9bfd4ef9c8cb4f6c8c378bb0ad7f1ba9c3960 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 12:56:56 +0100 Subject: [PATCH 07/45] rp2: OpenMV build patch. --- ports/rp2/CMakeLists.txt | 4 +++- ports/rp2/Makefile | 2 +- ports/rp2/pendsv.h | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index c4a081e2efd..94c9050bc09 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -164,7 +164,6 @@ set(MICROPY_SOURCE_PORT machine_rtc.c machine_spi.c machine_timer.c - main.c modrp2.c mphalport.c mpnetworkport.c @@ -248,6 +247,7 @@ set(PICO_SDK_COMPONENTS pico_util tinyusb_common tinyusb_device + cmsis_core ) if(PICO_ARM) @@ -632,6 +632,8 @@ add_custom_command(TARGET ${MICROPY_TARGET} VERBATIM ) +include(${OMV_CMAKE}) + # Collect all the include directories and compile definitions for the pico-sdk components. foreach(comp ${PICO_SDK_COMPONENTS}) micropy_gather_target_properties(${comp}) diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index 2895faaca61..b1bc3d44b16 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -34,7 +34,7 @@ ifeq ($(BUILD_VERBOSE),1) MAKE_ARGS += VERBOSE=1 # Picked up in Makefile generated by CMake endif -CMAKE_ARGS += -DMICROPY_BOARD=$(BOARD) -DMICROPY_BOARD_DIR="$(abspath $(BOARD_DIR))" +CMAKE_ARGS = -DMICROPY_BOARD=$(BOARD) -DMICROPY_BOARD_DIR="$(abspath $(BOARD_DIR))" -DOMV_CMAKE=${OMV_CMAKE} ifdef USER_C_MODULES CMAKE_ARGS += -DUSER_C_MODULES=${USER_C_MODULES} diff --git a/ports/rp2/pendsv.h b/ports/rp2/pendsv.h index de89f0473e7..6abe950df63 100644 --- a/ports/rp2/pendsv.h +++ b/ports/rp2/pendsv.h @@ -42,6 +42,9 @@ enum { #define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX +// PendSV IRQ priority, to run system-level tasks that preempt the main thread. +#define IRQ_PRI_PENDSV PICO_LOWEST_IRQ_PRIORITY + typedef void (*pendsv_dispatch_t)(void); void pendsv_init(void); From e7d68b92e16c0680cfd525553e829c72fe41eac5 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 13:05:26 +0100 Subject: [PATCH 08/45] rp2/boards/ARDUINO_NANO_RP2040_CONNECT: Set USB PID. Signed-off-by: iabdalkader --- ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h index 11aa663296f..2dbe9dd8a94 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h @@ -20,7 +20,7 @@ // Enable USB Mass Storage with FatFS filesystem. #define MICROPY_HW_USB_MSC (1) #define MICROPY_HW_USB_VID (0x2341) -#define MICROPY_HW_USB_PID (0x025e) +#define MICROPY_HW_USB_PID (0x015e) #define MICROPY_HW_USB_CDC_1200BPS_TOUCH (1) // UART 1 config. From 21e35fe01e8f0e96b2ccd486932af8749699ee06 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 14:57:35 +0100 Subject: [PATCH 09/45] nrf: OpenMV build patch. --- ports/nrf/Makefile | 9 ++++----- ports/nrf/drivers/bluetooth/bluetooth_common.mk | 12 ++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 7b16974f970..1cf0a63b769 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -155,8 +155,8 @@ endif #Debugging/Optimization ifeq ($(DEBUG), 1) #ASMFLAGS += -g -gtabs+ -CFLAGS += -g -O0 -LDFLAGS += -O0 +CFLAGS += -Og -ggdb3 +LDFLAGS += -Og else ifneq ($(LTO), 1) CFLAGS += -g # always include debug info in the ELF, unless LTO is on @@ -225,7 +225,6 @@ SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\ ) SRC_C += \ - main.c \ mphalport.c \ help.c \ gccollect.c \ @@ -314,9 +313,9 @@ $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os .PHONY: all flash deploy sd binary hex ifeq ($(MCU_VARIANT), nrf91) -all: binary hex secureboot +all: $(OBJ) else -all: binary hex +all: $(OBJ) endif OUTPUT_FILENAME = firmware diff --git a/ports/nrf/drivers/bluetooth/bluetooth_common.mk b/ports/nrf/drivers/bluetooth/bluetooth_common.mk index dba00769602..7558be8b45c 100644 --- a/ports/nrf/drivers/bluetooth/bluetooth_common.mk +++ b/ports/nrf/drivers/bluetooth/bluetooth_common.mk @@ -3,19 +3,19 @@ SOFTDEV_HEX_NAME ?= SOFTDEV_HEX_PATH ?= ifeq ($(SD), s110) - INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include + INC += -I$(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include CFLAGS += -DBLUETOOTH_SD_DEBUG=1 CFLAGS += -DBLUETOOTH_SD=110 else ifeq ($(SD), s132) - INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include - INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) + INC += -I$(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include + INC += -I$(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) CFLAGS += -DBLUETOOTH_SD_DEBUG=1 CFLAGS += -DBLUETOOTH_SD=132 else ifeq ($(SD), s140) - INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include - INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) + INC += -I$(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include + INC += -I$(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) CFLAGS += -DBLUETOOTH_SD_DEBUG=1 CFLAGS += -DBLUETOOTH_SD=140 else @@ -23,7 +23,7 @@ else endif SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex -SOFTDEV_HEX_PATH = drivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) +SOFTDEV_HEX_PATH = $(SD_DIR)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) define STACK_MISSING_ERROR From 7f8a90996ea4d96cc8be9ee9455404433e2688bd Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 14:55:06 +0100 Subject: [PATCH 10/45] nrf/boards/ARDUINO_NANO_33_BLE_SENSE: Set USB PID. - Set OpenMV PID. Signed-off-by: iabdalkader --- ports/nrf/boards/ARDUINO_NANO_33_BLE_SENSE/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/boards/ARDUINO_NANO_33_BLE_SENSE/mpconfigboard.h b/ports/nrf/boards/ARDUINO_NANO_33_BLE_SENSE/mpconfigboard.h index 65642bf2342..4091d5c3cc8 100644 --- a/ports/nrf/boards/ARDUINO_NANO_33_BLE_SENSE/mpconfigboard.h +++ b/ports/nrf/boards/ARDUINO_NANO_33_BLE_SENSE/mpconfigboard.h @@ -65,7 +65,7 @@ #define MICROPY_HW_PWM3_NAME "PWM3" #define MICROPY_HW_USB_VID (0x2341) -#define MICROPY_HW_USB_PID (0x025A) +#define MICROPY_HW_USB_PID (0x015A) #define MICROPY_HW_USB_CDC_1200BPS_TOUCH (1) void NANO33_board_early_init(void); From abfba6df27099157e5e758bdebfe86d02f766842 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 15:06:25 +0100 Subject: [PATCH 11/45] nrf: Set I2C IRQ priority. --- ports/nrf/modules/machine/i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/nrf/modules/machine/i2c.c b/ports/nrf/modules/machine/i2c.c index 6c2b3e94838..da11c31cf71 100644 --- a/ports/nrf/modules/machine/i2c.c +++ b/ports/nrf/modules/machine/i2c.c @@ -130,6 +130,7 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz config.frequency = freq; config.hold_bus_uninit = false; + config.interrupt_priority = 7; // First reset the TWI nrfx_twi_uninit(&self->p_twi); From 3ada29eb7b7a7586650f1086113c92900733e25b Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 15:34:16 +0100 Subject: [PATCH 12/45] mimxrt/boards: Add OpenMV boards. Signed-off-by: iabdalkader --- ports/mimxrt/boards/OPENMV_RT1060/manifest.py | 3 + .../boards/OPENMV_RT1060/mpconfigboard.h | 249 ++++++++++++++++++ .../boards/OPENMV_RT1060/mpconfigboard.mk | 24 ++ ports/mimxrt/boards/OPENMV_RT1060/pins.csv | 21 ++ .../boards/OPENMV_RT1060/wifi_nvram_1dx.h | 49 ++++ 5 files changed, 346 insertions(+) create mode 100644 ports/mimxrt/boards/OPENMV_RT1060/manifest.py create mode 100644 ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.h create mode 100644 ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.mk create mode 100644 ports/mimxrt/boards/OPENMV_RT1060/pins.csv create mode 100644 ports/mimxrt/boards/OPENMV_RT1060/wifi_nvram_1dx.h diff --git a/ports/mimxrt/boards/OPENMV_RT1060/manifest.py b/ports/mimxrt/boards/OPENMV_RT1060/manifest.py new file mode 100644 index 00000000000..107181c31ca --- /dev/null +++ b/ports/mimxrt/boards/OPENMV_RT1060/manifest.py @@ -0,0 +1,3 @@ +include("../manifest.py") + +require("bundle-networking") diff --git a/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.h b/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.h new file mode 100644 index 00000000000..07bfec5ec31 --- /dev/null +++ b/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.h @@ -0,0 +1,249 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2023 Ibrahim Abdelkader + * Copyright (c) 2023 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Board config for OpenMV-RT60. + */ + +#define MICROPY_HW_BOARD_NAME "OpenMV IMXRT1060" +#define MICROPY_HW_MCU_NAME "MIMXRT1062DVJ6A" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +extern void mimxrt_hal_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) mimxrt_hal_bootloader() + +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "openmvrt1060" + +#define MICROPY_PY_MACHINE_CAN (1) + +#define MICROPY_HW_USB_MSC (1) +#define MICROPY_HW_USB_VID 0x37c5 +#define MICROPY_HW_USB_PID 0x1060 + +#define MICROPY_HW_LED1_PIN (pin_GPIO_B0_10) +#define MICROPY_HW_LED2_PIN (pin_GPIO_B0_11) +#define MICROPY_HW_LED3_PIN (pin_GPIO_B1_14) + +#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) +#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) + +#define MICROPY_HW_NUM_PIN_IRQS (4 * 32 + 3) + +#define MICROPY_HW_SDCARD_SDMMC (1) + +// WiFi SDMMC +#define MICROPY_HW_SDIO_SDMMC (2) +#define MICROPY_HW_SDIO_CLK (pin_GPIO_AD_B1_09) +#define MICROPY_HW_SDIO_CMD (pin_GPIO_AD_B1_08) +#define MICROPY_HW_SDIO_D0 (pin_GPIO_SD_B1_03) +#define MICROPY_HW_SDIO_D1 (pin_GPIO_SD_B1_02) +#define MICROPY_HW_SDIO_D2 (pin_GPIO_AD_B1_06) +#define MICROPY_HW_SDIO_D3 (pin_GPIO_AD_B1_07) + +#define MICROPY_HW_WL_REG_ON (pin_GPIO_B0_14) +#define MICROPY_HW_WL_HOST_WAKE (pin_GPIO_B0_15) + +#define MICROPY_HW_BT_REG_ON (pin_GPIO_AD_B0_08) +#define MICROPY_HW_BT_HOST_WAKE (pin_GPIO_AD_B0_14) +#define MICROPY_HW_BT_DEV_WAKE (pin_GPIO_SD_B1_00) +#define MICROPY_HW_BT_CTS (pin_GPIO_AD_B1_04) + +#define MICROPY_HW_SDIO_CLK_ALT (6) +#define MICROPY_HW_SDIO_CMD_ALT (6) +#define MICROPY_HW_SDIO_D0_ALT (0) +#define MICROPY_HW_SDIO_D1_ALT (0) +#define MICROPY_HW_SDIO_D2_ALT (6) +#define MICROPY_HW_SDIO_D3_ALT (6) + +// Bluetooth config. +#define MICROPY_HW_BLE_UART_ID (0) +#define MICROPY_HW_BLE_UART_BASE (LPUART3) +#define MICROPY_HW_BLE_UART_BAUDRATE (115200) +#define MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY (2500000) +#define MICROPY_HW_BLE_UART_BAUDRATE_DOWNLOAD_FIRMWARE (2500000) + +// CYW43 config +#define CYW43_WIFI_NVRAM_INCLUDE_FILE "wifi_nvram_1dx.h" + +// SDRAM config +#define MICROPY_HW_SDRAM_TIMING_TRC (60) +#define MICROPY_HW_SDRAM_TIMING_TRP (18) +#define MICROPY_HW_SDRAM_TIMING_TRCD (18) +#define MICROPY_HW_SDRAM_TIMING_TWR (12) +#define MICROPY_HW_SDRAM_TIMING_TRRD (60) +#define MICROPY_HW_SDRAM_TIMING_TXSR (67) +#define MICROPY_HW_SDRAM_TIMING_TRAS (42) +#define MICROPY_HW_SDRAM_TIMING_TREF (64 * 1000000 / 8192) // 64ms/8192 + +#define MICROPY_HW_SDRAM_CAS_LATENCY (kSEMC_LatencyThree) +#define MICROPY_HW_SDRAM_MEM_BUS_WIDTH (kSEMC_PortSize16Bit) +#define MICROPY_HW_SDRAM_COLUMN_BITS_NUM (kSEMC_SdramColunm_9bit) +#define MICROPY_HW_SDRAM_BURST_LENGTH (kSEMC_Sdram_BurstLen8) +#define MICROPY_HW_SDRAM_RBURST_LENGTH (1) + +// Define the mapping hardware UART # to logical UART # +// Bus HW-UART Logical UART +// BLE LPUART3 -> 0 +// External LPUART1 -> 1 + +#define MICROPY_HW_UART_NUM (sizeof(uart_index_table) / sizeof(uart_index_table)[0]) +#define MICROPY_HW_UART_INDEX { 3, 1 } + +#define IOMUX_TABLE_UART \ + { IOMUXC_GPIO_AD_B0_12_LPUART1_TX }, { IOMUXC_GPIO_AD_B0_13_LPUART1_RX }, \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_B0_08_LPUART3_TX }, { IOMUXC_GPIO_B0_09_LPUART3_RX }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, + +#define IOMUX_TABLE_UART_CTS_RTS \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B1_04_LPUART3_CTS_B }, { IOMUXC_GPIO_AD_B1_05_LPUART3_RTS_B }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, + +// Define the mapping hardware SPI # to logical SPI # +// Bus HW-SPI Logical SPI +// Camera LPSPI4 -> 0 +// External LPSPI3 -> 1 + +#define MICROPY_HW_SPI_INDEX { 4, 3 } + +#define IOMUX_TABLE_SPI \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, { 0 }, \ + { 0 }, \ + { IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0 }, \ + { IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI }, \ + { 0 }, \ + { IOMUXC_GPIO_B0_03_LPSPI4_SCK }, { IOMUXC_GPIO_B0_00_LPSPI4_PCS0 }, \ + { IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI }, \ + { 0 }, + +#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \ + kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx } + +#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx, \ + kDmaRequestMuxLPSPI3Tx, kDmaRequestMuxLPSPI4Tx } + +// Define the mapping hardware I2C # to logical I2C # +// Bus HW-I2C Logical I2C +// Camera LPI2C1 -> 0 +// External LPI2C4 -> 1 +// Internal LPI2C2 -> 2 + +#define MICROPY_HW_I2C_INDEX { 1, 4, 2 } + +#define IOMUX_TABLE_I2C \ + { IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL }, { IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA }, \ + { IOMUXC_GPIO_B0_04_LPI2C2_SCL }, { IOMUXC_GPIO_B0_05_LPI2C2_SDA }, \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL }, { IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA }, + +// Define the mapping hardware CAN # to logical CAN # +// Bus HW-CAN Logical CAN +// External FLEXCAN2 -> 0 + +#define MICROPY_HW_CAN_INDEX { 2 } +#define MICROPY_HW_NUM_CAN_IRQS (1) + +#define IOMUX_TABLE_CAN \ + { 0 }, { 0 }, \ + { IOMUXC_GPIO_AD_B0_02_FLEXCAN2_TX }, { IOMUXC_GPIO_AD_B0_03_FLEXCAN2_RX }, + +#define USDHC_DUMMY_PIN NULL, 0 +#define MICROPY_USDHC1 \ + { \ + .cmd = {GPIO_SD_B0_00_USDHC1_CMD}, \ + .clk = { GPIO_SD_B0_01_USDHC1_CLK }, \ + .cd_b = { GPIO_AD_B1_02_USDHC1_CD_B }, \ + .data0 = { GPIO_SD_B0_02_USDHC1_DATA0 }, \ + .data1 = { GPIO_SD_B0_03_USDHC1_DATA1 }, \ + .data2 = { GPIO_SD_B0_04_USDHC1_DATA2 }, \ + .data3 = { GPIO_SD_B0_05_USDHC1_DATA3 }, \ + } + +// --- SEMC --- // +#define MIMXRT_IOMUXC_SEMC_DATA00 IOMUXC_GPIO_EMC_00_SEMC_DATA00 +#define MIMXRT_IOMUXC_SEMC_DATA01 IOMUXC_GPIO_EMC_01_SEMC_DATA01 +#define MIMXRT_IOMUXC_SEMC_DATA02 IOMUXC_GPIO_EMC_02_SEMC_DATA02 +#define MIMXRT_IOMUXC_SEMC_DATA03 IOMUXC_GPIO_EMC_03_SEMC_DATA03 +#define MIMXRT_IOMUXC_SEMC_DATA04 IOMUXC_GPIO_EMC_04_SEMC_DATA04 +#define MIMXRT_IOMUXC_SEMC_DATA05 IOMUXC_GPIO_EMC_05_SEMC_DATA05 +#define MIMXRT_IOMUXC_SEMC_DATA06 IOMUXC_GPIO_EMC_06_SEMC_DATA06 +#define MIMXRT_IOMUXC_SEMC_DATA07 IOMUXC_GPIO_EMC_07_SEMC_DATA07 +#define MIMXRT_IOMUXC_SEMC_DATA08 IOMUXC_GPIO_EMC_30_SEMC_DATA08 +#define MIMXRT_IOMUXC_SEMC_DATA09 IOMUXC_GPIO_EMC_31_SEMC_DATA09 +#define MIMXRT_IOMUXC_SEMC_DATA10 IOMUXC_GPIO_EMC_32_SEMC_DATA10 +#define MIMXRT_IOMUXC_SEMC_DATA11 IOMUXC_GPIO_EMC_33_SEMC_DATA11 +#define MIMXRT_IOMUXC_SEMC_DATA12 IOMUXC_GPIO_EMC_34_SEMC_DATA12 +#define MIMXRT_IOMUXC_SEMC_DATA13 IOMUXC_GPIO_EMC_35_SEMC_DATA13 +#define MIMXRT_IOMUXC_SEMC_DATA14 IOMUXC_GPIO_EMC_36_SEMC_DATA14 +#define MIMXRT_IOMUXC_SEMC_DATA15 IOMUXC_GPIO_EMC_37_SEMC_DATA15 + +#define MIMXRT_IOMUXC_SEMC_ADDR00 IOMUXC_GPIO_EMC_09_SEMC_ADDR00 +#define MIMXRT_IOMUXC_SEMC_ADDR01 IOMUXC_GPIO_EMC_10_SEMC_ADDR01 +#define MIMXRT_IOMUXC_SEMC_ADDR02 IOMUXC_GPIO_EMC_11_SEMC_ADDR02 +#define MIMXRT_IOMUXC_SEMC_ADDR03 IOMUXC_GPIO_EMC_12_SEMC_ADDR03 +#define MIMXRT_IOMUXC_SEMC_ADDR04 IOMUXC_GPIO_EMC_13_SEMC_ADDR04 +#define MIMXRT_IOMUXC_SEMC_ADDR05 IOMUXC_GPIO_EMC_14_SEMC_ADDR05 +#define MIMXRT_IOMUXC_SEMC_ADDR06 IOMUXC_GPIO_EMC_15_SEMC_ADDR06 +#define MIMXRT_IOMUXC_SEMC_ADDR07 IOMUXC_GPIO_EMC_16_SEMC_ADDR07 +#define MIMXRT_IOMUXC_SEMC_ADDR08 IOMUXC_GPIO_EMC_17_SEMC_ADDR08 +#define MIMXRT_IOMUXC_SEMC_ADDR09 IOMUXC_GPIO_EMC_18_SEMC_ADDR09 +#define MIMXRT_IOMUXC_SEMC_ADDR10 IOMUXC_GPIO_EMC_23_SEMC_ADDR10 +#define MIMXRT_IOMUXC_SEMC_ADDR11 IOMUXC_GPIO_EMC_19_SEMC_ADDR11 +#define MIMXRT_IOMUXC_SEMC_ADDR12 IOMUXC_GPIO_EMC_20_SEMC_ADDR12 + +#define MIMXRT_IOMUXC_SEMC_BA0 IOMUXC_GPIO_EMC_21_SEMC_BA0 +#define MIMXRT_IOMUXC_SEMC_BA1 IOMUXC_GPIO_EMC_22_SEMC_BA1 +#define MIMXRT_IOMUXC_SEMC_CAS IOMUXC_GPIO_EMC_24_SEMC_CAS +#define MIMXRT_IOMUXC_SEMC_CKE IOMUXC_GPIO_EMC_27_SEMC_CKE +#define MIMXRT_IOMUXC_SEMC_CLK IOMUXC_GPIO_EMC_26_SEMC_CLK +#define MIMXRT_IOMUXC_SEMC_DM00 IOMUXC_GPIO_EMC_08_SEMC_DM00 +#define MIMXRT_IOMUXC_SEMC_DM01 IOMUXC_GPIO_EMC_38_SEMC_DM01 +#define MIMXRT_IOMUXC_SEMC_DQS IOMUXC_GPIO_EMC_39_SEMC_DQS +#define MIMXRT_IOMUXC_SEMC_RAS IOMUXC_GPIO_EMC_25_SEMC_RAS +#define MIMXRT_IOMUXC_SEMC_WE IOMUXC_GPIO_EMC_28_SEMC_WE + +#define MIMXRT_IOMUXC_SEMC_CS0 IOMUXC_GPIO_EMC_29_SEMC_CS0 + +// Network definitions +// Transceiver Phy Address +#define ENET_PHY_ADDRESS (0) +#define ENET_PHY_OPS phyksz8081_ops + +// Etherner PIN definitions +#define ENET_RESET_PIN &pin_GPIO_B0_13 +#define ENET_INT_PIN &pin_GPIO_B0_12 + +#define IOMUX_TABLE_ENET \ + { IOMUXC_GPIO_B1_04_ENET_RX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_05_ENET_RX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_06_ENET_RX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_07_ENET_TX_DATA00, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_08_ENET_TX_DATA01, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_09_ENET_TX_EN, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_B1_10_ENET_REF_CLK, 1, 0x71u }, \ + { IOMUXC_GPIO_B1_11_ENET_RX_ER, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_41_ENET_MDIO, 0, 0xB0E9u }, \ + { IOMUXC_GPIO_EMC_40_ENET_MDC, 0, 0xB0E9u }, + +// USB CDC config +#define CFG_TUD_CDC_EP_BUFSIZE (4096) +#define CFG_TUD_CDC_RX_BUFSIZE (4096) +#define CFG_TUD_CDC_TX_BUFSIZE (4096) diff --git a/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.mk b/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.mk new file mode 100644 index 00000000000..466621a8d59 --- /dev/null +++ b/ports/mimxrt/boards/OPENMV_RT1060/mpconfigboard.mk @@ -0,0 +1,24 @@ +MCU_SERIES = MIMXRT1062 +MCU_VARIANT = MIMXRT1062DVJ6A + +MICROPY_FLOAT_IMPL = single +MICROPY_HW_FLASH_TYPE = qspi_nor_flash +MICROPY_HW_FLASH_SIZE = 0x1000000 # 16MB +MICROPY_HW_FLASH_CLK = kFlexSpiSerialClk_133MHz +MICROPY_HW_FLASH_QE_CMD = 0x01 +MICROPY_HW_FLASH_QE_ARG = 0x40 + +MICROPY_HW_SDRAM_AVAIL = 1 +MICROPY_HW_SDRAM_SIZE = 0x2000000 # 32MB + +MICROPY_PY_MACHINE_SDCARD ?= 1 +MICROPY_PY_LWIP = 1 +MICROPY_PY_USSL = 1 +MICROPY_SSL_MBEDTLS = 1 +MICROPY_PY_NETWORK_CYW43 = 1 +MICROPY_PY_NETWORK_PHYKSZ8081RND = 1 +MICROPY_PY_BLUETOOTH = 1 +MICROPY_BLUETOOTH_NIMBLE = 1 +MICROPY_BLUETOOTH_BTSTACK = 0 + +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py diff --git a/ports/mimxrt/boards/OPENMV_RT1060/pins.csv b/ports/mimxrt/boards/OPENMV_RT1060/pins.csv new file mode 100644 index 00000000000..48abe8d4dce --- /dev/null +++ b/ports/mimxrt/boards/OPENMV_RT1060/pins.csv @@ -0,0 +1,21 @@ +P0,GPIO_AD_B0_01 +P1,GPIO_AD_B0_02 +P2,GPIO_AD_B0_00 +P3,GPIO_AD_B0_03 +P4,GPIO_AD_B0_12 +P5,GPIO_AD_B0_13 +P6,GPIO_AD_B1_03 +P7,GPIO_B0_06 +P8,GPIO_B0_07 +P9,GPIO_B1_00 +P10,GPIO_SD_B1_01 +P11,WAKEUP +P13,GPIO_AD_B0_11 +P14,GPIO_AD_B0_09 +LED_RED,GPIO_B0_10 +LED_GREEN,GPIO_B0_11 +LED_BLUE,GPIO_B1_14 +CHG,GPIO_AD_B0_11 +PG,GPIO_SD_B1_04 +ST,GPIO_AD_B0_09 +SW,PMIC_STBY_REQ diff --git a/ports/mimxrt/boards/OPENMV_RT1060/wifi_nvram_1dx.h b/ports/mimxrt/boards/OPENMV_RT1060/wifi_nvram_1dx.h new file mode 100644 index 00000000000..61b4d34e25e --- /dev/null +++ b/ports/mimxrt/boards/OPENMV_RT1060/wifi_nvram_1dx.h @@ -0,0 +1,49 @@ +static const uint8_t wifi_nvram_4343[] CYW43_RESOURCE_ATTRIBUTE = + // Type1DX_Final_nvram2.txt + // 2.4 GHz, 20 MHz BW mode + "manfid=0x2d0\x00" + "prodid=0x0726\x00" + "vendid=0x14e4\x00" + "devid=0x43e2\x00" + "boardtype=0x0726\x00" + "boardrev=0x1202\x00" + "boardnum=22\x00" + "macaddr=00:90:4c:c5:12:38\x00" + "sromrev=11\x00" + "boardflags=0x00404201\x00" + "boardflags3=0x08000000\x00" + "xtalfreq=37400\x00" + "nocrc=1\x00" + "ag0=0\x00" + "aa2g=1\x00" + "ccode=ALL\x00" + // "pa0itssit=0x20\x00" + "extpagain2g=0\x00" + "pa2ga0=-145,6667,-751\x00" + "AvVmid_c0=0x0,0xc8\x00" + "cckpwroffset0=2\x00" + "maxp2ga0=74\x00" + // "txpwrbckof=6\x00" + "cckbw202gpo=0\x00" + "legofdmbw202gpo=0x88888888\x00" + "mcsbw202gpo=0xaaaaaaaa\x00" + "propbw202gpo=0xdd\x00" + "ofdmdigfilttype=18\x00" + "ofdmdigfilttypebe=18\x00" + "papdmode=1\x00" + "papdvalidtest=1\x00" + "pacalidx2g=48\x00" + "papdepsoffset=-22\x00" + "papdendidx=58\x00" + "il0macaddr=00:90:4c:c5:12:38\x00" + "wl0id=0x431b\x00" + "muxenab=0x10\x00" + // BT COEX deferral limit setting + // "btc_params 8 45000\x00" + // "btc_params 10 20000\x00" + // "spurconfig=0x3\x00" + // Antenna diversity + "swdiv_en=1\x00" + "swdiv_gpio=1\x00" + "\x00\x00" +; From d58369d7358d3a339ea2a8aec6a7a4a0e806b810 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 16:35:21 +0100 Subject: [PATCH 13/45] mimxrt: OpenMV build patch. --- ports/mimxrt/Makefile | 33 ++++++++++++++------------------- ports/mimxrt/mpconfigport.h | 5 ++++- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index fea7e56da22..c19cb20e7fb 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -53,7 +53,7 @@ include $(TOP)/extmod/extmod.mk # Set SDK directory based on MCU_SERIES MCUX_SDK_DIR = lib/nxp_driver/sdk -MCU_DIR = $(MCUX_SDK_DIR)/devices/$(MCU_SERIES) +MCU_DIR ?= $(MCUX_SDK_DIR)/devices/$(MCU_SERIES) # Select linker scripts based on MCU_SERIES LD_FILES = boards/$(MCU_SERIES).ld boards/common.ld @@ -243,7 +243,6 @@ SRC_C += \ eth.c \ fatfs_port.c \ flash.c \ - hal/fsl_lpuart.c \ hal/pwm_backport.c \ help.c \ led.c \ @@ -254,7 +253,6 @@ SRC_C += \ machine_rtc.c \ machine_sdcard.c \ machine_spi.c \ - main.c \ mbedtls/mbedtls_port.c \ mimxrt_flash.c \ mimxrt_sdram.c \ @@ -360,8 +358,8 @@ else endif # Reset variables -SUPPORTS_HARDWARE_FP_SINGLE = 0 -SUPPORTS_HARDWARE_FP_DOUBLE = 0 +SUPPORTS_HARDWARE_FP_SINGLE ?= 0 +SUPPORTS_HARDWARE_FP_DOUBLE ?= 0 # Assembly source files SRC_SS = \ @@ -406,6 +404,7 @@ CFLAGS += \ -DBOARD_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ -DCFG_TUSB_MCU=OPT_MCU_MIMXRT1XXX \ -DCFG_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED \ + -DCFG_TUD_TASK_QUEUE_SZ=128 \ -DCLOCK_CONFIG_H='' \ -DCPU_$(MCU_SERIES)$(MCU_CORE) \ -DCPU_$(MCU_VARIANT) \ @@ -423,11 +422,10 @@ CFLAGS += \ -mthumb \ -mtune=cortex-m7 \ -nostdlib \ - -std=c99 \ + -std=gnu99 \ -Wall \ -Wdouble-promotion \ -Werror \ - -Wfloat-conversion \ -Wno-error=unused-parameter # Configure respective board flash type @@ -446,7 +444,7 @@ ifeq ($(MICROPY_FLOAT_IMPL),single) CFLAGS += \ -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT \ -fsingle-precision-constant \ - -mfloat-abi=softfp \ + -mfloat-abi=hard \ -mfpu=fpv5-sp-d16 else ifeq ($(MICROPY_FLOAT_IMPL),double) CFLAGS += \ @@ -463,12 +461,13 @@ endif # All settings for Ethernet support are controller by the value of MICROPY_PY_LWIP ifeq ($(MICROPY_PY_LWIP),1) -CFLAGS += \ - -DFSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE=1 +ifeq ($(MICROPY_PY_NETWORK_PHYKSZ8081RND),0) +CFLAGS += -DFSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE=1 +endif endif ifdef MICROPY_HW_FLASH_CLK - CFLAGS += -DMICROPY_HW_FLASH_CLK=$(MICROPY_HW_FLASH_CLK) +CFLAGS += -DMICROPY_HW_FLASH_CLK=$(MICROPY_HW_FLASH_CLK) endif ifdef MICROPY_HW_FLASH_QE_CMD CFLAGS += -DMICROPY_HW_FLASH_QE_CMD=$(MICROPY_HW_FLASH_QE_CMD) @@ -534,11 +533,7 @@ $(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces # Build targets # ============================================================================= -ifeq ($(USE_UF2_BOOTLOADER),1) -all: $(BUILD)/firmware.hex $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 -else -all: $(BUILD)/firmware.hex $(BUILD)/firmware.bin -endif +all: $(OBJ) # Process linker scripts with C preprocessor to exchange LDDEFINES and # aggregate output of preprocessor in a single linker script `link.ld` @@ -572,15 +567,15 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h $(GEN_FLEXRAM_CONFIG_SRC): $(HEADER_BUILD) $(ECHO) "Create $@" - $(Q)$(PYTHON) $(MAKE_FLEXRAM_LD) -d $(TOP)/$(MCU_DIR)/$(MCU_SERIES)$(MCU_CORE).h \ - -f $(TOP)/$(MCU_DIR)/$(MCU_SERIES)$(MCU_CORE)_features.h -l boards/$(MCU_SERIES).ld -c $(MCU_SERIES) > $@ + $(Q)$(PYTHON) $(MAKE_FLEXRAM_LD) -d $(CMSIS_DIR)/include/mimxrt/$(MCU_SERIES)$(MCU_CORE).h \ + -f $(MCU_DIR)/$(MCU_SERIES)$(MCU_CORE)_features.h -l boards/$(MCU_SERIES).ld -c $(MCU_SERIES) > $(GEN_FLEXRAM_CONFIG_SRC) # 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-csv $(BOARD_PINS) --af-csv $(AF_FILE) \ - --prefix $(PREFIX_FILE) --iomux "$(abspath $(TOP)/$(MCU_DIR)/drivers/fsl_iomuxc.h)" \ + --prefix $(PREFIX_FILE) --iomux $(abspath $(MCU_DIR)/drivers/fsl_iomuxc.h) \ --output-source $(GEN_PINS_SRC) --output-header $(GEN_PINS_HDR) include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 0a623a63187..61c987e92ba 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -57,9 +57,13 @@ uint32_t trng_random_u32(void); #define MICROPY_STACK_CHECK_MARGIN (1024) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) +#endif #define MICROPY_SCHEDULER_DEPTH (8) #define MICROPY_SCHEDULER_STATIC_NODES (1) #define MICROPY_VFS (1) +#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool // Control over Python builtins #define MICROPY_PY_BUILTINS_HELP_TEXT mimxrt_help_text @@ -72,7 +76,6 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_TIME_INCLUDEFILE "ports/mimxrt/modtime.c" #define MICROPY_PY_OS_INCLUDEFILE "ports/mimxrt/modos.c" #define MICROPY_PY_OS_DUPTERM (3) -#define MICROPY_PY_OS_DUPTERM_NOTIFY (1) #define MICROPY_PY_OS_SYNC (1) #define MICROPY_PY_OS_UNAME (1) #define MICROPY_PY_OS_URANDOM (1) From 5c8cac171bb826f5ae75fde48c4cdec8bbf33864 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 29 Nov 2024 15:33:20 +0100 Subject: [PATCH 14/45] mimxrt: Add machine.CAN implementation. --- ports/mimxrt/Makefile | 5 + ports/mimxrt/README.md | 3 +- ports/mimxrt/machine_can.c | 928 ++++++++++++++++++++++++++++++++++++ ports/mimxrt/main.c | 3 + ports/mimxrt/modmachine.h | 1 + ports/mimxrt/mpconfigport.h | 3 + 6 files changed, 942 insertions(+), 1 deletion(-) create mode 100644 ports/mimxrt/machine_can.c diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index c19cb20e7fb..b3e74ce6076 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -181,6 +181,10 @@ SRC_HAL_IMX_C += $(MCUX_SDK_DIR)/drivers/usdhc/fsl_usdhc.c INC_HAL_IMX += -I$(TOP)/$(MCUX_SDK_DIR)/drivers/usdhc endif +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES), MIMXRT1021 MIMXRT1052 MIMXRT1062 MIMXRT1064 MIMXRT1176)) +SRC_HAL_IMX_C += $(MCU_DIR)/drivers/fsl_flexcan.c +endif + ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES), MIMXRT1015 MIMXRT1021 MIMXRT1052 MIMXRT1062 MIMXRT1064 MIMXRT1176)) SRC_HAL_IMX_C += \ $(MCUX_SDK_DIR)/drivers/qtmr_1/fsl_qtmr.c \ @@ -247,6 +251,7 @@ SRC_C += \ help.c \ led.c \ machine_bitstream.c \ + machine_can.c \ machine_i2c.c \ machine_led.c \ machine_pin.c \ diff --git a/ports/mimxrt/README.md b/ports/mimxrt/README.md index de3de1e2817..a578db00261 100644 --- a/ports/mimxrt/README.md +++ b/ports/mimxrt/README.md @@ -8,6 +8,7 @@ MIMXRT1064_EVK boards. Features: - REPL over USB VCP - machine.ADC + - machine.CAN - machine.I2C - machine.LED - machine.Pin @@ -27,7 +28,7 @@ Features: Known issues: TODO: - - More peripherals (Counter, I2S, CAN, etc) + - More peripherals (Counter, I2S, etc) - More Python options ## Build Instructions diff --git a/ports/mimxrt/machine_can.c b/ports/mimxrt/machine_can.c new file mode 100644 index 00000000000..12e3786e122 --- /dev/null +++ b/ports/mimxrt/machine_can.c @@ -0,0 +1,928 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Kwabena W. Agyeman + * + * 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/objarray.h" +#include "py/runtime.h" +#include "py/gc.h" +#include "py/binary.h" +#include "py/stream.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "shared/runtime/mpirq.h" +#include CLOCK_CONFIG_H +#include "extmod/modmachine.h" +#include "modmachine.h" + +#include "fsl_iomuxc.h" + +#if MICROPY_PY_MACHINE_CAN +#include "fsl_flexcan.h" + +#define CAN_MAX_DATA_FRAME (8) + +#define CAN_NORMAL_MODE (0) +#define CAN_LOOPBACK_FLAG (1) +#define CAN_SILENT_FLAG (2) + +#define CAN_DUAL (0) + +// matches fsl_flexcan.c enum _flexcan_mb_code_tx +#define kFLEXCAN_TxMbDataOrRemote (0xC) + +enum { + CAN_STATE_STOPPED, + CAN_STATE_ERROR_ACTIVE, + CAN_STATE_ERROR_WARNING, + CAN_STATE_ERROR_PASSIVE, + CAN_STATE_BUS_OFF, +}; + +#define MICROPY_HW_CAN_NUM MP_ARRAY_SIZE(can_index_table) + +#define CTX (iomux_table[index]) +#define CRX (iomux_table[index + 1]) + +typedef struct _machine_can_obj_t { + mp_obj_base_t base; + uint8_t can_id; + uint8_t can_hw_id; + CAN_Type *can_inst; + flexcan_config_t *flexcan_config; + flexcan_rx_fifo_config_t *flexcan_rx_fifo_config; + uint8_t flexcan_txmb_start; + uint8_t flexcan_txmb_count; + mp_obj_t callback; + bool is_enabled; + uint16_t num_error_warning; + uint16_t num_error_passive; + uint16_t num_bus_off; +} machine_can_obj_t; + +typedef struct _iomux_table_t { + uint32_t muxRegister; + uint32_t muxMode; + uint32_t inputRegister; + uint32_t inputDaisy; + uint32_t configRegister; +} iomux_table_t; + +static const uint8_t can_index_table[] = MICROPY_HW_CAN_INDEX; +#ifdef MIMXRT117x_SERIES +static const uint32_t can_clock_index_table[] = { + BOARD_BOOTCLOCKRUN_CAN1_CLK_ROOT, + BOARD_BOOTCLOCKRUN_CAN2_CLK_ROOT, + BOARD_BOOTCLOCKRUN_CAN3_CLK_ROOT +}; +#endif +static CAN_Type *can_base_ptr_table[] = CAN_BASE_PTRS; +static const iomux_table_t iomux_table[] = { + IOMUX_TABLE_CAN +}; + +bool can_set_iomux(int8_t can) { + int index = (can - 1) * 2; + + if (CTX.muxRegister != 0) { + IOMUXC_SetPinMux(CTX.muxRegister, CTX.muxMode, CTX.inputRegister, CTX.inputDaisy, CTX.configRegister, 0U); + IOMUXC_SetPinConfig(CTX.muxRegister, CTX.muxMode, CTX.inputRegister, CTX.inputDaisy, CTX.configRegister, + pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, PIN_DRIVE_6, CTX.configRegister)); + + IOMUXC_SetPinMux(CRX.muxRegister, CRX.muxMode, CRX.inputRegister, CRX.inputDaisy, CRX.configRegister, 0U); + IOMUXC_SetPinConfig(CRX.muxRegister, CRX.muxMode, CRX.inputRegister, CRX.inputDaisy, CRX.configRegister, + pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_IN, PIN_DRIVE_6, CRX.configRegister)); + + return true; + } else { + return false; + } +} + +void machine_can_irq_handler(CAN_Type *base) { + machine_can_obj_t *self = NULL; + for (int i = 0; i < MICROPY_HW_NUM_CAN_IRQS; ++i) { + machine_can_obj_t *machine_can_obj = MP_STATE_PORT(machine_can_objects[i]); + if ((machine_can_obj != NULL) && (machine_can_obj->can_inst == base)) { + self = machine_can_obj; + break; + } + } + if (self != NULL) { + uint32_t result = FLEXCAN_GetStatusFlags(self->can_inst); + if (result & FLEXCAN_ERROR_AND_STATUS_INIT_FLAG) { + uint32_t flt_conf = (result & CAN_ESR1_FLTCONF_MASK) >> CAN_ESR1_FLTCONF_SHIFT; + if (flt_conf > 1) { + ++self->num_bus_off; + } else if (flt_conf == 1) { + ++self->num_error_passive; + } else if ((result & CAN_ESR1_RXWRN_MASK) || (result & CAN_ESR1_TXWRN_MASK)) { + ++self->num_error_warning; + } + FLEXCAN_ClearStatusFlags(self->can_inst, FLEXCAN_ERROR_AND_STATUS_INIT_FLAG); + } + + mp_int_t irq_reason = -1; + + if (FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoOverflowFlag)) { + FLEXCAN_DisableMbInterrupts(self->can_inst, + kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag); + irq_reason = 2; + } else if (FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoWarningFlag)) { + FLEXCAN_DisableMbInterrupts(self->can_inst, kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag); + irq_reason = 1; + } else if (FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)) { + FLEXCAN_DisableMbInterrupts(self->can_inst, kFLEXCAN_RxFifoFrameAvlFlag); + irq_reason = 0; + } + + if (irq_reason != -1 && self->callback != mp_const_none) { + mp_sched_lock(); + gc_lock(); + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_call_function_2(self->callback, MP_OBJ_FROM_PTR(self), MP_OBJ_NEW_SMALL_INT(irq_reason)); + nlr_pop(); + } else { + // Uncaught exception; disable the callback so it doesn't run again. + self->callback = mp_const_none; + mp_printf(MICROPY_ERROR_PRINTER, "uncaught exception in CAN(%u) rx interrupt handler\n", self->can_id); + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + } + gc_unlock(); + mp_sched_unlock(); + } + } +} + +#if defined(CAN1) +void CAN1_IRQHandler(void) { + machine_can_irq_handler(CAN1); +} +#endif + +#if defined(CAN2) +void CAN2_IRQHandler(void) { + machine_can_irq_handler(CAN2); +} +#endif + +#if defined(CAN3) +void CAN3_IRQHandler(void) { + machine_can_irq_handler(CAN3); +} +#endif + +static void machine_flexcan_deinit(machine_can_obj_t *self) { + if (MP_STATE_PORT(machine_can_objects[self->can_id]) != NULL) { + mp_uint_t instance = FLEXCAN_GetInstance(self->can_inst); + DisableIRQ(((IRQn_Type [])CAN_Rx_Warning_IRQS)[instance]); + DisableIRQ(((IRQn_Type [])CAN_Tx_Warning_IRQS)[instance]); + DisableIRQ(((IRQn_Type [])CAN_Error_IRQS)[instance]); + DisableIRQ(((IRQn_Type [])CAN_Bus_Off_IRQS)[instance]); + DisableIRQ(((IRQn_Type [])CAN_ORed_Message_buffer_IRQS)[instance]); + FLEXCAN_DisableInterrupts(self->can_inst, + kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable | + kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable); + FLEXCAN_DisableMbInterrupts(self->can_inst, + kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag); + MP_STATE_PORT(machine_can_objects[self->can_id]) = NULL; + self->is_enabled = false; + FLEXCAN_Deinit(self->can_inst); + } +} + +// Deinit all can IRQ handlers. +void machine_can_irq_deinit(void) { + for (int i = 0; i < MICROPY_HW_NUM_CAN_IRQS; ++i) { + machine_can_obj_t *machine_can_obj = MP_STATE_PORT(machine_can_objects[i]); + if (machine_can_obj != NULL) { + machine_flexcan_deinit(machine_can_obj); + } + } +} + +static void machine_can_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->is_enabled) { + mp_printf(print, "CAN(%u)", self->can_id); + } else { + qstr mode = MP_QSTR_NORMAL; + if (self->flexcan_config->enableLoopBack) { + if (self->flexcan_config->enableListenOnlyMode) { + mode = MP_QSTR_SILENT_LOOPBACK; + } else { + mode = MP_QSTR_LOOPBACK; + } + } else if (self->flexcan_config->enableListenOnlyMode) { + mode = MP_QSTR_SILENT; + } + mp_printf(print, "CAN(%u, mode=CAN.%q, auto_restart=%q, baudrate=%u)", + self->can_id, + mode, + (self->can_inst->CTRL1 & CAN_CTRL1_BOFFREC_MASK) ? MP_QSTR_False : MP_QSTR_True, + self->flexcan_config->bitRate); + } +} + +static mp_obj_t machine_can_init_helper(machine_can_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_auto_restart, ARG_baudrate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = CAN_NORMAL_MODE} }, + { MP_QSTR_auto_restart, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + + // Parse the arguments. + 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); + + machine_flexcan_deinit(self); + + // Initialise the CAN peripheral. + self->flexcan_config->enableLoopBack = args[ARG_mode].u_int & CAN_LOOPBACK_FLAG; + self->flexcan_config->enableListenOnlyMode = args[ARG_mode].u_int & CAN_SILENT_FLAG; + self->flexcan_config->bitRate = args[ARG_baudrate].u_int; + + // When selecting the CCM CAN clock source with CAN_CLK_SEL set to 2, the UART clock gate + // will not open and CAN_CLK_ROOT will be off. To avoid this issue, set CAN_CLK_SEL to 0 or + // 1 for CAN clock selection, or open the UART clock gate by configuring the CCM_CCGRx register. + // There are two workarounds: + // Set CAN_CLK_SEL to 0 or 1 for CAN clock selection, or if CAN_CLK_SEL is set to 2, + // then the CCM must open any of UART clock gate by configuring the CCM_CCGRx register. + #if (defined(FSL_FEATURE_CCM_HAS_ERRATA_50235) && FSL_FEATURE_CCM_HAS_ERRATA_50235) + CLOCK_EnableClock(kCLOCK_Lpuart1); + #endif // FSL_FEATURE_CCM_HAS_ERRATA_50235 + + uint32_t sourceClock_Hz; + #ifdef MIMXRT117x_SERIES + sourceClock_Hz = can_clock_index_table[self->can_hw_id]; + #else + sourceClock_Hz = BOARD_BOOTCLOCKRUN_CAN_CLK_ROOT; + #endif + + FLEXCAN_Init(self->can_inst, self->flexcan_config, sourceClock_Hz); + memset(self->flexcan_rx_fifo_config->idFilterTable, 0, + sizeof(uint32_t) * self->flexcan_rx_fifo_config->idFilterNum); + FLEXCAN_SetRxFifoConfig(self->can_inst, self->flexcan_rx_fifo_config, true); + + // Calculate the Number of Mailboxes occupied by RX Legacy FIFO and the filter. + mp_uint_t rffn = (uint8_t)((self->can_inst->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT); + self->flexcan_txmb_start = 6U + (rffn + 1U) * 2U; + #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ + (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) + // the first valid MB should be occupied by ERRATA 5461 or 5829. + self->flexcan_txmb_start += 1U; + #endif + self->flexcan_txmb_count = self->flexcan_config->maxMbNum - self->flexcan_txmb_start; + + for (mp_uint_t i = 0; i < self->flexcan_txmb_count; i++) { + FLEXCAN_SetTxMbConfig(self->can_inst, self->flexcan_txmb_start + i, true); + } + + if (!args[ARG_auto_restart].u_bool) { + self->can_inst->CTRL1 |= CAN_CTRL1_BOFFREC_MASK; + } else { + self->can_inst->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK; + } + + self->callback = mp_const_none; + self->is_enabled = true; + self->num_error_warning = 0; + self->num_error_passive = 0; + self->num_bus_off = 0; + + MP_STATE_PORT(machine_can_objects[self->can_id]) = self; + + FLEXCAN_EnableMbInterrupts(self->can_inst, + kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag); + + FLEXCAN_EnableInterrupts(self->can_inst, + kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable | + kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable); + + mp_uint_t instance = FLEXCAN_GetInstance(self->can_inst); + EnableIRQ(((IRQn_Type [])CAN_Rx_Warning_IRQS)[instance]); + EnableIRQ(((IRQn_Type [])CAN_Tx_Warning_IRQS)[instance]); + EnableIRQ(((IRQn_Type [])CAN_Error_IRQS)[instance]); + EnableIRQ(((IRQn_Type [])CAN_Bus_Off_IRQS)[instance]); + EnableIRQ(((IRQn_Type [])CAN_ORed_Message_buffer_IRQS)[instance]); + + return MP_OBJ_FROM_PTR(self); +} + +// CAN(bus, ...) +mp_obj_t machine_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // Get the CAN bus id. + int can_id = mp_obj_get_int(args[0]); + if (can_id < 0 || can_id >= MP_ARRAY_SIZE(can_index_table) || can_index_table[can_id] == 0) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("CAN(%d) doesn't exist"), can_id); + } + + // Get peripheral object. + mp_uint_t can_hw_id = can_index_table[can_id]; // the hw can number 1..n + machine_can_obj_t *self = mp_obj_malloc(machine_can_obj_t, &machine_can_type); + self->can_id = can_id; + self->can_inst = can_base_ptr_table[can_hw_id]; + self->can_hw_id = can_hw_id; + self->flexcan_config = m_new_obj(flexcan_config_t); + FLEXCAN_GetDefaultConfig(self->flexcan_config); + mp_uint_t maxMbNum = FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(self->can_inst); + self->flexcan_config->maxMbNum = maxMbNum; + self->flexcan_config->disableSelfReception = true; + + self->flexcan_rx_fifo_config = m_new_obj(flexcan_rx_fifo_config_t); + mp_uint_t idFilterNum = maxMbNum * 2; + self->flexcan_rx_fifo_config->idFilterNum = idFilterNum; + self->flexcan_rx_fifo_config->idFilterType = kFLEXCAN_RxFifoFilterTypeA; + self->flexcan_rx_fifo_config->priority = kFLEXCAN_RxFifoPrioHigh; + self->flexcan_rx_fifo_config->idFilterTable = m_new0(uint32_t, idFilterNum); + + // Configure board-specific pin MUX based on the hardware device number. + bool can_present = can_set_iomux(can_hw_id); + + if (can_present) { + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + return machine_can_init_helper(self, n_args - 1, args + 1, &kw_args); + } else { + return mp_const_none; + } +} + +// can.init(mode, [kwargs]) +static mp_obj_t machine_can_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return machine_can_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +MP_DEFINE_CONST_FUN_OBJ_KW(machine_can_init_obj, 1, machine_can_init); + +// deinit() +static mp_obj_t machine_can_deinit(mp_obj_t self_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + machine_flexcan_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(machine_can_deinit_obj, machine_can_deinit); + +// Force a software restart of the controller, to allow transmission after a bus error +static mp_obj_t machine_can_restart(mp_obj_t self_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + bool boff_rec = self->can_inst->CTRL1 & CAN_CTRL1_BOFFREC_MASK; + self->can_inst->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK; + while (self->can_inst->CTRL1 & CAN_CTRL1_BOFFREC_MASK) { + } + if (boff_rec) { + self->can_inst->CTRL1 |= CAN_CTRL1_BOFFREC_MASK; + while ((self->can_inst->CTRL1 & CAN_CTRL1_BOFFREC_MASK) == 0) { + } + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(machine_can_restart_obj, machine_can_restart); + +// Get the state of the controller +static mp_obj_t machine_can_state(mp_obj_t self_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->is_enabled) { + uint32_t result = FLEXCAN_GetStatusFlags(self->can_inst); + uint32_t flt_conf = (result & CAN_ESR1_FLTCONF_MASK) >> CAN_ESR1_FLTCONF_SHIFT; + if (flt_conf > 1) { + return MP_OBJ_NEW_SMALL_INT(CAN_STATE_BUS_OFF); + } + if (flt_conf == 1) { + return MP_OBJ_NEW_SMALL_INT(CAN_STATE_ERROR_PASSIVE); + } + if ((result & CAN_ESR1_RXWRN_MASK) || (result & CAN_ESR1_TXWRN_MASK)) { + return MP_OBJ_NEW_SMALL_INT(CAN_STATE_ERROR_WARNING); + } + // flt_conf == 0 + return MP_OBJ_NEW_SMALL_INT(CAN_STATE_ERROR_ACTIVE); + } + return MP_OBJ_NEW_SMALL_INT(CAN_STATE_STOPPED); +} +static MP_DEFINE_CONST_FUN_OBJ_1(machine_can_state_obj, machine_can_state); + +static mp_uint_t can_count_txmb_pending(machine_can_obj_t *self) { + mp_uint_t count = 0; + for (mp_uint_t i = 0; i < self->flexcan_txmb_count; i++) { + uint32_t cs_temp = self->can_inst->MB[self->flexcan_txmb_start + i].CS; + if ((cs_temp & CAN_CS_CODE_MASK) == CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote)) { + count++; + } + } + return count; +} + +// Get info about error states and TX/RX buffers +static mp_obj_t machine_can_info(size_t n_args, const mp_obj_t *args) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_obj_list_t *list; + if (n_args == 1) { + list = MP_OBJ_TO_PTR(mp_obj_new_list(8, NULL)); + } else { + if (!mp_obj_is_type(args[1], &mp_type_list)) { + mp_raise_TypeError(NULL); + } + list = MP_OBJ_TO_PTR(args[1]); + if (list->len < 8) { + mp_raise_ValueError(NULL); + } + } + + CAN_Type *can = self->can_inst; + list->items[0] = MP_OBJ_NEW_SMALL_INT((can->ECR & CAN_ECR_TXERRCNT_MASK) >> CAN_ECR_TXERRCNT_SHIFT); + list->items[1] = MP_OBJ_NEW_SMALL_INT((can->ECR & CAN_ECR_RXERRCNT_MASK) >> CAN_ECR_RXERRCNT_SHIFT); + list->items[2] = MP_OBJ_NEW_SMALL_INT(self->num_error_warning); + list->items[3] = MP_OBJ_NEW_SMALL_INT(self->num_error_passive); + list->items[4] = MP_OBJ_NEW_SMALL_INT(self->num_bus_off); + list->items[5] = MP_OBJ_NEW_SMALL_INT(can_count_txmb_pending(self)); + // only 0 or 1 + int n_rx_pending = FLEXCAN_GetMbStatusFlags(can, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); + list->items[6] = MP_OBJ_NEW_SMALL_INT(n_rx_pending); + list->items[7] = MP_OBJ_NEW_SMALL_INT(0); + + return MP_OBJ_FROM_PTR(list); +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_can_info_obj, 1, 2, machine_can_info); + +// any(fifo) - return `True` if any message waiting on the FIFO, else `False` +static mp_obj_t machine_can_any(mp_obj_t self_in, mp_obj_t fifo_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_int_t fifo = mp_obj_get_int(fifo_in); + if (fifo != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("Fifo must be 0")); + } + if (FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)) { + return mp_const_true; + } + return mp_const_false; +} +static MP_DEFINE_CONST_FUN_OBJ_2(machine_can_any_obj, machine_can_any); + +static mp_uint_t can_find_txmb(machine_can_obj_t *self, flexcan_frame_t *frame) { + // See if this frame id has been used before. If so, re-use the same mailbox to keep message ordering. + for (mp_uint_t i = 0; i < self->flexcan_txmb_count; i++) { + uint32_t cs_temp = self->can_inst->MB[self->flexcan_txmb_start + i].CS; + if (((frame->format == kFLEXCAN_FrameFormatStandard) || (cs_temp & CAN_CS_IDE_MASK)) + && ((frame->type == kFLEXCAN_FrameTypeData) || (cs_temp & CAN_CS_RTR_MASK)) + && (self->can_inst->MB[self->flexcan_txmb_start + i].ID == frame->id)) { + if ((cs_temp & CAN_CS_CODE_MASK) != CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote)) { + return self->flexcan_txmb_start + i; + } else { + return 0; + } + } + } + // Frame id has never been used before so just pick the first empty mailbox. + for (mp_uint_t i = 0; i < self->flexcan_txmb_count; i++) { + uint32_t cs_temp = self->can_inst->MB[self->flexcan_txmb_start + i].CS; + if ((cs_temp & CAN_CS_CODE_MASK) != CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote)) { + return self->flexcan_txmb_start + i; + } + } + return 0; +} + +static mp_obj_t machine_can_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_data, ARG_id, ARG_timeout, ARG_rtr, ARG_extframe }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_extframe, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // get the buffer to send from + mp_buffer_info_t bufinfo; + uint8_t data[1]; + if (mp_obj_is_int(args[ARG_data].u_obj)) { + data[0] = mp_obj_get_int(args[ARG_data].u_obj); + bufinfo.buf = data; + bufinfo.len = 1; + bufinfo.typecode = 'B'; + } else { + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + } + + if (bufinfo.len > CAN_MAX_DATA_FRAME) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN data field too long")); + } + + flexcan_frame_t tx_msg; + + tx_msg.dataWord0 = 0; + tx_msg.dataWord1 = 0; + + if (bufinfo.len > 0) { + tx_msg.dataByte0 = ((byte *)bufinfo.buf)[0]; + } + if (bufinfo.len > 1) { + tx_msg.dataByte1 = ((byte *)bufinfo.buf)[1]; + } + if (bufinfo.len > 2) { + tx_msg.dataByte2 = ((byte *)bufinfo.buf)[2]; + } + if (bufinfo.len > 3) { + tx_msg.dataByte3 = ((byte *)bufinfo.buf)[3]; + } + if (bufinfo.len > 4) { + tx_msg.dataByte4 = ((byte *)bufinfo.buf)[4]; + } + if (bufinfo.len > 5) { + tx_msg.dataByte5 = ((byte *)bufinfo.buf)[5]; + } + if (bufinfo.len > 6) { + tx_msg.dataByte6 = ((byte *)bufinfo.buf)[6]; + } + if (bufinfo.len > 7) { + tx_msg.dataByte7 = ((byte *)bufinfo.buf)[7]; + } + + tx_msg.length = bufinfo.len; + tx_msg.type = args[ARG_rtr].u_bool; + tx_msg.format = args[ARG_extframe].u_bool; + + if (tx_msg.format) { + tx_msg.id = FLEXCAN_ID_EXT(args[ARG_id].u_int); + } else { + tx_msg.id = FLEXCAN_ID_STD(args[ARG_id].u_int); + } + + uint32_t timeout_ms = args[ARG_timeout].u_int; + uint32_t start = mp_hal_ticks_ms(); + + while (true) { + mp_uint_t mbIdx = can_find_txmb(self, &tx_msg); + if (mbIdx && (FLEXCAN_WriteTxMb(self->can_inst, mbIdx, &tx_msg) == kStatus_Success)) { + break; + } + if (timeout_ms == 0) { + mp_raise_OSError(MP_ETIMEDOUT); + } + // Check for the Timeout + if (timeout_ms != UINT32_MAX) { + if (mp_hal_ticks_ms() - start >= timeout_ms) { + mp_raise_OSError(MP_ETIMEDOUT); + } + } + MICROPY_EVENT_POLL_HOOK + } + + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(machine_can_send_obj, 1, machine_can_send); + +// recv(fifo, list=None, *, timeout=5000) +static mp_obj_t machine_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_fifo, ARG_list, ARG_timeout, ARG_fdf }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_fifo, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_list, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} }, + }; + + // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_uint_t fifo = args[ARG_fifo].u_int; + if (fifo != 0) { + mp_raise_TypeError(MP_ERROR_TEXT("fifo must be 0")); + } + + uint32_t timeout_ms = args[ARG_timeout].u_int; + uint32_t start = mp_hal_ticks_ms(); + + while (!FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)) { + if (timeout_ms == 0) { + mp_raise_OSError(MP_ETIMEDOUT); + } + // Check for the Timeout + if (timeout_ms != UINT32_MAX) { + if (mp_hal_ticks_ms() - start >= timeout_ms) { + mp_raise_OSError(MP_ETIMEDOUT); + } + } + MICROPY_EVENT_POLL_HOOK + } + + flexcan_frame_t rx_frame; + status_t status = FLEXCAN_ReadRxFifo(self->can_inst, &rx_frame); + FLEXCAN_ClearMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); + + FLEXCAN_EnableMbInterrupts(self->can_inst, + kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag); + + if (status != kStatus_Success) { + mp_raise_OSError(MP_EIO); + } + + uint32_t rx_dlc = rx_frame.length; + uint8_t rx_data[CAN_MAX_DATA_FRAME] = {}; + + if (rx_dlc > 0) { + rx_data[0] = rx_frame.dataByte0; + } + if (rx_dlc > 1) { + rx_data[1] = rx_frame.dataByte1; + } + if (rx_dlc > 2) { + rx_data[2] = rx_frame.dataByte2; + } + if (rx_dlc > 3) { + rx_data[3] = rx_frame.dataByte3; + } + if (rx_dlc > 4) { + rx_data[4] = rx_frame.dataByte4; + } + if (rx_dlc > 5) { + rx_data[5] = rx_frame.dataByte5; + } + if (rx_dlc > 6) { + rx_data[6] = rx_frame.dataByte6; + } + if (rx_dlc > 7) { + rx_data[7] = rx_frame.dataByte7; + } + + // Create the tuple, or get the list, that will hold the return values + // Also populate the fifth element, either a new bytes or reuse existing memoryview + mp_obj_t ret_obj = args[ARG_list].u_obj; + mp_obj_t *items; + if (ret_obj == mp_const_none) { + ret_obj = mp_obj_new_tuple(5, NULL); + items = ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(ret_obj))->items; + items[4] = mp_obj_new_bytes(rx_data, rx_dlc); + } else { + // User should provide a list of length at least 5 to hold the values + if (!mp_obj_is_type(ret_obj, &mp_type_list)) { + mp_raise_TypeError(NULL); + } + mp_obj_list_t *list = MP_OBJ_TO_PTR(ret_obj); + if (list->len < 5) { + mp_raise_ValueError(NULL); + } + items = list->items; + // Fifth element must be a memoryview which we assume points to a + // byte-like array which is large enough, and then we resize it inplace + if (!mp_obj_is_type(items[4], &mp_type_memoryview)) { + mp_raise_TypeError(NULL); + } + mp_obj_array_t *mv = MP_OBJ_TO_PTR(items[4]); + if (!(mv->typecode == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | BYTEARRAY_TYPECODE) + || (mv->typecode | 0x20) == (MP_OBJ_ARRAY_TYPECODE_FLAG_RW | 'b'))) { + mp_raise_ValueError(NULL); + } + mv->len = rx_dlc; + memcpy(mv->items, rx_data, rx_dlc); + } + + // Populate the first 4 values of the tuple/list + items[0] = MP_OBJ_NEW_SMALL_INT(rx_frame.id >> (rx_frame.format ? CAN_ID_EXT_SHIFT : CAN_ID_STD_SHIFT)); + items[1] = mp_obj_new_bool(rx_frame.format); + items[2] = mp_obj_new_bool(rx_frame.type); + items[3] = MP_OBJ_NEW_SMALL_INT(rx_frame.idhit); + + // Return the result + return ret_obj; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(machine_can_recv_obj, 1, machine_can_recv); + +static mp_obj_t machine_can_clearfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_extframe }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_extframe, MP_ARG_BOOL, {.u_bool = false} }, + }; + + // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_uint_t bank = mp_obj_get_int(pos_args[1]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + if ((bank < 0) || (bank >= self->flexcan_config->maxMbNum)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d maximum banks"), + self->flexcan_config->maxMbNum); + } + + self->flexcan_rx_fifo_config->idFilterTable[bank * 2] = 0; + self->flexcan_rx_fifo_config->idFilterTable[(bank * 2) + 1] = 0; + + FLEXCAN_SetRxFifoConfig(self->can_inst, self->flexcan_rx_fifo_config, true); + + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(machine_can_clearfilter_obj, 2, machine_can_clearfilter); + +// setfilter(bank, mode, fifo, params, *, rtr) +static mp_obj_t machine_can_setfilter(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_bank, ARG_mode, ARG_fifo, ARG_params, ARG_rtr, ARG_extframe }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bank, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_fifo, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_rtr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_extframe, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + // parse args + machine_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_uint_t bank = args[ARG_bank].u_int; + if ((bank < 0) || (bank >= self->flexcan_config->maxMbNum)) { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%d maximum banks"), + self->flexcan_config->maxMbNum); + } + + if (args[ARG_fifo].u_int != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("fifo must be 0")); + } + + size_t len; + size_t rtr_len; + mp_uint_t rtr_masks[2] = {0, 0}; + mp_obj_t *rtr_flags; + mp_obj_t *params; + mp_obj_get_array(args[ARG_params].u_obj, &len, ¶ms); + if (args[ARG_rtr].u_obj != MP_OBJ_NULL) { + mp_obj_get_array(args[ARG_rtr].u_obj, &rtr_len, &rtr_flags); + } + + if (args[ARG_mode].u_int == CAN_DUAL) { + if (len != 2) { + goto error; + } + if (args[ARG_rtr].u_obj != MP_OBJ_NULL) { + if (rtr_len != 2) { + goto error; + } + rtr_masks[0] = mp_obj_is_true(rtr_flags[0]); + rtr_masks[1] = mp_obj_is_true(rtr_flags[1]); + } + mp_uint_t id0 = mp_obj_get_int(params[0]); + mp_uint_t id1 = mp_obj_get_int(params[1]); + if (args[ARG_extframe].u_bool) { + id0 = FLEXCAN_ID_EXT(id0) | (1 << 29); + id1 = FLEXCAN_ID_EXT(id1) | (1 << 29); + } else { + id0 = FLEXCAN_ID_STD(id0); + id1 = FLEXCAN_ID_STD(id1); + } + id0 = ((rtr_masks[0] << 30) | id0) << 1; + id1 = ((rtr_masks[1] << 30) | id1) << 1; + self->flexcan_rx_fifo_config->idFilterTable[bank * 2] = id0; + self->flexcan_rx_fifo_config->idFilterTable[(bank * 2) + 1] = id1; + } else { + goto error; + } + + FLEXCAN_SetRxFifoConfig(self->can_inst, self->flexcan_rx_fifo_config, true); + + return mp_const_none; +error: + mp_raise_ValueError(MP_ERROR_TEXT("CAN filter parameter error")); +} +static MP_DEFINE_CONST_FUN_OBJ_KW(machine_can_setfilter_obj, 1, machine_can_setfilter); + +static mp_obj_t machine_can_rxcallback(mp_obj_t self_in, mp_obj_t fifo_in, mp_obj_t callback_in) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->is_enabled) { + mp_raise_ValueError(MP_ERROR_TEXT("CAN bus not enabled")); + } + mp_int_t fifo = mp_obj_get_int(fifo_in); + if (fifo != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("fifo must be 0")); + } + self->callback = callback_in; + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(machine_can_rxcallback_obj, machine_can_rxcallback); + +static const mp_rom_map_elem_t machine_can_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_can_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_can_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&machine_can_restart_obj) }, + { MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&machine_can_state_obj) }, + { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_can_info_obj) }, + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_can_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&machine_can_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&machine_can_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&machine_can_setfilter_obj) }, + { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&machine_can_clearfilter_obj) }, + { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&machine_can_rxcallback_obj) }, + + // class constants + { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_NORMAL_MODE) }, + { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_LOOPBACK_FLAG) }, + { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_SILENT_FLAG) }, + { MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_LOOPBACK_FLAG | CAN_SILENT_FLAG) }, + { MP_ROM_QSTR(MP_QSTR_DUAL), MP_ROM_INT(CAN_DUAL) }, + { MP_ROM_QSTR(MP_QSTR_LIST32), MP_ROM_INT(CAN_DUAL) }, + + // values for CAN.state() + { MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) }, + { MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_ERROR_ACTIVE) }, + { MP_ROM_QSTR(MP_QSTR_ERROR_WARNING), MP_ROM_INT(CAN_STATE_ERROR_WARNING) }, + { MP_ROM_QSTR(MP_QSTR_ERROR_PASSIVE), MP_ROM_INT(CAN_STATE_ERROR_PASSIVE) }, + { MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) }, +}; +static MP_DEFINE_CONST_DICT(machine_can_locals_dict, machine_can_locals_dict_table); + +static mp_uint_t can_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + machine_can_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (self->is_enabled && request == MP_STREAM_POLL) { + uintptr_t flags = arg; + ret = 0; + + if ((flags & MP_STREAM_POLL_RD) + && FLEXCAN_GetMbStatusFlags(self->can_inst, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)) { + ret |= MP_STREAM_POLL_RD; + } + + if ((flags & MP_STREAM_POLL_WR) + && can_count_txmb_pending(self)) { + ret |= MP_STREAM_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = -1; + } + return ret; +} + +static const mp_stream_p_t can_stream_p = { + .ioctl = can_ioctl, + .is_text = false, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + machine_can_type, + MP_QSTR_CAN, + MP_TYPE_FLAG_NONE, + make_new, machine_can_make_new, + print, machine_can_print, + protocol, &can_stream_p, + locals_dict, &machine_can_locals_dict + ); + +MP_REGISTER_ROOT_POINTER(void *machine_can_objects[MICROPY_HW_NUM_CAN_IRQS]); + +#endif // MICROPY_PY_MACHINE_CAN diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c index dcb1ede1670..8e5f41fd888 100644 --- a/ports/mimxrt/main.c +++ b/ports/mimxrt/main.c @@ -159,6 +159,9 @@ int main(void) { soft_reset_exit: mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + #if MICROPY_PY_MACHINE_CAN + machine_can_irq_deinit(); + #endif machine_pin_irq_deinit(); machine_rtc_irq_deinit(); #if MICROPY_PY_MACHINE_I2S diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h index 34e93260f2d..22630a46b2f 100644 --- a/ports/mimxrt/modmachine.h +++ b/ports/mimxrt/modmachine.h @@ -32,6 +32,7 @@ extern const mp_obj_type_t machine_sdcard_type; void machine_adc_init(void); +void machine_can_irq_deinit(void); void machine_pin_irq_deinit(void); void machine_rtc_irq_deinit(void); void machine_pwm_deinit_all(void); diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 61c987e92ba..8fe8a11bfce 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -118,6 +118,9 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_MACHINE_SPI (1) #define MICROPY_PY_MACHINE_SOFTSPI (1) #define MICROPY_PY_MACHINE_TIMER (1) +#ifndef MICROPY_PY_MACHINE_CAN +#define MICROPY_PY_MACHINE_CAN (0) +#endif #define MICROPY_PY_MACHINE_WDT (1) #define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/mimxrt/machine_wdt.c" #define MICROPY_PY_MACHINE_WDT_TIMEOUT_MS (1) From 420cf20a3027e30b3b07a637164c8d035850eaee Mon Sep 17 00:00:00 2001 From: robert-hh Date: Thu, 21 Nov 2024 17:03:37 +0100 Subject: [PATCH 15/45] mimxrt: Add support for the VfsRom filesystem. Signed-off-by: robert-hh --- ports/mimxrt/Makefile | 5 ++-- ports/mimxrt/boards/MIMXRT1011.ld | 4 ++- ports/mimxrt/boards/MIMXRT1015.ld | 4 ++- ports/mimxrt/boards/MIMXRT1021.ld | 4 ++- ports/mimxrt/boards/MIMXRT1052.ld | 4 ++- ports/mimxrt/boards/MIMXRT1062.ld | 4 ++- ports/mimxrt/boards/MIMXRT1064.ld | 4 ++- ports/mimxrt/boards/MIMXRT1176.ld | 4 ++- ports/mimxrt/mimxrt_flash.c | 49 +++++++++++++++++++++++++++++++ ports/mimxrt/mpconfigport.h | 3 ++ 10 files changed, 76 insertions(+), 9 deletions(-) diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile index b3e74ce6076..ef98223ac41 100644 --- a/ports/mimxrt/Makefile +++ b/ports/mimxrt/Makefile @@ -498,9 +498,10 @@ LDFLAGS += \ # LDDEFINES are used for link time adaptation of linker scripts, utilizing # the C preprocessor. Therefore keep LDDEFINES separated from LDFLAGS! -LDDEFINES = \ +LDDEFINES += \ -DMICROPY_HW_FLASH_BASE=$(MICROPY_HW_FLASH_BASE) \ - -DMICROPY_HW_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) + -DMICROPY_HW_FLASH_SIZE=$(MICROPY_HW_FLASH_SIZE) \ + -DMICROPY_HW_ROMFS_BYTES=$(MICROPY_HW_ROMFS_BYTES) ifdef MICROPY_HW_FLASH_RESERVED LDDEFINES += -DMICROPY_HW_FLASH_RESERVED=$(MICROPY_HW_FLASH_RESERVED) diff --git a/ports/mimxrt/boards/MIMXRT1011.ld b/ports/mimxrt/boards/MIMXRT1011.ld index 0e961a49433..b5c5464dd7a 100644 --- a/ports/mimxrt/boards/MIMXRT1011.ld +++ b/ports/mimxrt/boards/MIMXRT1011.ld @@ -18,8 +18,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00100000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00008000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1015.ld b/ports/mimxrt/boards/MIMXRT1015.ld index 58b88e0fe30..64ca7bfd3f2 100644 --- a/ports/mimxrt/boards/MIMXRT1015.ld +++ b/ports/mimxrt/boards/MIMXRT1015.ld @@ -18,8 +18,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00100000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00008000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1021.ld b/ports/mimxrt/boards/MIMXRT1021.ld index 78add04c0c2..7b032788aa8 100644 --- a/ports/mimxrt/boards/MIMXRT1021.ld +++ b/ports/mimxrt/boards/MIMXRT1021.ld @@ -18,8 +18,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00100000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00010000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1052.ld b/ports/mimxrt/boards/MIMXRT1052.ld index ea034d713e2..d1b4d556eba 100644 --- a/ports/mimxrt/boards/MIMXRT1052.ld +++ b/ports/mimxrt/boards/MIMXRT1052.ld @@ -20,8 +20,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00200000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1062.ld b/ports/mimxrt/boards/MIMXRT1062.ld index 3d7e6d06341..d5da419f7e3 100644 --- a/ports/mimxrt/boards/MIMXRT1062.ld +++ b/ports/mimxrt/boards/MIMXRT1062.ld @@ -20,8 +20,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00100000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1064.ld b/ports/mimxrt/boards/MIMXRT1064.ld index 7c35cb60c75..a8215bc3bf5 100644 --- a/ports/mimxrt/boards/MIMXRT1064.ld +++ b/ports/mimxrt/boards/MIMXRT1064.ld @@ -14,8 +14,10 @@ interrupts_start = flash_start + 0x0000C000; interrupts_size = 0x00000400; text_start = flash_start + 0x0000C400; vfs_start = flash_start + 0x00100000; -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/boards/MIMXRT1176.ld b/ports/mimxrt/boards/MIMXRT1176.ld index 4d114ef96fa..11664a752f0 100644 --- a/ports/mimxrt/boards/MIMXRT1176.ld +++ b/ports/mimxrt/boards/MIMXRT1176.ld @@ -30,8 +30,10 @@ m_core1_image_start = vfs_start - 0x00040000; m_core1_image_size = 0x00040000; #endif -text_size = ((vfs_start) - (text_start)); vfs_size = ((flash_end) - (vfs_start)); +vfsrom_start = ((vfs_start) - MICROPY_HW_ROMFS_BYTES); +vfsrom_end = ((vfsrom_start) + MICROPY_HW_ROMFS_BYTES); +text_size = ((vfsrom_start) - (text_start)); itcm_start = 0x00000000; itcm_size = 0x00020000; dtcm_start = 0x20000000; diff --git a/ports/mimxrt/mimxrt_flash.c b/ports/mimxrt/mimxrt_flash.c index fdd48e280bc..3819d8b9043 100644 --- a/ports/mimxrt/mimxrt_flash.c +++ b/ports/mimxrt/mimxrt_flash.c @@ -5,6 +5,7 @@ * * Copyright (c) 2020-2021 Damien P. George * Copyright (c) 2021-2023 Philipp Ebensberger + * Copyright (c) 2021-2024 Robert Hammelrath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +30,7 @@ #include "py/runtime.h" #include "extmod/vfs.h" +#include "py/mperrno.h" #include "modmimxrt.h" #include "flash.h" #include BOARD_FLASH_OPS_HEADER_H @@ -60,6 +62,19 @@ static mp_obj_t mimxrt_flash_make_new(const mp_obj_type_t *type, size_t n_args, return MP_OBJ_FROM_PTR(&mimxrt_flash_obj); } +static mp_int_t mimxrt_flash_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + mimxrt_flash_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (flags == MP_BUFFER_READ) { + bufinfo->buf = (void *)((uintptr_t)&__flash_start + self->flash_base); + bufinfo->len = self->flash_size; + bufinfo->typecode = 'B'; + return 0; + } else { + // Write unsupported. + return 1; + } +} + // readblocks(block_num, buf, [offset]) // read size of buffer number of bytes from block (with offset) into buffer static mp_obj_t mimxrt_flash_readblocks(size_t n_args, const mp_obj_t *args) { @@ -151,5 +166,39 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_QSTR_Flash, MP_TYPE_FLAG_NONE, make_new, mimxrt_flash_make_new, + buffer, mimxrt_flash_get_buffer, locals_dict, &mimxrt_flash_locals_dict ); + +#if MICROPY_VFS_ROM + +extern uint8_t _micropy_hw_romfs_part0_start; +extern uint8_t _micropy_hw_romfs_part0_size; + +// Put VfsRom file system between the code space and the VFS file system. +// The size is defined in Makefile(s) as linker symbol MICROPY_HW_ROMFS_BYTES. +// For machine.mem32 the absolute address is required, for the flash functions +// erase and write the offset to the flash start address. +#define MICROPY_HW_ROMFS_BASE ((uintptr_t)&_micropy_hw_romfs_part0_start - (uintptr_t)&__flash_start) +#define MICROPY_HW_ROMFS_BYTES ((uintptr_t)&_micropy_hw_romfs_part0_size) + +static mimxrt_flash_obj_t mimxrt_flash_romfs_obj = { + .base = { &mimxrt_flash_type }, +}; + +mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args) { + if (MICROPY_HW_ROMFS_BYTES <= 0) { + return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL); + } + switch (mp_obj_get_int(args[0])) { + case MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS: + return MP_OBJ_NEW_SMALL_INT(1); + case MP_VFS_ROM_IOCTL_GET_SEGMENT: + mimxrt_flash_romfs_obj.flash_base = MICROPY_HW_ROMFS_BASE; + mimxrt_flash_romfs_obj.flash_size = MICROPY_HW_ROMFS_BYTES; + return MP_OBJ_FROM_PTR(&mimxrt_flash_romfs_obj); + default: + return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL); + } +} +#endif // MICROPY_VFS_ROM diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 8fe8a11bfce..0ffdb0c3be9 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -63,6 +63,9 @@ uint32_t trng_random_u32(void); #define MICROPY_SCHEDULER_DEPTH (8) #define MICROPY_SCHEDULER_STATIC_NODES (1) #define MICROPY_VFS (1) +#ifndef MICROPY_VFS_ROM +#define MICROPY_VFS_ROM (1) +#endif #define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool // Control over Python builtins From 6a92cdf247b2fbb3c7e0d461b3196d15f7b42a99 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 06:54:20 +0100 Subject: [PATCH 16/45] stm32/boards: Add OpenMV boards. Signed-off-by: iabdalkader --- ports/stm32/boards/OPENMV1/mpconfigboard.h | 104 +++++ ports/stm32/boards/OPENMV1/mpconfigboard.mk | 3 + ports/stm32/boards/OPENMV1/pins.csv | 88 ++++ .../stm32/boards/OPENMV1/stm32f4xx_hal_conf.h | 393 ++++++++++++++++++ ports/stm32/boards/OPENMV2/board_init.c | 8 + ports/stm32/boards/OPENMV2/mpconfigboard.h | 136 ++++++ ports/stm32/boards/OPENMV2/mpconfigboard.mk | 5 + ports/stm32/boards/OPENMV2/pins.csv | 88 ++++ .../stm32/boards/OPENMV2/stm32f4xx_hal_conf.h | 19 + ports/stm32/boards/OPENMV3/board_init.c | 8 + ports/stm32/boards/OPENMV3/mpconfigboard.h | 145 +++++++ ports/stm32/boards/OPENMV3/mpconfigboard.mk | 5 + ports/stm32/boards/OPENMV3/pins.csv | 33 ++ .../stm32/boards/OPENMV3/stm32f7xx_hal_conf.h | 19 + ports/stm32/boards/OPENMV4/board_init.c | 8 + ports/stm32/boards/OPENMV4/mpconfigboard.h | 135 ++++++ ports/stm32/boards/OPENMV4/mpconfigboard.mk | 5 + ports/stm32/boards/OPENMV4/pins.csv | 33 ++ .../stm32/boards/OPENMV4/stm32h7xx_hal_conf.h | 51 +++ ports/stm32/boards/OPENMV4P/bdev.c | 18 + ports/stm32/boards/OPENMV4P/board_init.c | 27 ++ ports/stm32/boards/OPENMV4P/mpconfigboard.h | 259 ++++++++++++ ports/stm32/boards/OPENMV4P/mpconfigboard.mk | 5 + ports/stm32/boards/OPENMV4P/pins.csv | 97 +++++ .../boards/OPENMV4P/stm32h7xx_hal_conf.h | 51 +++ ports/stm32/boards/OPENMVPT/bdev.c | 14 + ports/stm32/boards/OPENMVPT/board_init.c | 74 ++++ ports/stm32/boards/OPENMVPT/mpconfigboard.h | 270 ++++++++++++ ports/stm32/boards/OPENMVPT/mpconfigboard.mk | 5 + ports/stm32/boards/OPENMVPT/pins.csv | 111 +++++ .../boards/OPENMVPT/stm32h7xx_hal_conf.h | 51 +++ ports/stm32/boards/stm32f427_af.csv | 2 +- 32 files changed, 2269 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/OPENMV1/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMV1/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMV1/pins.csv create mode 100644 ports/stm32/boards/OPENMV1/stm32f4xx_hal_conf.h create mode 100644 ports/stm32/boards/OPENMV2/board_init.c create mode 100644 ports/stm32/boards/OPENMV2/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMV2/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMV2/pins.csv create mode 100644 ports/stm32/boards/OPENMV2/stm32f4xx_hal_conf.h create mode 100644 ports/stm32/boards/OPENMV3/board_init.c create mode 100644 ports/stm32/boards/OPENMV3/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMV3/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMV3/pins.csv create mode 100644 ports/stm32/boards/OPENMV3/stm32f7xx_hal_conf.h create mode 100644 ports/stm32/boards/OPENMV4/board_init.c create mode 100644 ports/stm32/boards/OPENMV4/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMV4/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMV4/pins.csv create mode 100644 ports/stm32/boards/OPENMV4/stm32h7xx_hal_conf.h create mode 100644 ports/stm32/boards/OPENMV4P/bdev.c create mode 100644 ports/stm32/boards/OPENMV4P/board_init.c create mode 100644 ports/stm32/boards/OPENMV4P/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMV4P/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMV4P/pins.csv create mode 100644 ports/stm32/boards/OPENMV4P/stm32h7xx_hal_conf.h create mode 100644 ports/stm32/boards/OPENMVPT/bdev.c create mode 100644 ports/stm32/boards/OPENMVPT/board_init.c create mode 100644 ports/stm32/boards/OPENMVPT/mpconfigboard.h create mode 100644 ports/stm32/boards/OPENMVPT/mpconfigboard.mk create mode 100644 ports/stm32/boards/OPENMVPT/pins.csv create mode 100644 ports/stm32/boards/OPENMVPT/stm32h7xx_hal_conf.h diff --git a/ports/stm32/boards/OPENMV1/mpconfigboard.h b/ports/stm32/boards/OPENMV1/mpconfigboard.h new file mode 100644 index 00000000000..bc3bfb431db --- /dev/null +++ b/ports/stm32/boards/OPENMV1/mpconfigboard.h @@ -0,0 +1,104 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMV1" +#define MICROPY_HW_MCU_NAME "STM32F407" +#define MICROPY_PY_SYS_PLATFORM "OpenMV1" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-1" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_MMA7660 (0) +#define MICROPY_HW_HAS_LIS3DSH (0) +#define MICROPY_HW_HAS_LCD (0) +#define MICROPY_HW_ENABLE_RTC (0) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENABLE_SPI1 (0) +#define MICROPY_HW_ENABLE_SPI2 (0) +#define MICROPY_HW_ENABLE_SPI3 (1) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) + +#define MICROPY_HW_CLK_PLLM (12) +#define MICROPY_HW_CLK_PLLN (336) +#define MICROPY_HW_CLK_PLLQ (7) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) + +// UART config +#define MICROPY_HW_UART3_PORT (GPIOB) +#define MICROPY_HW_UART3_PINS (GPIO_PIN_10 | GPIO_PIN_11) + +// I2C busses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_A0) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_D4) // red +#define MICROPY_HW_LED2 (pin_D6) // green +#define MICROPY_HW_LED3 (pin_D5) // blue +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRH = pin->pin_mask) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRL = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (2) + +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +#define MICROPY_HW_USB_VID 0x1209 +#define MICROPY_HW_USB_PID 0xabd1 +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMV1/mpconfigboard.mk b/ports/stm32/boards/OPENMV1/mpconfigboard.mk new file mode 100644 index 00000000000..feb34633dbc --- /dev/null +++ b/ports/stm32/boards/OPENMV1/mpconfigboard.mk @@ -0,0 +1,3 @@ +AF_FILE = boards/stm32f405_af.csv +LD_FILE = boards/stm32f405.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMV1/pins.csv b/ports/stm32/boards/OPENMV1/pins.csv new file mode 100644 index 00000000000..fba3da0a99b --- /dev/null +++ b/ports/stm32/boards/OPENMV1/pins.csv @@ -0,0 +1,88 @@ +PC0,PC0 +PC1,PC1 +PC2,PC2 +PC3,PC3 +P13,PA0 +P14,PA1 +P15,PA2 +P16,PA3 +PA4,PA4 +P6,PA5 +PA6,PA6 +PA7,PA7 +PC4,PC4 +PC5,PC5 +PB0,PB0 +PB1,PB1 +PB2,PB2 +PE7,PE7 +PE8,PE8 +PE9,PE9 +PE10,PE10 +PE11,PE11 +PE12,PE12 +PE13,PE13 +PE14,PE14 +PE15,PE15 +P4,PB10 +P5,PB11 +P3,PB12 +P2,PB13 +P1,PB14 +P0,PB15 +PD8,PD8 +PD9,PD9 +P9,PD10 +P10,PD11 +P7,PD12 +P8,PD13 +PD14,PD14 +PD15,PD15 +PC6,PC6 +PC7,PC7 +PC8,PC8 +PC9,PC9 +PA8,PA8 +PA9,PA9 +PA10,PA10 +P11,PA13 +P12,PA14 +PA15,PA15 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD0,PD0 +PD1,PD1 +PD2,PD2 +PD3,PD3 +PD4,PD4 +PD5,PD5 +PD6,PD6 +PD7,PD7 +PB4,PB4 +PB5,PB5 +PB6,PB6 +PB7,PB7 +PB8,PB8 +PB9,PB9 +PE0,PE0 +PE1,PE1 +PE2,PE2 +PE3,PE3 +PE4,PE4 +PE5,PE5 +PE6,PE6 +PC13,PC13 +PC14,PC14 +PC15,PC15 +PH0,PH0 +PH1,PH1 +LED_GREEN,PD12 +LED_ORANGE,PD13 +LED_RED,PD14 +LED_BLUE,PD15 +SW,PA0 +USB_VBUS,PA9 +USB_DM,PA11 +USB_DP,PA12 +USB_ID,PA10 diff --git a/ports/stm32/boards/OPENMV1/stm32f4xx_hal_conf.h b/ports/stm32/boards/OPENMV1/stm32f4xx_hal_conf.h new file mode 100644 index 00000000000..6ce81fb63f6 --- /dev/null +++ b/ports/stm32/boards/OPENMV1/stm32f4xx_hal_conf.h @@ -0,0 +1,393 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf.h + * @author MCD Application Team + * @version V1.0.1 + * @date 26-February-2014 + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +#define STM32F407xx +#define USE_USB_FS + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +#define HAL_ETH_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_PCCARD_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +/* #define HAL_SDRAM_MODULE_ENABLED */ +#define HAL_HASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +/* #define HAL_SAI_MODULE_ENABLED */ +#define HAL_SD_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED + + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2 +#define MAC_ADDR1 0 +#define MAC_ADDR2 0 +#define MAC_ADDR3 0 +#define MAC_ADDR4 0 +#define MAC_ADDR5 0 + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x10) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32/boards/OPENMV2/board_init.c b/ports/stm32/boards/OPENMV2/board_init.c new file mode 100644 index 00000000000..2bc1d187c06 --- /dev/null +++ b/ports/stm32/boards/OPENMV2/board_init.c @@ -0,0 +1,8 @@ +#include "py/mphal.h" +#define OMV_BOOTLOADER_MAGIC_ADDR (0x1000FFFCU) +#define OMV_BOOTLOADER_MAGIC_VALUE (0xB00710ADU) + +void board_enter_bootloader(void) { + *((uint32_t *) OMV_BOOTLOADER_MAGIC_ADDR) = OMV_BOOTLOADER_MAGIC_VALUE; + NVIC_SystemReset(); +} diff --git a/ports/stm32/boards/OPENMV2/mpconfigboard.h b/ports/stm32/boards/OPENMV2/mpconfigboard.h new file mode 100644 index 00000000000..ca5763c0bae --- /dev/null +++ b/ports/stm32/boards/OPENMV2/mpconfigboard.h @@ -0,0 +1,136 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMV2" +#define MICROPY_HW_MCU_NAME "STM32F427" +#define MICROPY_PY_SYS_PLATFORM "OpenMV2" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-2" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_FATFS_EXFAT (1) +#define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_MMA7660 (0) +#define MICROPY_HW_HAS_LIS3DSH (0) +#define MICROPY_HW_HAS_LCD (0) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SPI1 (0) +#define MICROPY_HW_ENABLE_SPI2 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) + +// ROMFS config +#define MICROPY_HW_ROMFS_ENABLE_INTERNAL_FLASH (1) +#define MICROPY_HW_ROMFS_ENABLE_PART0 (1) + +#define MICROPY_BOARD_ENTER_STANDBY + +extern void board_enter_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader() + +#define MICROPY_HW_CLK_PLLM (6) +#define MICROPY_HW_CLK_PLLN (360) +#define MICROPY_HW_CLK_PLLQ (15) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV4) + +// UART config +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART3_RTS (pin_B14) +#define MICROPY_HW_UART3_CTS (pin_B13) + +// I2C busses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +// SPI busses +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// CAN busses +#define MICROPY_HW_CAN2_NAME "CAN2" // CAN2 on RX,TX = P3,P2 = PB12,PB13 +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) +#define MICROPY_HW_CAN_IS_RESERVED(id) (id != PYB_CAN_2) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A15) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +//#define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN (pin_A0) +#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_C0) // red +#define MICROPY_HW_LED2 (pin_C2) // green +#define MICROPY_HW_LED3 (pin_C1) // blue +#define MICROPY_HW_LED4 (pin_E2) // IR +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = (pin->pin_mask << 16)) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (2) + +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +#define MICROPY_HW_USB_VID 0x37C5 +#define MICROPY_HW_USB_PID 0x1202 +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMV2/mpconfigboard.mk b/ports/stm32/boards/OPENMV2/mpconfigboard.mk new file mode 100644 index 00000000000..51c995dac35 --- /dev/null +++ b/ports/stm32/boards/OPENMV2/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F427xx +AF_FILE = boards/stm32f427_af.csv +LD_FILE = boards/stm32f405.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMV2/pins.csv b/ports/stm32/boards/OPENMV2/pins.csv new file mode 100644 index 00000000000..5ea29033a73 --- /dev/null +++ b/ports/stm32/boards/OPENMV2/pins.csv @@ -0,0 +1,88 @@ +PC0,PC0 +PC1,PC1 +PC2,PC2 +PC3,PC3 +P13,PA0 +P14,PA1 +P15,PA2 +P16,PA3 +PA4,PA4 +P6,PA5 +PA6,PA6 +PA7,PA7 +PC4,PC4 +PC5,PC5 +PB0,PB0 +PB1,PB1 +PB2,PB2 +PE7,PE7 +PE8,PE8 +PE9,PE9 +PE10,PE10 +PE11,PE11 +PE12,PE12 +PE13,PE13 +PE14,PE14 +PE15,PE15 +P4,PB10 +P5,PB11 +P3,PB12 +P2,PB13 +P1,PB14 +P0,PB15 +PD8,PD8 +PD9,PD9 +P9,PD10 +P10,PD11 +P7,PD12 +P8,PD13 +PD14,PD14 +PD15,PD15 +PC6,PC6 +PC7,PC7 +PC8,PC8 +PC9,PC9 +PA8,PA8 +PA9,PA9 +PA10,PA10 +P11,PA13 +P12,PA14 +PA15,PA15 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD0,PD0 +PD1,PD1 +PD2,PD2 +PD3,PD3 +PD4,PD4 +PD5,PD5 +PD6,PD6 +PD7,PD7 +PB4,PB4 +PB5,PB5 +PB6,PB6 +PB7,PB7 +PB8,PB8 +PB9,PB9 +PE0,PE0 +PE1,PE1 +PE2,PE2 +PE3,PE3 +PE4,PE4 +PE5,PE5 +PE6,PE6 +PC13,PC13 +PC14,PC14 +PC15,PC15 +PH0,PH0 +PH1,PH1 +LED_IR,PE2 +LED_RED,PC0 +LED_GREEN,PC2 +LED_BLUE,PC1 +SW,PA0 +USB_VBUS,PA9 +USB_DM,PA11 +USB_DP,PA12 +USB_ID,PA10 diff --git a/ports/stm32/boards/OPENMV2/stm32f4xx_hal_conf.h b/ports/stm32/boards/OPENMV2/stm32f4xx_hal_conf.h new file mode 100644 index 00000000000..4c433efa87e --- /dev/null +++ b/ports/stm32/boards/OPENMV2/stm32f4xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#include "boards/stm32f4xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H diff --git a/ports/stm32/boards/OPENMV3/board_init.c b/ports/stm32/boards/OPENMV3/board_init.c new file mode 100644 index 00000000000..cc699644b5c --- /dev/null +++ b/ports/stm32/boards/OPENMV3/board_init.c @@ -0,0 +1,8 @@ +#include "py/mphal.h" +#define OMV_BOOTLOADER_MAGIC_ADDR (0x2001FFFCU) +#define OMV_BOOTLOADER_MAGIC_VALUE (0xB00710ADU) + +void board_enter_bootloader(void) { + *((uint32_t *) OMV_BOOTLOADER_MAGIC_ADDR) = OMV_BOOTLOADER_MAGIC_VALUE; + NVIC_SystemReset(); +} diff --git a/ports/stm32/boards/OPENMV3/mpconfigboard.h b/ports/stm32/boards/OPENMV3/mpconfigboard.h new file mode 100644 index 00000000000..7ead542a585 --- /dev/null +++ b/ports/stm32/boards/OPENMV3/mpconfigboard.h @@ -0,0 +1,145 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMV3" +#define MICROPY_HW_MCU_NAME "STM32F765" +#define MICROPY_PY_SYS_PLATFORM "OpenMV3-M7" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-3" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_FATFS_EXFAT (1) +#define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_MMA7660 (0) +#define MICROPY_HW_HAS_LIS3DSH (0) +#define MICROPY_HW_HAS_LCD (0) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SPI1 (0) +#define MICROPY_HW_ENABLE_SPI2 (1) +#define MICROPY_HW_ENABLE_SPI3 (0) +#define MICROPY_HW_ENABLE_SPI4 (0) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) + +// ROMFS config +#define MICROPY_HW_ROMFS_ENABLE_INTERNAL_FLASH (1) +#define MICROPY_HW_ROMFS_ENABLE_PART0 (1) + +#define MICROPY_BOARD_ENTER_STANDBY + +extern void board_enter_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader() + +#define MICROPY_HW_CLK_PLLM (12) +#define MICROPY_HW_CLK_PLLN (432) +#define MICROPY_HW_CLK_PLLQ (9) +#define MICROPY_HW_CLK_PLLR (2) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) + +// UART1 config +#define MICROPY_HW_UART1_TX (pin_B14) +#define MICROPY_HW_UART1_RX (pin_B15) + +// UART3 config +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART3_RTS (pin_B14) +#define MICROPY_HW_UART3_CTS (pin_B13) + +// I2C buses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +#define MICROPY_HW_I2C4_SCL (pin_D12) +#define MICROPY_HW_I2C4_SDA (pin_D13) + +// SPI buses +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// CAN busses +#define MICROPY_HW_CAN2_NAME "CAN2" // CAN2 on RX,TX = P3,P2 = PB12,PB13 +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) +#define MICROPY_HW_CAN_IS_RESERVED(id) (id != PYB_CAN_2) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A15) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +//#define MICROPY_HW_USB_OTG_ID_PIN (pin_A10) + +// USRSW is pulled low. Pressing the button makes the input go high. +//#define MICROPY_HW_USRSW_PIN (pin_A5) +//#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) +//#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) +//#define MICROPY_HW_USRSW_PRESSED (1) + +// LEDs +#define MICROPY_HW_LED1 (pin_C0) // red +#define MICROPY_HW_LED2 (pin_C1) // green +#define MICROPY_HW_LED3 (pin_C2) // blue +#define MICROPY_HW_LED4 (pin_E2) // IR +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = (pin->pin_mask << 16)) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (4) + +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +#define MICROPY_HW_USB_VID 0x37C5 +#define MICROPY_HW_USB_PID 0x1203 +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMV3/mpconfigboard.mk b/ports/stm32/boards/OPENMV3/mpconfigboard.mk new file mode 100644 index 00000000000..7a1cacaa930 --- /dev/null +++ b/ports/stm32/boards/OPENMV3/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = f7 +CMSIS_MCU = STM32F765xx +AF_FILE = boards/stm32f767_af.csv +LD_FILE = boards/stm32f767.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMV3/pins.csv b/ports/stm32/boards/OPENMV3/pins.csv new file mode 100644 index 00000000000..2b1d1a236af --- /dev/null +++ b/ports/stm32/boards/OPENMV3/pins.csv @@ -0,0 +1,33 @@ +P0,PB15 +P1,PB14 +P2,PB13 +P3,PB12 +P4,PB10 +P5,PB11 +P6,PA5 +P7,PD12 +P8,PD13 +P9,PD14 +P10,PD15 +P11,PA13 +P12,PA14 +P13,PA0 +P14,PA1 +P15,PA2 +P16,PA3 +PA4,PA4 +PA15,PA15 +PC8,PC8 +PC9,PC9 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD2,PD2 +LED_IR,PE2 +LED_RED,PC0 +LED_GREEN,PC1 +LED_BLUE,PC2 +USB_VBUS,PA9 +USB_DM,PA11 +USB_DP,PA12 +USB_ID,PA10 diff --git a/ports/stm32/boards/OPENMV3/stm32f7xx_hal_conf.h b/ports/stm32/boards/OPENMV3/stm32f7xx_hal_conf.h new file mode 100644 index 00000000000..8ad33745bf9 --- /dev/null +++ b/ports/stm32/boards/OPENMV3/stm32f7xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F7XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#include "boards/stm32f7xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32F7XX_HAL_CONF_H diff --git a/ports/stm32/boards/OPENMV4/board_init.c b/ports/stm32/boards/OPENMV4/board_init.c new file mode 100644 index 00000000000..cc699644b5c --- /dev/null +++ b/ports/stm32/boards/OPENMV4/board_init.c @@ -0,0 +1,8 @@ +#include "py/mphal.h" +#define OMV_BOOTLOADER_MAGIC_ADDR (0x2001FFFCU) +#define OMV_BOOTLOADER_MAGIC_VALUE (0xB00710ADU) + +void board_enter_bootloader(void) { + *((uint32_t *) OMV_BOOTLOADER_MAGIC_ADDR) = OMV_BOOTLOADER_MAGIC_VALUE; + NVIC_SystemReset(); +} diff --git a/ports/stm32/boards/OPENMV4/mpconfigboard.h b/ports/stm32/boards/OPENMV4/mpconfigboard.h new file mode 100644 index 00000000000..ad58247786a --- /dev/null +++ b/ports/stm32/boards/OPENMV4/mpconfigboard.h @@ -0,0 +1,135 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMV4" +#define MICROPY_HW_MCU_NAME "STM32H743" +#define MICROPY_PY_SYS_PLATFORM "OpenMV4-H7" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-4" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_FATFS_EXFAT (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_ADC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SPI2 (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) + +// ROMFS config +#define MICROPY_HW_ROMFS_ENABLE_INTERNAL_FLASH (1) +#define MICROPY_HW_ROMFS_ENABLE_PART0 (1) + +#define MICROPY_BOARD_ENTER_STANDBY + +extern void board_enter_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader() + +// Note these are not used in top system.c. +#define MICROPY_HW_CLK_PLLM (3) +#define MICROPY_HW_CLK_PLLN (200) +#define MICROPY_HW_CLK_PLLP (2) +#define MICROPY_HW_CLK_PLLQ (8) +#define MICROPY_HW_CLK_PLLR (2) + +// UART1 config +#define MICROPY_HW_UART1_TX (pin_B14) +#define MICROPY_HW_UART1_RX (pin_B15) + +// UART3 config +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART3_RTS (pin_B14) +#define MICROPY_HW_UART3_CTS (pin_B13) + +// I2C buses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +#define MICROPY_HW_I2C4_SCL (pin_D12) +#define MICROPY_HW_I2C4_SDA (pin_D13) + +// SPI buses +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// FDCAN bus +#define MICROPY_HW_CAN2_NAME "FDCAN2" +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) +#define MICROPY_HW_CAN_IS_RESERVED(id) (id != PYB_CAN_2) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_D0) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) + +// LEDs +#define MICROPY_HW_LED1 (pin_C0) // red +#define MICROPY_HW_LED2 (pin_C1) // green +#define MICROPY_HW_LED3 (pin_C2) // blue +#define MICROPY_HW_LED4 (pin_E2) // IR +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +// NOTE: LEDs are active low. +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = (pin->pin_mask << 16)) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (4) + +// Board network interfaces config. +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +#define MICROPY_HW_USB_VID 0x37C5 +#define MICROPY_HW_USB_PID 0x1204 +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMV4/mpconfigboard.mk b/ports/stm32/boards/OPENMV4/mpconfigboard.mk new file mode 100644 index 00000000000..b262ec87fb3 --- /dev/null +++ b/ports/stm32/boards/OPENMV4/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = h7 +CMSIS_MCU = STM32H743xx +AF_FILE = boards/stm32h743_af.csv +LD_FILE = boards/stm32h743.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMV4/pins.csv b/ports/stm32/boards/OPENMV4/pins.csv new file mode 100644 index 00000000000..daaadf7fa4a --- /dev/null +++ b/ports/stm32/boards/OPENMV4/pins.csv @@ -0,0 +1,33 @@ +P0,PB15 +P1,PB14 +P2,PB13 +P3,PB12 +P4,PB10 +P5,PB11 +P6,PA5 +P7,PD12 +P8,PD13 +P9,PD14 +P10,PD15 +P11,PA13 +P12,PA14 +P13,-PA0 +P14,-PA1 +P15,-PA2 +P16,-PA3 +PA4,PA4 +PC8,PC8 +PC9,PC9 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD0,PD0 +PD2,PD2 +LED_IR,PE2 +LED_RED,-PC0 +LED_GREEN,-PC1 +LED_BLUE,-PC2 +USB_VBUS,PA9 +USB_DM,PA11 +USB_DP,PA12 +USB_ID,PA10 diff --git a/ports/stm32/boards/OPENMV4/stm32h7xx_hal_conf.h b/ports/stm32/boards/OPENMV4/stm32h7xx_hal_conf.h new file mode 100644 index 00000000000..b2ce050c162 --- /dev/null +++ b/ports/stm32/boards/OPENMV4/stm32h7xx_hal_conf.h @@ -0,0 +1,51 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define PREFETCH_ENABLE 1 +#define USE_RTOS 0 + +#define HAL_HSEM_MODULE_ENABLED +#define HAL_JPEG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_MDIOS_MODULE_ENABLED +#define HAL_MDMA_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_OPAMP_MODULE_ENABLED +#define HAL_QSPI_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPDIFRX_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_SWPMI_MODULE_ENABLED + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32h7xx_hal_hsem.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32h7xx_hal_mmc.h" +#endif + +#include "boards/stm32h7xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H diff --git a/ports/stm32/boards/OPENMV4P/bdev.c b/ports/stm32/boards/OPENMV4P/bdev.c new file mode 100644 index 00000000000..f7cfdd854be --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/bdev.c @@ -0,0 +1,18 @@ +#include "qspi.h" +#include "storage.h" + +#if MICROPY_HW_SPIFLASH_ENABLE_CACHE +// Shared cache for first and second SPI block devices +static mp_spiflash_cache_t spi_bdev_cache; +#endif + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_QSPI, + .bus.u_qspi.data = NULL, + .bus.u_qspi.proto = &qspi_proto, + #if MICROPY_HW_SPIFLASH_ENABLE_CACHE + .cache = &spi_bdev_cache, + #endif +}; + +spi_bdev_t spi_bdev; diff --git a/ports/stm32/boards/OPENMV4P/board_init.c b/ports/stm32/boards/OPENMV4P/board_init.c new file mode 100644 index 00000000000..c0c5e9b6863 --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/board_init.c @@ -0,0 +1,27 @@ +#include "py/mphal.h" +#include "storage.h" +#include "sdram.h" + +#define OMV_BOOTLOADER_MAGIC_ADDR (0x2001FFFCU) +#define OMV_BOOTLOADER_MAGIC_VALUE (0xB00710ADU) + +void board_low_power(int mode) { + switch (mode) { + case 0: // Leave stop mode. + sdram_leave_low_power(); + break; + case 1: // Enter stop mode. + sdram_enter_low_power(); + break; + case 2: // Enter standby mode. + sdram_enter_power_down(); + break; + } + // Enable QSPI deepsleep for modes 1 and 2 + mp_spiflash_deepsleep(&spi_bdev.spiflash, (mode != 0)); +} + +void board_enter_bootloader(void) { + *((uint32_t *) OMV_BOOTLOADER_MAGIC_ADDR) = OMV_BOOTLOADER_MAGIC_VALUE; + NVIC_SystemReset(); +} diff --git a/ports/stm32/boards/OPENMV4P/mpconfigboard.h b/ports/stm32/boards/OPENMV4P/mpconfigboard.h new file mode 100644 index 00000000000..e70d1da7a9a --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/mpconfigboard.h @@ -0,0 +1,259 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMV4P" +#define MICROPY_HW_MCU_NAME "STM32H743" +#define MICROPY_PY_SYS_PLATFORM "OpenMV4P-H7" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-4p" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_FATFS_EXFAT (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_ADC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SPI2 (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) + +// ROMFS config +#define MICROPY_HW_ROMFS_ENABLE_EXTERNAL_QSPI (1) +#define MICROPY_HW_ROMFS_QSPI_SPIFLASH_OBJ (&spi_bdev.spiflash) +#define MICROPY_HW_ROMFS_ENABLE_PART0 (1) + +// Flash storage config +#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1) +#define MICROPY_HW_SPIFLASH_SOFT_RESET (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +extern void board_enter_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader() + +void board_low_power(int mode); +#define MICROPY_BOARD_LEAVE_STOP board_low_power(0); +#define MICROPY_BOARD_ENTER_STOP board_low_power(1); +#define MICROPY_BOARD_ENTER_STANDBY board_low_power(2); + +// Note these are not used in top system.c. +#define MICROPY_HW_CLK_PLLM (3) +#define MICROPY_HW_CLK_PLLN (200) +#define MICROPY_HW_CLK_PLLP (2) +#define MICROPY_HW_CLK_PLLQ (8) +#define MICROPY_HW_CLK_PLLR (2) + +// UART1 config +#define MICROPY_HW_UART1_TX (pin_B14) +#define MICROPY_HW_UART1_RX (pin_B15) + +// UART3 config +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART3_RTS (pin_B14) +#define MICROPY_HW_UART3_CTS (pin_B13) + +// I2C buses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +#define MICROPY_HW_I2C4_SCL (pin_D12) +#define MICROPY_HW_I2C4_SDA (pin_D13) + +// SPI buses +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// FDCAN bus +#define MICROPY_HW_CAN2_NAME "FDCAN2" +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) +#define MICROPY_HW_CAN_IS_RESERVED(id) (id != PYB_CAN_2) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_G7) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) + +// LEDs +#define MICROPY_HW_LED1 (pin_C0) // red +#define MICROPY_HW_LED2 (pin_C1) // green +#define MICROPY_HW_LED3 (pin_C2) // blue +#define MICROPY_HW_LED4 (pin_E2) // IR +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +// NOTE: LEDs are active low. +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = (pin->pin_mask << 16)) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (2) + +// Board network interfaces config. +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +// QSPI Flash 256MBits +#define MICROPY_HW_QSPI_PRESCALER (2) // F_CLK = F_AHB/2 (100MHz) +#define MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 (28) +// Reserve 8MiB for romfs +#define MICROPY_HW_SPIFLASH_SIZE_BITS (192 * 1024 * 1024) +#define MICROPY_HW_QSPIFLASH_CS (pyb_pin_QSPIFLASH_CS) +#define MICROPY_HW_QSPIFLASH_SCK (pyb_pin_QSPIFLASH_SCK) +#define MICROPY_HW_QSPIFLASH_IO0 (pyb_pin_QSPIFLASH_IO0) +#define MICROPY_HW_QSPIFLASH_IO1 (pyb_pin_QSPIFLASH_IO1) +#define MICROPY_HW_QSPIFLASH_IO2 (pyb_pin_QSPIFLASH_IO2) +#define MICROPY_HW_QSPIFLASH_IO3 (pyb_pin_QSPIFLASH_IO3) + +// block device config for SPI flash +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_SPIFLASH (&spi_bdev) +#define MICROPY_HW_BDEV_SPIFLASH_CONFIG (&spiflash_config) +#define MICROPY_HW_BDEV_SPIFLASH_EXTENDED (&spi_bdev) +#define MICROPY_HW_BDEV_SPIFLASH_SIZE_BYTES (MICROPY_HW_SPIFLASH_SIZE_BITS / 8) + +// SDRAM +#define MICROPY_HW_SDRAM_SIZE (32 * 1024 * 1024) +#define MICROPY_HW_SDRAM_STARTUP_TEST (1) +#define MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR (true) + +// Timing configuration for 200MHz/2=100MHz (10ns) +#define MICROPY_HW_SDRAM_CLOCK_PERIOD 2 +#define MICROPY_HW_SDRAM_CAS_LATENCY 2 +#define MICROPY_HW_SDRAM_FREQUENCY_KHZ (100000) // 100 MHz +#define MICROPY_HW_SDRAM_TIMING_TMRD (2) +#define MICROPY_HW_SDRAM_TIMING_TXSR (7) +#define MICROPY_HW_SDRAM_TIMING_TRAS (5) +#define MICROPY_HW_SDRAM_TIMING_TRC (6) +#define MICROPY_HW_SDRAM_TIMING_TWR (3) +#define MICROPY_HW_SDRAM_TIMING_TRP (2) +#define MICROPY_HW_SDRAM_TIMING_TRCD (2) + +// 16-bit SDRAM +//#define MICROPY_HW_SDRAM_ROW_BITS_NUM 13 +//#define MICROPY_HW_SDRAM_MEM_BUS_WIDTH 16 +//#define MICROPY_HW_SDRAM_REFRESH_CYCLES 8192 + +// 32-bit SDRAM +#define MICROPY_HW_SDRAM_ROW_BITS_NUM 12 +#define MICROPY_HW_SDRAM_MEM_BUS_WIDTH 32 +#define MICROPY_HW_SDRAM_REFRESH_CYCLES 4096 + +#define MICROPY_HW_SDRAM_COLUMN_BITS_NUM 9 +#define MICROPY_HW_SDRAM_INTERN_BANKS_NUM 4 +#define MICROPY_HW_SDRAM_RPIPE_DELAY 0 +#define MICROPY_HW_SDRAM_RBURST (1) +#define MICROPY_HW_SDRAM_WRITE_PROTECTION (0) + +#define MICROPY_HW_SDRAM_AUTOREFRESH_NUM (8) +#define MICROPY_HW_SDRAM_BURST_LENGTH 1 +#define MICROPY_HW_SDRAM_REFRESH_RATE (64) // ms + +#define MICROPY_HW_FMC_SDCKE0 (pin_C5) +#define MICROPY_HW_FMC_SDNE0 (pin_C4) +#define MICROPY_HW_FMC_SDCLK (pin_G8) +#define MICROPY_HW_FMC_SDNCAS (pin_G15) +#define MICROPY_HW_FMC_SDNRAS (pin_F11) +#define MICROPY_HW_FMC_SDNWE (pin_A7) +#define MICROPY_HW_FMC_BA0 (pin_G4) +#define MICROPY_HW_FMC_BA1 (pin_G5) +#define MICROPY_HW_FMC_NBL0 (pin_E0) +#define MICROPY_HW_FMC_NBL1 (pin_E1) +#define MICROPY_HW_FMC_NBL2 (pin_I4) +#define MICROPY_HW_FMC_NBL3 (pin_I5) +#define MICROPY_HW_FMC_A0 (pin_F0) +#define MICROPY_HW_FMC_A1 (pin_F1) +#define MICROPY_HW_FMC_A2 (pin_F2) +#define MICROPY_HW_FMC_A3 (pin_F3) +#define MICROPY_HW_FMC_A4 (pin_F4) +#define MICROPY_HW_FMC_A5 (pin_F5) +#define MICROPY_HW_FMC_A6 (pin_F12) +#define MICROPY_HW_FMC_A7 (pin_F13) +#define MICROPY_HW_FMC_A8 (pin_F14) +#define MICROPY_HW_FMC_A9 (pin_F15) +#define MICROPY_HW_FMC_A10 (pin_G0) +#define MICROPY_HW_FMC_A11 (pin_G1) +#define MICROPY_HW_FMC_A12 (pin_G2) +#define MICROPY_HW_FMC_D0 (pin_D14) +#define MICROPY_HW_FMC_D1 (pin_D15) +#define MICROPY_HW_FMC_D2 (pin_D0) +#define MICROPY_HW_FMC_D3 (pin_D1) +#define MICROPY_HW_FMC_D4 (pin_E7) +#define MICROPY_HW_FMC_D5 (pin_E8) +#define MICROPY_HW_FMC_D6 (pin_E9) +#define MICROPY_HW_FMC_D7 (pin_E10) +#define MICROPY_HW_FMC_D8 (pin_E11) +#define MICROPY_HW_FMC_D9 (pin_E12) +#define MICROPY_HW_FMC_D10 (pin_E13) +#define MICROPY_HW_FMC_D11 (pin_E14) +#define MICROPY_HW_FMC_D12 (pin_E15) +#define MICROPY_HW_FMC_D13 (pin_D8) +#define MICROPY_HW_FMC_D14 (pin_D9) +#define MICROPY_HW_FMC_D15 (pin_D10) +#define MICROPY_HW_FMC_D16 (pin_H8) +#define MICROPY_HW_FMC_D17 (pin_H9) +#define MICROPY_HW_FMC_D18 (pin_H10) +#define MICROPY_HW_FMC_D19 (pin_H11) +#define MICROPY_HW_FMC_D20 (pin_H12) +#define MICROPY_HW_FMC_D21 (pin_H13) +#define MICROPY_HW_FMC_D22 (pin_H14) +#define MICROPY_HW_FMC_D23 (pin_H15) +#define MICROPY_HW_FMC_D24 (pin_I0) +#define MICROPY_HW_FMC_D25 (pin_I1) +#define MICROPY_HW_FMC_D26 (pin_I2) +#define MICROPY_HW_FMC_D27 (pin_I3) +#define MICROPY_HW_FMC_D28 (pin_I6) +#define MICROPY_HW_FMC_D29 (pin_I7) +#define MICROPY_HW_FMC_D30 (pin_I9) +#define MICROPY_HW_FMC_D31 (pin_I10) + +#define MICROPY_HW_USB_VID 0x37C5 +#define MICROPY_HW_USB_PID 0x124A +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMV4P/mpconfigboard.mk b/ports/stm32/boards/OPENMV4P/mpconfigboard.mk new file mode 100644 index 00000000000..b262ec87fb3 --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = h7 +CMSIS_MCU = STM32H743xx +AF_FILE = boards/stm32h743_af.csv +LD_FILE = boards/stm32h743.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMV4P/pins.csv b/ports/stm32/boards/OPENMV4P/pins.csv new file mode 100644 index 00000000000..a480c374b12 --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/pins.csv @@ -0,0 +1,97 @@ +P0,PB15 +P1,PB14 +P2,PB13 +P3,PB12 +P4,PB10 +P5,PB11 +P6,PA5 +P7,PD12 +P8,PD13 +P9,PG3 +P10,PD11 +P11,PA13 +P12,PA14 +P13,-PA0 +P14,-PA1 +P15,-PA2 +P16,-PA3 +PA4,PA4 +PC8,PC8 +PC9,PC9 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD2,PD2 +PG7,PG7 +LED_IR,PE2 +LED_RED,-PC0 +LED_GREEN,-PC1 +LED_BLUE,-PC2 +PA15,PA15 +USB_VBUS,-PA9 +-USB_DM,-PA11 +-USB_DP,-PA12 +-USB_ID,-PA10 +-QSPIFLASH_CS,-PG6 +-QSPIFLASH_SCK,-PF10 +-QSPIFLASH_IO0,-PF8 +-QSPIFLASH_IO1,-PF9 +-QSPIFLASH_IO2,-PF7 +-QSPIFLASH_IO3,-PF6 +-SDRAM_SDCKE0,-PC5 +-SDRAM_SDNE0,-PC4 +-SDRAM_SDCLK,-PG8 +-SDRAM_SDNCAS,-PG15 +-SDRAM_SDNRAS,-PF11 +-SDRAM_SDNWE,-PA7 +-SDRAM_BA0,-PG4 +-SDRAM_BA1,-PG5 +-SDRAM_NBL0,-PE0 +-SDRAM_NBL1,-PE1 +-SDRAM_NBL2,-PI4 +-SDRAM_NBL3,-PI5 +-SDRAM_A0,-PF0 +-SDRAM_A1,-PF1 +-SDRAM_A2,-PF2 +-SDRAM_A3,-PF3 +-SDRAM_A4,-PF4 +-SDRAM_A5,-PF5 +-SDRAM_A6,-PF12 +-SDRAM_A7,-PF13 +-SDRAM_A8,-PF14 +-SDRAM_A9,-PF15 +-SDRAM_A10,-PG0 +-SDRAM_A11,-PG1 +-SDRAM_A12,-PG2 +-SDRAM_D0,-PD14 +-SDRAM_D1,-PD15 +-SDRAM_D2,-PD0 +-SDRAM_D3,-PD1 +-SDRAM_D4,-PE7 +-SDRAM_D5,-PE8 +-SDRAM_D6,-PE9 +-SDRAM_D7,-PE10 +-SDRAM_D8,-PE11 +-SDRAM_D9,-PE12 +-SDRAM_D10,-PE13 +-SDRAM_D11,-PE14 +-SDRAM_D12,-PE15 +-SDRAM_D13,-PD8 +-SDRAM_D14,-PD9 +-SDRAM_D15,-PD10 +-SDRAM_D16,-PH8 +-SDRAM_D17,-PH9 +-SDRAM_D18,-PH10 +-SDRAM_D19,-PH11 +-SDRAM_D20,-PH12 +-SDRAM_D21,-PH13 +-SDRAM_D22,-PH14 +-SDRAM_D23,-PH15 +-SDRAM_D24,-PI0 +-SDRAM_D25,-PI1 +-SDRAM_D26,-PI2 +-SDRAM_D27,-PI3 +-SDRAM_D28,-PI6 +-SDRAM_D29,-PI7 +-SDRAM_D30,-PI9 +-SDRAM_D31,-PI10 diff --git a/ports/stm32/boards/OPENMV4P/stm32h7xx_hal_conf.h b/ports/stm32/boards/OPENMV4P/stm32h7xx_hal_conf.h new file mode 100644 index 00000000000..b2ce050c162 --- /dev/null +++ b/ports/stm32/boards/OPENMV4P/stm32h7xx_hal_conf.h @@ -0,0 +1,51 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define PREFETCH_ENABLE 1 +#define USE_RTOS 0 + +#define HAL_HSEM_MODULE_ENABLED +#define HAL_JPEG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_MDIOS_MODULE_ENABLED +#define HAL_MDMA_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_OPAMP_MODULE_ENABLED +#define HAL_QSPI_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPDIFRX_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_SWPMI_MODULE_ENABLED + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32h7xx_hal_hsem.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32h7xx_hal_mmc.h" +#endif + +#include "boards/stm32h7xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H diff --git a/ports/stm32/boards/OPENMVPT/bdev.c b/ports/stm32/boards/OPENMVPT/bdev.c new file mode 100644 index 00000000000..324bf241841 --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/bdev.c @@ -0,0 +1,14 @@ +#include "qspi.h" +#include "storage.h" + +// Shared cache for first and second SPI block devices +static mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_QSPI, + .bus.u_qspi.data = NULL, + .bus.u_qspi.proto = &qspi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; diff --git a/ports/stm32/boards/OPENMVPT/board_init.c b/ports/stm32/boards/OPENMVPT/board_init.c new file mode 100644 index 00000000000..937abbcc2c9 --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/board_init.c @@ -0,0 +1,74 @@ +#include "py/mphal.h" +#include "storage.h" +#include "sdram.h" + +#define OMV_BOOTLOADER_MAGIC_ADDR (0x2001FFFCU) +#define OMV_BOOTLOADER_MAGIC_VALUE (0xB00710ADU) + +void board_early_init(void) { + // Bring FLIR Lepton out of reset. + mp_hal_pin_config(pyb_pin_LEPTON_RSTN, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pyb_pin_LEPTON_RSTN, MP_HAL_PIN_SPEED_LOW); + mp_hal_pin_write(pyb_pin_LEPTON_RSTN, 1); + + // Release powerdown. + mp_hal_pin_config(pyb_pin_LEPTON_PWDN, MP_HAL_PIN_MODE_OUTPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pyb_pin_LEPTON_PWDN, MP_HAL_PIN_SPEED_LOW); + mp_hal_pin_write(pyb_pin_LEPTON_PWDN, 1); + + // Enable FLIR Lepton MCLK. + mp_hal_pin_config(pyb_pin_LEPTON_MCLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 4); + mp_hal_pin_config_speed(pyb_pin_LEPTON_MCLK, MP_HAL_PIN_SPEED_HIGH); + + // Hardcode the clock frequency as SystemClock_Config() hasn't been called yet. + int tclk = 120000000 * 2; // HAL_RCC_GetPCLK2Freq() * 2 + int period = (tclk / 24000000) - 1; + + TIM_HandleTypeDef mclk_tim_handle; + mclk_tim_handle.Instance = TIM15; + mclk_tim_handle.Init.Prescaler = 0; + mclk_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP; + mclk_tim_handle.Init.Period = period; + mclk_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + mclk_tim_handle.Init.RepetitionCounter = 0; + mclk_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + + TIM_OC_InitTypeDef mclk_tim_oc_handle; + mclk_tim_oc_handle.Pulse = (period + 1) / 2; + mclk_tim_oc_handle.OCMode = TIM_OCMODE_PWM1; + mclk_tim_oc_handle.OCPolarity = TIM_OCPOLARITY_HIGH; + mclk_tim_oc_handle.OCNPolarity = TIM_OCNPOLARITY_HIGH; + mclk_tim_oc_handle.OCFastMode = TIM_OCFAST_DISABLE; + mclk_tim_oc_handle.OCIdleState = TIM_OCIDLESTATE_RESET; + mclk_tim_oc_handle.OCNIdleState = TIM_OCNIDLESTATE_RESET; + + __HAL_RCC_TIM15_CLK_ENABLE(); + __HAL_RCC_TIM15_CLK_SLEEP_ENABLE(); + __HAL_RCC_TIM15_FORCE_RESET(); + __HAL_RCC_TIM15_RELEASE_RESET(); + + HAL_TIM_PWM_Init(&mclk_tim_handle); + HAL_TIM_PWM_ConfigChannel(&mclk_tim_handle, &mclk_tim_oc_handle, TIM_CHANNEL_2); + HAL_TIM_PWM_Start(&mclk_tim_handle, TIM_CHANNEL_2); +} + +void board_low_power(int mode) { + switch (mode) { + case 0: // Leave stop mode. + sdram_leave_low_power(); + break; + case 1: // Enter stop mode. + sdram_enter_low_power(); + break; + case 2: // Enter standby mode. + sdram_enter_power_down(); + break; + } + // Enable QSPI deepsleep for modes 1 and 2 + mp_spiflash_deepsleep(&spi_bdev.spiflash, (mode != 0)); +} + +void board_enter_bootloader(void) { + *((uint32_t *) OMV_BOOTLOADER_MAGIC_ADDR) = OMV_BOOTLOADER_MAGIC_VALUE; + NVIC_SystemReset(); +} diff --git a/ports/stm32/boards/OPENMVPT/mpconfigboard.h b/ports/stm32/boards/OPENMVPT/mpconfigboard.h new file mode 100644 index 00000000000..da4903f1ba1 --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/mpconfigboard.h @@ -0,0 +1,270 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (C) 2013-2025 OpenMV, LLC. + */ + +#define MICROPY_HW_BOARD_NAME "OPENMVPT" +#define MICROPY_HW_MCU_NAME "STM32H743" +#define MICROPY_PY_SYS_PLATFORM "OpenMVPureThermal" +#define MICROPY_HW_FLASH_FS_LABEL "OPENMV" + +// Network config +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "mpy-openmv-4p" + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_FATFS_EXFAT (1) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_ADC (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_SPI2 (1) +#define MICROPY_HW_ENABLE_USB (1) +#define MICROPY_HW_HAS_FLASH (1) +#define MICROPY_HW_ENABLE_SERVO (1) +#define MICROPY_HW_ENABLE_TIMER (1) +#define MICROPY_HW_ENABLE_SDCARD (1) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_TIM_IS_RESERVED(id) (id == 1 || id == 6) + +// ROMFS config +#define MICROPY_HW_ROMFS_ENABLE_EXTERNAL_QSPI (1) +#define MICROPY_HW_ROMFS_QSPI_SPIFLASH_OBJ (&spi_bdev.spiflash) +#define MICROPY_HW_ROMFS_ENABLE_PART0 (1) + +// Flash storage config +#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1) +#define MICROPY_HW_SPIFLASH_SOFT_RESET (1) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) + +#define MICROPY_BOARD_EARLY_INIT board_early_init +void board_early_init(void); + +extern void board_enter_bootloader(void); +#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) board_enter_bootloader() + +// Note these are not used in top system.c. +#define MICROPY_HW_CLK_PLLM (3) +#define MICROPY_HW_CLK_PLLN (200) +#define MICROPY_HW_CLK_PLLP (2) +#define MICROPY_HW_CLK_PLLQ (8) +#define MICROPY_HW_CLK_PLLR (2) + +// Use external 32kHz crystal for the RTC. +#define MICROPY_HW_RTC_USE_LSE (1) +#define MICROPY_HW_RTC_USE_BYPASS (0) +#define MICROPY_HW_RTC_USE_US (1) +#define MICROPY_HW_RTC_USE_CALOUT (0) + +void board_low_power(int mode); +#define MICROPY_BOARD_LEAVE_STOP board_low_power(0); +#define MICROPY_BOARD_ENTER_STOP board_low_power(1); +#define MICROPY_BOARD_ENTER_STANDBY board_low_power(2); + +// UART1 config +#define MICROPY_HW_UART1_TX (pin_B14) +#define MICROPY_HW_UART1_RX (pin_B15) + +// UART3 config +#define MICROPY_HW_UART3_TX (pin_B10) +#define MICROPY_HW_UART3_RX (pin_B11) +#define MICROPY_HW_UART3_RTS (pin_B14) +#define MICROPY_HW_UART3_CTS (pin_B13) + +// I2C buses +#define MICROPY_HW_I2C2_SCL (pin_B10) +#define MICROPY_HW_I2C2_SDA (pin_B11) + +#define MICROPY_HW_I2C4_SCL (pin_D12) +#define MICROPY_HW_I2C4_SDA (pin_D13) + +// SPI buses +#define MICROPY_HW_SPI2_NSS (pin_B12) +#define MICROPY_HW_SPI2_SCK (pin_B13) +#define MICROPY_HW_SPI2_MISO (pin_B14) +#define MICROPY_HW_SPI2_MOSI (pin_B15) + +// SPI buses +#define MICROPY_HW_SPI3_NSS (pin_A15) +#define MICROPY_HW_SPI3_SCK (pin_B3) +#define MICROPY_HW_SPI3_MISO (pin_B4) +#define MICROPY_HW_SPI3_MOSI (pin_B5) + +// FDCAN bus +#define MICROPY_HW_CAN2_NAME "FDCAN2" +#define MICROPY_HW_CAN2_TX (pin_B13) +#define MICROPY_HW_CAN2_RX (pin_B12) +#define MICROPY_HW_CAN_IS_RESERVED(id) (id != PYB_CAN_2) + +// SD card detect switch +#define MICROPY_HW_SDCARD_DETECT_PIN (pin_G7) +#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP) +#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET) + +// USB config +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_CDC_RX_DATA_SIZE (512) +#define MICROPY_HW_USB_CDC_TX_DATA_SIZE (512) +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) + +// LEDs +#define MICROPY_HW_LED1 (pin_C0) // red +#define MICROPY_HW_LED2 (pin_C1) // green +#define MICROPY_HW_LED3 (pin_C2) // blue +#define MICROPY_HW_LED4 (pin_G3) // white +#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP) +// NOTE: LEDs are active low. +#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = (pin->pin_mask << 16)) +#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask) + +// Servos +#define PYB_SERVO_NUM (2) + +// Board network interfaces config. +#if MICROPY_PY_WINC1500 +extern const struct _mp_obj_type_t mod_network_nic_type_winc; +#define MICROPY_PY_USOCKET_EXTENDED_STATE (1) +#define MICROPY_BOARD_NETWORK_INTERFACES \ + { MP_ROM_QSTR(MP_QSTR_WINC), MP_ROM_PTR(&mod_network_nic_type_winc) },\ + { MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&mod_network_nic_type_winc) }, +#else +#define MICROPY_BOARD_NETWORK_INTERFACES +#endif + +// QSPI Flash 256MBits +#define MICROPY_HW_QSPI_PRESCALER (2) // F_CLK = F_AHB/2 (100MHz) +#define MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 (28) +// Reserve 8MiB for romfs +#define MICROPY_HW_SPIFLASH_SIZE_BITS (192 * 1024 * 1024) +#define MICROPY_HW_QSPIFLASH_CS (pin_G6) +#define MICROPY_HW_QSPIFLASH_SCK (pin_F10) +#define MICROPY_HW_QSPIFLASH_IO0 (pin_F8) +#define MICROPY_HW_QSPIFLASH_IO1 (pin_F9) +#define MICROPY_HW_QSPIFLASH_IO2 (pin_F7) +#define MICROPY_HW_QSPIFLASH_IO3 (pin_F6) + +// block device config for SPI flash +extern const struct _mp_spiflash_config_t spiflash_config; +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_SPIFLASH (&spi_bdev) +#define MICROPY_HW_BDEV_SPIFLASH_CONFIG (&spiflash_config) +#define MICROPY_HW_BDEV_SPIFLASH_EXTENDED (&spi_bdev) +#define MICROPY_HW_BDEV_SPIFLASH_SIZE_BYTES (MICROPY_HW_SPIFLASH_SIZE_BITS / 8) + +// SDRAM +#define MICROPY_HW_SDRAM_SIZE (64 * 1024 * 1024) +#define MICROPY_HW_SDRAM_STARTUP_TEST (1) +#define MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR (true) + +// Timing configuration for 200MHz/2=100MHz (10ns) +#define MICROPY_HW_SDRAM_CLOCK_PERIOD 2 +#define MICROPY_HW_SDRAM_CAS_LATENCY 2 +#define MICROPY_HW_SDRAM_FREQUENCY_KHZ (100000) // 100 MHz +#define MICROPY_HW_SDRAM_TIMING_TMRD (2) +#define MICROPY_HW_SDRAM_TIMING_TXSR (7) +#define MICROPY_HW_SDRAM_TIMING_TRAS (5) +#define MICROPY_HW_SDRAM_TIMING_TRC (7) +#define MICROPY_HW_SDRAM_TIMING_TWR (3) +#define MICROPY_HW_SDRAM_TIMING_TRP (2) +#define MICROPY_HW_SDRAM_TIMING_TRCD (2) + +// 32-bit SDRAM +#define MICROPY_HW_SDRAM_ROW_BITS_NUM 13 +#define MICROPY_HW_SDRAM_MEM_BUS_WIDTH 32 +#define MICROPY_HW_SDRAM_REFRESH_CYCLES 8192 + +// IS42S32160F-7TLI - Industrial - 143MHz - 7ns - CAS Latency 2 - 10 ns - 100 MHz - 6 ns +#define MICROPY_HW_SDRAM_COLUMN_BITS_NUM 9 +#define MICROPY_HW_SDRAM_INTERN_BANKS_NUM 4 +#define MICROPY_HW_SDRAM_RPIPE_DELAY 0 +#define MICROPY_HW_SDRAM_RBURST (1) +#define MICROPY_HW_SDRAM_WRITE_PROTECTION (0) + +#define MICROPY_HW_SDRAM_AUTOREFRESH_NUM (8) +#define MICROPY_HW_SDRAM_BURST_LENGTH 1 +#define MICROPY_HW_SDRAM_REFRESH_RATE (64) // ms + +#define MICROPY_HW_FMC_SDCKE0 (pin_C5) +#define MICROPY_HW_FMC_SDNE0 (pin_C4) +#define MICROPY_HW_FMC_SDCLK (pin_G8) +#define MICROPY_HW_FMC_SDNCAS (pin_G15) +#define MICROPY_HW_FMC_SDNRAS (pin_F11) +#define MICROPY_HW_FMC_SDNWE (pin_A7) +#define MICROPY_HW_FMC_BA0 (pin_G4) +#define MICROPY_HW_FMC_BA1 (pin_G5) +#define MICROPY_HW_FMC_NBL0 (pin_E0) +#define MICROPY_HW_FMC_NBL1 (pin_E1) +#define MICROPY_HW_FMC_NBL2 (pin_I4) +#define MICROPY_HW_FMC_NBL3 (pin_I5) +#define MICROPY_HW_FMC_A0 (pin_F0) +#define MICROPY_HW_FMC_A1 (pin_F1) +#define MICROPY_HW_FMC_A2 (pin_F2) +#define MICROPY_HW_FMC_A3 (pin_F3) +#define MICROPY_HW_FMC_A4 (pin_F4) +#define MICROPY_HW_FMC_A5 (pin_F5) +#define MICROPY_HW_FMC_A6 (pin_F12) +#define MICROPY_HW_FMC_A7 (pin_F13) +#define MICROPY_HW_FMC_A8 (pin_F14) +#define MICROPY_HW_FMC_A9 (pin_F15) +#define MICROPY_HW_FMC_A10 (pin_G0) +#define MICROPY_HW_FMC_A11 (pin_G1) +#define MICROPY_HW_FMC_A12 (pin_G2) +#define MICROPY_HW_FMC_D0 (pin_D14) +#define MICROPY_HW_FMC_D1 (pin_D15) +#define MICROPY_HW_FMC_D2 (pin_D0) +#define MICROPY_HW_FMC_D3 (pin_D1) +#define MICROPY_HW_FMC_D4 (pin_E7) +#define MICROPY_HW_FMC_D5 (pin_E8) +#define MICROPY_HW_FMC_D6 (pin_E9) +#define MICROPY_HW_FMC_D7 (pin_E10) +#define MICROPY_HW_FMC_D8 (pin_E11) +#define MICROPY_HW_FMC_D9 (pin_E12) +#define MICROPY_HW_FMC_D10 (pin_E13) +#define MICROPY_HW_FMC_D11 (pin_E14) +#define MICROPY_HW_FMC_D12 (pin_E15) +#define MICROPY_HW_FMC_D13 (pin_D8) +#define MICROPY_HW_FMC_D14 (pin_D9) +#define MICROPY_HW_FMC_D15 (pin_D10) +#define MICROPY_HW_FMC_D16 (pin_H8) +#define MICROPY_HW_FMC_D17 (pin_H9) +#define MICROPY_HW_FMC_D18 (pin_H10) +#define MICROPY_HW_FMC_D19 (pin_H11) +#define MICROPY_HW_FMC_D20 (pin_H12) +#define MICROPY_HW_FMC_D21 (pin_H13) +#define MICROPY_HW_FMC_D22 (pin_H14) +#define MICROPY_HW_FMC_D23 (pin_H15) +#define MICROPY_HW_FMC_D24 (pin_I0) +#define MICROPY_HW_FMC_D25 (pin_I1) +#define MICROPY_HW_FMC_D26 (pin_I2) +#define MICROPY_HW_FMC_D27 (pin_I3) +#define MICROPY_HW_FMC_D28 (pin_I6) +#define MICROPY_HW_FMC_D29 (pin_I7) +#define MICROPY_HW_FMC_D30 (pin_I9) +#define MICROPY_HW_FMC_D31 (pin_I10) + +#define MICROPY_HW_USB_VID 0x37C5 +#define MICROPY_HW_USB_PID 0x1205 +#define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3 (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC2_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_PID_CDC3_MSC_HID (MICROPY_HW_USB_PID) +#define MICROPY_HW_USB_LANGID_STRING 0x409 +#define MICROPY_HW_USB_MANUFACTURER_STRING "OpenMV" +#define MICROPY_HW_USB_PRODUCT_FS_STRING "OpenMV Virtual Comm Port in FS Mode" +#define MICROPY_HW_USB_PRODUCT_HS_STRING "OpenMV Virtual Comm Port in HS Mode" +#define MICROPY_HW_USB_INTERFACE_FS_STRING "VCP Interface" +#define MICROPY_HW_USB_INTERFACE_HS_STRING "VCP Interface" +#define MICROPY_HW_USB_CONFIGURATION_FS_STRING "VCP Config" +#define MICROPY_HW_USB_CONFIGURATION_HS_STRING "VCP Config" diff --git a/ports/stm32/boards/OPENMVPT/mpconfigboard.mk b/ports/stm32/boards/OPENMVPT/mpconfigboard.mk new file mode 100644 index 00000000000..b262ec87fb3 --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = h7 +CMSIS_MCU = STM32H743xx +AF_FILE = boards/stm32h743_af.csv +LD_FILE = boards/stm32h743.ld +GIT_SUBMODULES += lib/mbedtls diff --git a/ports/stm32/boards/OPENMVPT/pins.csv b/ports/stm32/boards/OPENMVPT/pins.csv new file mode 100644 index 00000000000..af75cb3653d --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/pins.csv @@ -0,0 +1,111 @@ +P0,PB15 +P1,PB14 +P2,PB13 +P3,PB12 +P4,PB10 +P5,PB11 +P6,PA5 +P7,PD12 +P8,PD13 +P9,PE2 +PC8,PC8 +PC9,PC9 +PC10,PC10 +PC11,PC11 +PC12,PC12 +PD2,PD2 +PG7,PG7 +LED_WHITE,PG3 +LED_RED,-PC0 +LED_GREEN,-PC2 +LED_BLUE,-PC1 +BUZZER,PA1 +PA4,PA4 +PA15,PA15 +PB3,PB3 +PB4,PB4 +PB5,PB5 +USB_VBUS,PA9 +-USB_DM,PA11 +-USB_DP,PA12 +-USB_ID,PA10 +-QSPIFLASH_CS,PG6 +-QSPIFLASH_SCK,-PF10 +-QSPIFLASH_IO0,-PF8 +-QSPIFLASH_IO1,-PF9 +-QSPIFLASH_IO2,-PF7 +-QSPIFLASH_IO3,-PF6 +-SDRAM_SDCKE0,-PC5 +-SDRAM_SDNE0,-PC4 +-SDRAM_SDCLK,PG8 +-SDRAM_SDNCAS,PG15 +-SDRAM_SDNRAS,-PF11 +-SDRAM_SDNWE,-PA7 +-SDRAM_BA0,PG4 +-SDRAM_BA1,PG5 +-SDRAM_NBL0,PE0 +-SDRAM_NBL1,PE1 +-SDRAM_NBL2,PI4 +-SDRAM_NBL3,PI5 +-SDRAM_A0,PF0 +-SDRAM_A1,PF1 +-SDRAM_A2,PF2 +-SDRAM_A3,-PF3 +-SDRAM_A4,-PF4 +-SDRAM_A5,-PF5 +-SDRAM_A6,PF12 +-SDRAM_A7,PF13 +-SDRAM_A8,-PF14 +-SDRAM_A9,PF15 +-SDRAM_A10,PG0 +-SDRAM_A11,PG1 +-SDRAM_A12,PG2 +-SDRAM_D0,PD14 +-SDRAM_D1,PD15 +-SDRAM_D2,PD0 +-SDRAM_D3,PD1 +-SDRAM_D4,PE7 +-SDRAM_D5,PE8 +-SDRAM_D6,PE9 +-SDRAM_D7,PE10 +-SDRAM_D8,PE11 +-SDRAM_D9,PE12 +-SDRAM_D10,PE13 +-SDRAM_D11,PE14 +-SDRAM_D12,PE15 +-SDRAM_D13,PD8 +-SDRAM_D14,PD9 +-SDRAM_D15,PD10 +-SDRAM_D16,PH8 +-SDRAM_D17,PH9 +-SDRAM_D18,PH10 +-SDRAM_D19,PH11 +-SDRAM_D20,PH12 +-SDRAM_D21,PH13 +-SDRAM_D22,PH14 +-SDRAM_D23,PH15 +-SDRAM_D24,PI0 +-SDRAM_D25,PI1 +-SDRAM_D26,PI2 +-SDRAM_D27,PI3 +-SDRAM_D28,PI6 +-SDRAM_D29,PI7 +-SDRAM_D30,PI9 +-SDRAM_D31,PI10 +-OV5640_INT,PC13 +-LEPTON_VSYNC,PE3 +-HDMI_CEC,-PH2 +-DVI_RST,PD11 +-DVI_SCL,-PB1 +-DVI_SDA,PB2 +-DVI_INT,PI8 +-DDC_SCL,-PH3 +-DDC_SDA,-PH4 +TOUCH_RST,PK2 +TOUCH_SCL,PJ13 +TOUCH_SDA,PJ14 +TOUCH_INT,PJ6 +WINC_INT,-PH5 +LEPTON_RSTN,PD5 +LEPTON_PWDN,PD4 +LEPTON_MCLK,PA3 diff --git a/ports/stm32/boards/OPENMVPT/stm32h7xx_hal_conf.h b/ports/stm32/boards/OPENMVPT/stm32h7xx_hal_conf.h new file mode 100644 index 00000000000..b2ce050c162 --- /dev/null +++ b/ports/stm32/boards/OPENMVPT/stm32h7xx_hal_conf.h @@ -0,0 +1,51 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (12000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (5000) +#define LSE_STARTUP_TIMEOUT (5000) + +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 1 +#define PREFETCH_ENABLE 1 +#define USE_RTOS 0 + +#define HAL_HSEM_MODULE_ENABLED +#define HAL_JPEG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_MDIOS_MODULE_ENABLED +#define HAL_MDMA_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_OPAMP_MODULE_ENABLED +#define HAL_QSPI_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPDIFRX_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_SWPMI_MODULE_ENABLED + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32h7xx_hal_hsem.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32h7xx_hal_mmc.h" +#endif + +#include "boards/stm32h7xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32H7XX_HAL_CONF_H diff --git a/ports/stm32/boards/stm32f427_af.csv b/ports/stm32/boards/stm32f427_af.csv index 34d5a94cb8f..f55eaebf318 100644 --- a/ports/stm32/boards/stm32f427_af.csv +++ b/ports/stm32/boards/stm32f427_af.csv @@ -107,7 +107,7 @@ PortG,PG7 , , , , , , PortG,PG8 , , , , , ,SPI6_NSS , , ,USART6_RTS , , ,ETH_PPS_OUT ,FMC_SDCLK , , ,EVENTOUT, PortG,PG9 , , , , , , , , ,USART6_RX , , , ,FMC_NE2/FMC_NCE3 ,DCMI_VSYNC , ,EVENTOUT, PortG,PG10, , , , , , , , , , , , ,FMC_NCE4_1/FMC_NE3,DCMI_D2 , ,EVENTOUT, -PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 , ,EVENTOUT, +PortG,PG11, , , , , , , , , , , ,ETH_MII_TX_EN/ETH_RMII_TX_EN ,FMC_NCE4_2 ,DCMI_D3 , ,EVENTOUT, PortG,PG12, , , , , ,SPI6_MISO , , ,USART6_RTS , , , ,FMC_NE4 , , ,EVENTOUT, PortG,PG13, , , , , ,SPI6_SCK , , ,USART6_CTS , , ,ETH_MII_TXD0/ETH_RMII_TXD0 ,FMC_A24 , , ,EVENTOUT, PortG,PG14, , , , , ,SPI6_MOSI , , ,USART6_TX , , ,ETH_MII_TXD1/ETH_RMII_TXD1 ,FMC_A25 , , ,EVENTOUT, From da1e56cb3480849509c28e69b43451e55e2c78a0 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 07:22:38 +0100 Subject: [PATCH 17/45] stm32: OpenMV build patch. --- ports/stm32/Makefile | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index b43f284b1ab..cff4d734e70 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -100,14 +100,15 @@ GEN_PLLFREQTABLE_HDR = $(HEADER_BUILD)/pllfreqtable.h GEN_PLLI2STABLE_HDR = $(HEADER_BUILD)/plli2stable.h GEN_STMCONST_HDR = $(HEADER_BUILD)/modstm_const.h GEN_STMCONST_MPZ = $(HEADER_BUILD)/modstm_mpz.h -CMSIS_MCU_HDR = $(STM32LIB_CMSIS_ABS)/Include/$(CMSIS_MCU_LOWER).h +CMSIS_MCU_HDR = $(STM32LIB_CMSIS_ABS)/include/st/$(CMSIS_MCU_LOWER).h INC += -I. -INC += -I$(TOP) +INC += -I.. INC += -I$(BUILD) INC += -I$(TOP)/lib/cmsis/inc -INC += -I$(STM32LIB_CMSIS_ABS)/Include -INC += -I$(STM32LIB_HAL_ABS)/Inc +INC += -I$(STM32LIB_CMSIS_ABS)/include +INC += -I$(STM32LIB_CMSIS_ABS)/include/st +INC += -I$(STM32LIB_HAL_ABS)/include INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc #INC += -I$(USBHOST_DIR) INC += -I$(TOP)/lib/tinyusb/src @@ -115,6 +116,7 @@ INC += -I$(TOP)/shared/tinyusb/ INC += -Ilwip_inc CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA) +CFLAGS += -fno-inline-small-functions CFLAGS += -D$(CMSIS_MCU) -DUSE_FULL_LL_DRIVER CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) CFLAGS += $(COPT) @@ -178,7 +180,7 @@ endif # Debugging/Optimization ifeq ($(DEBUG), 1) -CFLAGS += -g -DPENDSV_DEBUG +CFLAGS += -ggdb3 -DPENDSV_DEBUG COPT ?= -Og # Disable text compression in debug builds MICROPY_ROM_TEXT_COMPRESSION = 0 @@ -244,9 +246,7 @@ DRIVERS_SRC_C += $(addprefix drivers/,\ dht/dht.c \ ) -SRC_C += \ - boardctrl.c \ - main.c \ +SRC_C = \ stm32_it.c \ usbd.c \ usbd_conf.c \ @@ -341,7 +341,6 @@ SRC_O += resethandler.o endif else SRC_O += \ - system_stm32.o \ resethandler.o \ shared/runtime/gchelper_thumb2.o endif @@ -539,7 +538,7 @@ $(PY_BUILD)/parsenum.o: COPT += -Os $(PY_BUILD)/mpprint.o: COPT += -Os endif -all: $(TOP)/lib/stm32lib/README.md all_main $(BUILD)/firmware.hex +all: $(OBJ) ifeq ($(MBOOT_ENABLE_PACKING),1) all_main: $(BUILD)/firmware.pack.dfu @@ -553,11 +552,6 @@ else all_main: $(BUILD)/firmware.dfu endif -# For convenience, automatically fetch required submodules if they don't exist -$(TOP)/lib/stm32lib/README.md: - $(ECHO) "stm32lib submodule not found, fetching it now..." - (cd $(TOP) && git submodule update --init lib/stm32lib) - define RUN_DFU $(ECHO) "Writing $(1) to the board" $(if $(filter $(USE_PYDFU),1),\ @@ -697,7 +691,7 @@ $(HEADER_BUILD)/qstrdefs.generated.h: $(BOARD_DIR)/mpconfigboard.h # main.c can't be even preprocessed without $(GEN_CDCINF_HEADER) # As main.c is in SRC_QSTR this will also ensure that GEN_CDCINF_HEADER # will be run before QSTR extraction. -main.c: $(GEN_CDCINF_HEADER) +factoryreset.c: $(GEN_CDCINF_HEADER) # Use a pattern rule here so that make will only call make-pins.py once to make # both pins_$(BOARD).c and pins.h From e7e156b111f9c08ee9dc9a42a44e0c84943c0a37 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 10 Aug 2025 16:45:47 +0200 Subject: [PATCH 18/45] stm32/boards/OPENMV_N6: Fix board config. Signed-off-by: iabdalkader --- ports/stm32/boards/OPENMV_N6/board.c | 28 ++++++++++++++++++- ports/stm32/boards/OPENMV_N6/mpconfigboard.h | 4 ++- ports/stm32/boards/OPENMV_N6/mpconfigboard.mk | 4 +-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ports/stm32/boards/OPENMV_N6/board.c b/ports/stm32/boards/OPENMV_N6/board.c index 1f82d10bac2..d4b2fa1a164 100644 --- a/ports/stm32/boards/OPENMV_N6/board.c +++ b/ports/stm32/boards/OPENMV_N6/board.c @@ -94,7 +94,20 @@ void board_enter_bootloader(unsigned int n_args, const void *args) { // Support both OpenMV bootloader and mboot. *((uint32_t *)OMV_BOOT_MAGIC_ADDR) = OMV_BOOT_MAGIC_VALUE; SCB_CleanDCache(); - boardctrl_maybe_enter_mboot(n_args, args); + NVIC_SystemReset(); +} + +static char _boot_mem[128] __attribute__((aligned(1024))); + +__attribute__((naked, noreturn, section(".ram_function"))) void ram_reset(void) { + // NVIC_SystemReset doesn't get inlined here. + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); + for (;;) { + __NOP(); + } } void board_early_init(void) { @@ -104,6 +117,19 @@ void board_early_init(void) { LL_PWR_SetWakeUpPinPolarityLow(LL_PWR_WAKEUP_PIN3 | LL_PWR_WAKEUP_PIN2); } +void board_enter_standby(void) { + HAL_PWREx_EnableTCMRetention(); + HAL_PWREx_EnableTCMFLXRetention(); + + uint32_t *boot_mem = (uint32_t *)_boot_mem; + boot_mem[0] = (uint32_t)(_boot_mem + sizeof(_boot_mem)); + boot_mem[1] = ((uint32_t)&ram_reset) | 1; + SCB_CleanDCache_by_Addr((uint32_t *)_boot_mem, 32); + + SYSCFG->INITSVTORCR = (uint32_t) boot_mem; + (void) SYSCFG->INITSVTORCR; +} + void board_leave_standby(void) { // TODO: move some of the below code to a common location for all N6 boards? diff --git a/ports/stm32/boards/OPENMV_N6/mpconfigboard.h b/ports/stm32/boards/OPENMV_N6/mpconfigboard.h index 0d63ff22478..751da650bfe 100644 --- a/ports/stm32/boards/OPENMV_N6/mpconfigboard.h +++ b/ports/stm32/boards/OPENMV_N6/mpconfigboard.h @@ -20,7 +20,8 @@ #define MICROPY_BOARD_ENTER_BOOTLOADER board_enter_bootloader #define MICROPY_BOARD_EARLY_INIT board_early_init -#define MICROPY_BOARD_LEAVE_STANDBY board_leave_standby() +#define MICROPY_BOARD_ENTER_STANDBY board_enter_standby(); +#define MICROPY_BOARD_LEAVE_STANDBY board_leave_standby(); // HSE is 48MHz, this gives a CPU frequency of 800MHz. #define MICROPY_HW_CLK_PLLM (6) @@ -185,4 +186,5 @@ void mboot_board_entry_init(void); void board_enter_bootloader(unsigned int n_args, const void *args); void board_early_init(void); +void board_enter_standby(void); void board_leave_standby(void); diff --git a/ports/stm32/boards/OPENMV_N6/mpconfigboard.mk b/ports/stm32/boards/OPENMV_N6/mpconfigboard.mk index a4afb7a976a..8f748a0b8de 100644 --- a/ports/stm32/boards/OPENMV_N6/mpconfigboard.mk +++ b/ports/stm32/boards/OPENMV_N6/mpconfigboard.mk @@ -1,5 +1,5 @@ # This board requires a bootloader, either mboot or OpenMV's bootloader. -USE_MBOOT = 1 +USE_MBOOT ?= 1 MCU_SERIES = n6 CMSIS_MCU = STM32N657xx @@ -24,7 +24,7 @@ MICROPY_PY_LWIP ?= 1 MICROPY_PY_NETWORK_CYW43 ?= 1 MICROPY_PY_SSL ?= 1 MICROPY_SSL_MBEDTLS ?= 1 -MICROPY_VFS_LFS2 ?= 1 +MICROPY_VFS_LFS2 ?= 0 # Board specific frozen modules FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py From 202936f5ac9be19ef0c31d3e0b8c107e2d1e778f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 07:13:25 +0100 Subject: [PATCH 19/45] stm32/boards/Arduino: Update Arduino boards config. --- ports/stm32/boards/ARDUINO_GIGA/mpconfigboard.h | 2 +- ports/stm32/boards/ARDUINO_OPTA/mpconfigboard.h | 1 - ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ports/stm32/boards/ARDUINO_GIGA/mpconfigboard.h b/ports/stm32/boards/ARDUINO_GIGA/mpconfigboard.h index 71097406b43..2ed75e320f3 100644 --- a/ports/stm32/boards/ARDUINO_GIGA/mpconfigboard.h +++ b/ports/stm32/boards/ARDUINO_GIGA/mpconfigboard.h @@ -302,7 +302,7 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_FMC_D15 (pin_D10) #define MICROPY_HW_USB_VID 0x2341 -#define MICROPY_HW_USB_PID 0x0566 +#define MICROPY_HW_USB_PID 0x0466 #define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) #define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) #define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) diff --git a/ports/stm32/boards/ARDUINO_OPTA/mpconfigboard.h b/ports/stm32/boards/ARDUINO_OPTA/mpconfigboard.h index 851b9f9d2f8..e20e6108fab 100644 --- a/ports/stm32/boards/ARDUINO_OPTA/mpconfigboard.h +++ b/ports/stm32/boards/ARDUINO_OPTA/mpconfigboard.h @@ -34,7 +34,6 @@ void OPTA_board_startup(void); #define MICROPY_BOARD_EARLY_INIT OPTA_board_early_init void OPTA_board_early_init(void); -#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) #define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) OPTA_board_enter_bootloader() void OPTA_board_enter_bootloader(void); diff --git a/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.h b/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.h index 1c1a804c5ec..f0964c3b6be 100644 --- a/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.h +++ b/ports/stm32/boards/ARDUINO_PORTENTA_H7/mpconfigboard.h @@ -326,7 +326,7 @@ extern struct _spi_bdev_t spi_bdev; #define MICROPY_HW_ETH_RMII_TXD1 (pin_G12) #define MICROPY_HW_USB_VID 0x2341 -#define MICROPY_HW_USB_PID 0x055B +#define MICROPY_HW_USB_PID 0x045B #define MICROPY_HW_USB_PID_CDC_MSC (MICROPY_HW_USB_PID) #define MICROPY_HW_USB_PID_CDC_HID (MICROPY_HW_USB_PID) #define MICROPY_HW_USB_PID_CDC (MICROPY_HW_USB_PID) From a32089a7a0c6f6f8d006be2362177843d24e48f2 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 09:10:54 +0100 Subject: [PATCH 20/45] stm32/timer: Switch the default servo timer to TIM4. All older boards use TIM4 for the PWM. --- ports/stm32/servo.c | 61 +++++++++++++++++++++--------------------- ports/stm32/stm32_it.c | 2 +- ports/stm32/timer.c | 32 +++++++++++----------- ports/stm32/timer.h | 4 +-- 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/ports/stm32/servo.c b/ports/stm32/servo.c index ea8205756a6..577547818d1 100644 --- a/ports/stm32/servo.c +++ b/ports/stm32/servo.c @@ -40,11 +40,10 @@ // The driver uses hardware PWM to drive servos on pins X1, X2, X3, X4 which are // assumed to be on PA0, PA1, PA2, PA3 but not necessarily in that order (the // pins PA0-PA3 are used directly if the X pins are not defined). -// -// TIM2 and TIM5 have CH1-CH4 on PA0-PA3 respectively. They are both 32-bit -// counters with 16-bit prescaler. TIM5 is used by this driver. -#define PYB_SERVO_NUM (4) +#ifndef PYB_SERVO_NUM +#define PYB_SERVO_NUM (2) +#endif typedef struct _pyb_servo_obj_t { mp_obj_base_t base; @@ -76,18 +75,14 @@ void servo_init(void) { pyb_servo_obj[i].time_left = 0; } - // assign servo objects to specific pins (must be some permutation of PA0-PA3) - #ifdef pyb_pin_X1 - pyb_servo_obj[0].pin = pyb_pin_X1; - pyb_servo_obj[1].pin = pyb_pin_X2; - pyb_servo_obj[2].pin = pyb_pin_X3; - pyb_servo_obj[3].pin = pyb_pin_X4; - #else - pyb_servo_obj[0].pin = pin_A0; - pyb_servo_obj[1].pin = pin_A1; - pyb_servo_obj[2].pin = pin_A2; - pyb_servo_obj[3].pin = pin_A3; - #endif + pyb_servo_obj[0].pin = pin_D12; + pyb_servo_obj[1].pin = pin_D13; +#if PYB_SERVO_NUM >= 3 + pyb_servo_obj[2].pin = pin_D14; +#endif +#if PYB_SERVO_NUM >= 4 + pyb_servo_obj[3].pin = pin_D15; +#endif } void servo_timer_irq_callback(void) { @@ -113,26 +108,26 @@ void servo_timer_irq_callback(void) { need_it = true; } // set the pulse width - *(&TIM5->CCR1 + s->pin->pin) = s->pulse_cur; + *(&TIM4->CCR1 + (s->pin->pin - 12)) = s->pulse_cur; } } if (need_it) { - __HAL_TIM_ENABLE_IT(&TIM5_Handle, TIM_IT_UPDATE); + __HAL_TIM_ENABLE_IT(&TIM4_Handle, TIM_IT_UPDATE); } else { - __HAL_TIM_DISABLE_IT(&TIM5_Handle, TIM_IT_UPDATE); + __HAL_TIM_DISABLE_IT(&TIM4_Handle, TIM_IT_UPDATE); } } static void servo_init_channel(pyb_servo_obj_t *s) { static const uint8_t channel_table[4] = {TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3, TIM_CHANNEL_4}; - uint32_t channel = channel_table[s->pin->pin]; + uint32_t channel = channel_table[s->pin->pin - 12]; // GPIO configuration - mp_hal_pin_config(s->pin, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, GPIO_AF2_TIM5); + mp_hal_pin_config(s->pin, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, GPIO_AF2_TIM4); - if (__HAL_RCC_TIM5_IS_CLK_DISABLED()) { - timer_tim5_init(); + if (__HAL_RCC_TIM4_IS_CLK_DISABLED()) { + timer_tim4_init(); } // PWM mode configuration @@ -141,10 +136,14 @@ static void servo_init_channel(pyb_servo_obj_t *s) { oc_init.Pulse = s->pulse_cur; // units of 10us oc_init.OCPolarity = TIM_OCPOLARITY_HIGH; oc_init.OCFastMode = TIM_OCFAST_DISABLE; - HAL_TIM_PWM_ConfigChannel(&TIM5_Handle, &oc_init, channel); + HAL_TIM_PWM_ConfigChannel(&TIM4_Handle, &oc_init, channel); // start PWM - HAL_TIM_PWM_Start(&TIM5_Handle, channel); + #if defined(STM32H7) + // Reset channel state to ready before calling HAL_PWM/IC/OC_Start_IT() + HAL_TIM_PWM_Stop(&TIM4_Handle, channel); + #endif + HAL_TIM_PWM_Start(&TIM4_Handle, channel); } /******************************************************************************/ @@ -161,16 +160,16 @@ static mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) { } switch (p) { case 1: - TIM5->CCR1 = v; + TIM4->CCR1 = v; break; case 2: - TIM5->CCR2 = v; + TIM4->CCR2 = v; break; case 3: - TIM5->CCR3 = v; + TIM4->CCR3 = v; break; case 4: - TIM5->CCR4 = v; + TIM4->CCR4 = v; break; } return mp_const_none; @@ -181,8 +180,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(pyb_servo_set_obj, pyb_servo_set); static mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) { int pe = mp_obj_get_int(period); int pu = mp_obj_get_int(pulse); - TIM5->ARR = pe; - TIM5->CCR3 = pu; + TIM4->ARR = pe; + TIM4->CCR3 = pu; return mp_const_none; } diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 17b95326460..7d5f4792dba 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -730,6 +730,7 @@ void TIM3_IRQHandler(void) { void TIM4_IRQHandler(void) { IRQ_ENTER(TIM4_IRQn); timer_irq_handler(4); + HAL_TIM_IRQHandler(&TIM4_Handle); IRQ_EXIT(TIM4_IRQn); } #endif @@ -737,7 +738,6 @@ void TIM4_IRQHandler(void) { void TIM5_IRQHandler(void) { IRQ_ENTER(TIM5_IRQn); timer_irq_handler(5); - HAL_TIM_IRQHandler(&TIM5_Handle); IRQ_EXIT(TIM5_IRQn); } diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index aa410928298..5ce33abe9c7 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -73,7 +73,7 @@ // TIM3: // - LED 4, PWM to set the LED intensity // -// TIM5: +// TIM4: // - servo controller, PWM // // TIM6: @@ -144,7 +144,7 @@ typedef struct _pyb_timer_obj_t { #define TIMER_CNT_MASK(self) ((self)->is_32bit ? 0xffffffff : 0xffff) #define TIMER_CHANNEL(self) ((((self)->channel) - 1) << 2) -TIM_HandleTypeDef TIM5_Handle; +TIM_HandleTypeDef TIM4_Handle; TIM_HandleTypeDef TIM6_Handle; #define PYB_TIMER_OBJ_ALL_NUM MP_ARRAY_SIZE(MP_STATE_PORT(pyb_timer_obj_all)) @@ -169,25 +169,25 @@ void timer_deinit(void) { } } -#if defined(TIM5) -// TIM5 is set-up for the servo controller +#if defined(TIM4) +// TIM4 is set-up for the servo controller // This function inits but does not start the timer -void timer_tim5_init(void) { - // TIM5 clock enable - __HAL_RCC_TIM5_CLK_ENABLE(); +void timer_tim4_init(void) { + // TIM4 clock enable + __HAL_RCC_TIM4_CLK_ENABLE(); // set up and enable interrupt - NVIC_SetPriority(TIM5_IRQn, IRQ_PRI_TIM5); - HAL_NVIC_EnableIRQ(TIM5_IRQn); + NVIC_SetPriority(TIM4_IRQn, IRQ_PRI_TIM4); + HAL_NVIC_EnableIRQ(TIM4_IRQn); // PWM clock configuration - TIM5_Handle.Instance = TIM5; - TIM5_Handle.Init.Period = 2000 - 1; // timer cycles at 50Hz - TIM5_Handle.Init.Prescaler = (timer_get_source_freq(5) / 100000) - 1; // timer runs at 100kHz - TIM5_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - TIM5_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; + TIM4_Handle.Instance = TIM4; + TIM4_Handle.Init.Period = 2000 - 1; // timer cycles at 50Hz + TIM4_Handle.Init.Prescaler = (timer_get_source_freq(4) / 100000) - 1; // timer runs at 100kHz + TIM4_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + TIM4_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; - HAL_TIM_PWM_Init(&TIM5_Handle); + HAL_TIM_PWM_Init(&TIM4_Handle); } #endif @@ -223,7 +223,7 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) { // Interrupt dispatch void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { #if MICROPY_HW_ENABLE_SERVO - if (htim == &TIM5_Handle) { + if (htim == &TIM4_Handle) { servo_timer_irq_callback(); } #endif diff --git a/ports/stm32/timer.h b/ports/stm32/timer.h index 2ba91cf158d..8aca8270f97 100644 --- a/ports/stm32/timer.h +++ b/ports/stm32/timer.h @@ -26,12 +26,12 @@ #ifndef MICROPY_INCLUDED_STM32_TIMER_H #define MICROPY_INCLUDED_STM32_TIMER_H -extern TIM_HandleTypeDef TIM5_Handle; +extern TIM_HandleTypeDef TIM4_Handle; extern const mp_obj_type_t pyb_timer_type; void timer_init0(void); -void timer_tim5_init(void); +void timer_tim4_init(void); TIM_HandleTypeDef *timer_tim6_init(uint freq); void timer_deinit(void); uint32_t timer_get_source_freq(uint32_t tim_id); From 346825c8a94e2735858f7a0ff8219b9f35d729f4 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 09:44:38 +0100 Subject: [PATCH 21/45] stm32/stm32_it: Call omv GPIO IRQ handlers. Signed-off-by: iabdalkader --- ports/stm32/extint.c | 5 +++++ ports/stm32/stm32_it.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index 9b658dca968..1f9970f8a45 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -248,10 +248,13 @@ static const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { #endif }; +extern void omv_gpio_irq_handler(uint32_t); + #define DEFINE_EXTI_IRQ_HANDLER(line) \ void EXTI##line##_IRQHandler(void) { \ MP_STATIC_ASSERT(EXTI##line##_IRQn > 0); \ IRQ_ENTER(EXTI##line##_IRQn); \ + omv_gpio_irq_handler(line); \ Handle_EXTI_Irq(line); \ IRQ_EXIT(EXTI##line##_IRQn); \ } @@ -294,6 +297,7 @@ DEFINE_EXTI_IRQ_HANDLER(4) void EXTI9_5_IRQHandler(void) { MP_STATIC_ASSERT(EXTI9_5_IRQn > 0); IRQ_ENTER(EXTI9_5_IRQn); + omv_gpio_irq_handler(5); Handle_EXTI_Irq(5); Handle_EXTI_Irq(6); Handle_EXTI_Irq(7); @@ -305,6 +309,7 @@ void EXTI9_5_IRQHandler(void) { void EXTI15_10_IRQHandler(void) { MP_STATIC_ASSERT(EXTI15_10_IRQn > 0); IRQ_ENTER(EXTI15_10_IRQn); + omv_gpio_irq_handler(10); Handle_EXTI_Irq(10); Handle_EXTI_Irq(11); Handle_EXTI_Irq(12); diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 7d5f4792dba..897daaa15ab 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -88,6 +88,7 @@ #include "usb.h" #endif +extern void omv_gpio_irq_handler(uint32_t line); #if defined(MICROPY_HW_USB_FS) extern PCD_HandleTypeDef pcd_fs_handle; #endif @@ -581,6 +582,7 @@ void RTC_WKUP_IRQHandler(void) RTC->ISR &= ~RTC_ISR_WUTF; // clear wakeup interrupt flag #endif Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); // Clear the EXTI's line Flag for RTC WakeUpTimer IRQ_EXIT(RTC_WKUP_IRQn); } #endif From 448668c10e613e3b7399a6df696371cac8cb132f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 10:33:29 +0100 Subject: [PATCH 22/45] stm32/powerctrl: Clear pending EXTI flags. --- ports/stm32/powerctrl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index a63c57f4a78..f6fd4756ec5 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -848,6 +848,11 @@ void powerctrl_enter_stop_mode(void) { } #endif + #if defined(STM32H7) + // Clear any pending EXTIs. + EXTI_D1->PR1 = 0x3fffff; __ISB(); __DSB(); + #endif + #if defined(STM32WB) powerctrl_low_power_prep_wb55(); #endif @@ -1178,7 +1183,8 @@ MP_NORETURN void powerctrl_enter_standby_mode(void) { EXTI_D2->PR1 = 0x3fffffu; EXTI_D2->IMR1 &= ~(0xFFFFu); // 16 lines #endif - // Clear all wake-up flags. + // Disable all wakeup pins and clear flags. + PWR->WKUPEPR &= ~(0x1Fu); PWR->WKUPCR |= PWR_WAKEUP_FLAG_ALL; #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) // clear all wake-up flags From 0af9316b7de3bcf4938066d9b4dcebadaa226afb Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 10:58:18 +0100 Subject: [PATCH 23/45] stm32/usb: Make MSC bot data relocatable. --- ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h | 2 +- ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h index 34f04125341..b91b8bb22b5 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -77,7 +77,7 @@ typedef struct { uint8_t bot_state; uint8_t bot_status; uint16_t bot_data_length; - uint8_t bot_data[MSC_MEDIA_PACKET]; + uint8_t *bot_data; USBD_MSC_BOT_CBWTypeDef cbw; USBD_MSC_BOT_CSWTypeDef csw; diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index e541c321343..0e65f2fc0a7 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -741,6 +741,9 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_EP_TYPE_BULK, mp); + extern uint8_t _msc_buf; + usbd->MSC_BOT_ClassData.bot_data = &_msc_buf; + // Init the BOT layer MSC_BOT_Init(pdev); } From db98cce98a35895c8ee68222ad4851359c8a2aed Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 13:46:52 +0100 Subject: [PATCH 24/45] stm32/irq.h: Update IRQs config. --- ports/stm32/irq.h | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/ports/stm32/irq.h b/ports/stm32/irq.h index 3348175420c..a9f1d8af579 100644 --- a/ports/stm32/irq.h +++ b/ports/stm32/irq.h @@ -152,31 +152,46 @@ static inline void restore_irq_pri(uint32_t state) { // get dropped. The handling for each character only consumes about 0.5 usec #define IRQ_PRI_UART NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0) +// DCMI Priority +#define IRQ_PRI_DCMI NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 2, 0) + +// DCMI DMA2_Stream1 +#define IRQ_PRI_DMA21 NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 3, 0) + // SDIO must be higher priority than DMA for SDIO DMA transfers to work. #define IRQ_PRI_SDIO NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 4, 0) -// SPI must be higher priority than DMA for SPI DMA transfers to work. -#define IRQ_PRI_SPI NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 4, 0) - // DMA should be higher priority than USB, since USB Mass Storage calls // into the sdcard driver which waits for the DMA to complete. #define IRQ_PRI_DMA NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 5, 0) +#define IRQ_PRI_MDMA NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) + +#define IRQ_PRI_GPU NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) + // Flash IRQ (used for flushing storage cache) must be at the same priority as // the USB IRQs, so that the IRQ priority can be raised to this level to disable // both the USB and cache flushing, when storage transfers are in progress. -#define IRQ_PRI_FLASH NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) +#define IRQ_PRI_FLASH NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) -#define IRQ_PRI_OTG_FS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) -#define IRQ_PRI_OTG_HS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) -#define IRQ_PRI_TIM5 NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0) +#define IRQ_PRI_OTG_FS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) +#define IRQ_PRI_OTG_HS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) +#define IRQ_PRI_TIM4 NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) -#define IRQ_PRI_CAN NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0) +#define IRQ_PRI_CAN NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 8, 0) -#define IRQ_PRI_SUBGHZ_RADIO NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 8, 0) +#define IRQ_PRI_SUBGHZ_RADIO NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 9, 0) + +#define IRQ_PRI_SPI NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 9, 0) + +#define IRQ_PRI_LTDC NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 10, 0) + +#define IRQ_PRI_DSI NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 10, 0) #define IRQ_PRI_HSEM NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 10, 0) +#define IRQ_PRI_JPEG NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 10, 0) + #define IRQ_PRI_I2C NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 12, 0) // Interrupt priority for non-special timers. From d3ea9d8ce31a6bfc1cf1e46ba02476dd42b269ad Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 13:54:03 +0100 Subject: [PATCH 25/45] stm32/led: Invert LED 4. --- ports/stm32/led.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ports/stm32/led.c b/ports/stm32/led.c index 2fcb2abb60d..771519c1cba 100644 --- a/ports/stm32/led.c +++ b/ports/stm32/led.c @@ -75,7 +75,12 @@ void led_init(void) { for (int led = 0; led < NUM_LEDS; led++) { const machine_pin_obj_t *led_pin = pyb_led_obj[led].led_pin; mp_hal_gpio_clock_enable(led_pin->gpio); - MICROPY_HW_LED_OFF(led_pin); + if (led == 3) { + //IR is inverted + MICROPY_HW_LED_ON(led_pin); + } else { + MICROPY_HW_LED_OFF(led_pin); + } mp_hal_pin_output(led_pin); } } @@ -214,10 +219,18 @@ void led_state(pyb_led_t led, int state) { const machine_pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin; if (state == 0) { // turn LED off - MICROPY_HW_LED_OFF(led_pin); + if (led == 4) { + MICROPY_HW_LED_ON(led_pin); + } else { + MICROPY_HW_LED_OFF(led_pin); + } } else { // turn LED on - MICROPY_HW_LED_ON(led_pin); + if (led == 4) { + MICROPY_HW_LED_OFF(led_pin); + } else { + MICROPY_HW_LED_ON(led_pin); + } } #if LED_PWM_ENABLED From aabf8c79e4d5d50d64bdecf3ac3d983fa25e9738 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:06:42 +0100 Subject: [PATCH 26/45] stm32/dac: Flush DAC buffer before writing. --- ports/stm32/dac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index eb729a6d4eb..d82b240d3d8 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -198,6 +198,10 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui #endif } + #ifdef __DCACHE_PRESENT + MP_HAL_CLEAN_DCACHE(buf, len); + #endif + dma_nohal_deinit(dma_descr); dma_nohal_init(dma_descr, DMA_MEMORY_TO_PERIPH | dma_mode | dma_align); dma_nohal_start(dma_descr, (uint32_t)buf, base + dac_align, len); From 964055295255223e35b1cc67296ecd5f8b240707 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:09:39 +0100 Subject: [PATCH 27/45] stm32/sdio: Use temporary DMA buffer when needed. --- ports/stm32/sdio.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index de82ceadc5f..9c18ae4213d 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -25,6 +25,7 @@ */ #include +#include #include "py/mperrno.h" #include "py/mphal.h" @@ -33,6 +34,7 @@ #include "pin_static_af.h" #include "pendsv.h" #include "sdio.h" +#include "dma.h" #if MICROPY_PY_NETWORK_CYW43 @@ -52,6 +54,9 @@ static volatile uint32_t sdmmc_error; static volatile uint8_t *sdmmc_buf_cur; static volatile uint8_t *sdmmc_buf_top; +// NOTE SDMMC1 and SDMMC2 both have access to D1 AXI memory. +static uint8_t DMA_BUFFER[4*1024] __attribute__((aligned(32), section(".d1_dma_buffer"))); + // 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. @@ -355,7 +360,7 @@ int sdio_transfer(uint32_t cmd, uint32_t arg, uint32_t *resp) { return 0; } -int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t len, uint8_t *buf) { +int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t len, uint8_t *buf_in) { #if defined(STM32F7) // Wait for any outstanding TX to complete while (SDMMC->STA & SDMMC_STA_TXACT) { @@ -383,7 +388,19 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le return -MP_EINVAL; } - bool dma = (len > 16); + uint8_t *buf = buf_in; + bool dma = (len > 16) && SD_DMA_BUFFER(SDMMC, buf); + bool dma_buf_used = false; + + // For read transfers bigger than FIFO size with a non-DMA buffer provided, we use + // a temporary DMA buffer instead to force a DMA transfer, to avoid FIFO overruns. + if (dma == false && len > 16 && len <= sizeof(DMA_BUFFER)) { + dma = dma_buf_used = true; + if (write) { + memcpy(DMA_BUFFER, buf_in, len); + } + buf = DMA_BUFFER; // overwrite dest buffer with DMA_BUFFER. + } SDMMC->ICR = SDMMC_STATIC_FLAGS; // clear interrupts SDMMC->MASK &= SDMMC_MASK_SDIOITIE; @@ -478,7 +495,7 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le if (sdmmc_irq_state == SDMMC_IRQ_STATE_DONE) { break; } - if (mp_hal_ticks_ms() - start > 200) { + if (mp_hal_ticks_ms() - start > 1000) { 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)SDMMC->STA, (uint)SDMMC->DCOUNT, (uint)SDMMC->FIFOCNT, (uint)DMA2->LISR, (uint)DMA2->HISR, (uint)DMA2_Stream3->NDTR, (uint)RCC->AHB1ENR); @@ -521,6 +538,10 @@ int sdio_transfer_cmd53(bool write, uint32_t block_size, uint32_t arg, size_t le #endif } + if (dma_buf_used && write == 0) { + // If DMA buffer was used, copy back to user buffer. + memcpy(buf_in, DMA_BUFFER, len); + } return 0; } From 8d79e75bf21ea9077868b0bd8ea709fc5beace2a Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:23:34 +0100 Subject: [PATCH 28/45] stm32/sdcard: Misc fixes. - Enable flow control. - Reset SDCARD on init. - Disable temporary DMA buffers. --- ports/stm32/sdcard.c | 68 ++++++++------------------------------------ 1 file changed, 12 insertions(+), 56 deletions(-) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index b91fa3a9c28..481b467cefa 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -266,7 +266,10 @@ bool sdcard_is_present(void) { } #if MICROPY_HW_ENABLE_SDCARD +static void sdcard_reset_periph(); static HAL_StatusTypeDef sdmmc_init_sd(void) { + sdcard_reset_periph(); + // SD device interface configuration sdmmc_handle.sd.Instance = SDIO; sdmmc_handle.sd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; @@ -275,7 +278,7 @@ static HAL_StatusTypeDef sdmmc_init_sd(void) { #endif sdmmc_handle.sd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_ENABLE; sdmmc_handle.sd.Init.BusWide = SDIO_BUS_WIDE_1B; - sdmmc_handle.sd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; + sdmmc_handle.sd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; sdmmc_handle.sd.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; // init the SD interface, with retry if it's not ready yet @@ -463,7 +466,6 @@ static HAL_StatusTypeDef sdcard_wait_finished(void) { break; } } - __WFI(); enable_irq(irq_state); if (HAL_GetTick() - start >= TIMEOUT_MS) { return HAL_TIMEOUT; @@ -495,7 +497,6 @@ static HAL_StatusTypeDef sdcard_wait_finished(void) { if (HAL_GetTick() - start >= TIMEOUT_MS) { return HAL_TIMEOUT; } - __WFI(); } return HAL_OK; } @@ -522,28 +523,10 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo return err; } - // check that dest pointer is aligned on a 4-byte boundary - uint8_t *orig_dest = NULL; - uint32_t saved_word; - if (((uint32_t)dest & 3) != 0) { - // Pointer is not aligned so it needs fixing. - // We could allocate a temporary block of RAM (as sdcard_write_blocks - // does) but instead we are going to use the dest buffer inplace. We - // are going to align the pointer, save the initial word at the aligned - // location, read into the aligned memory, move the memory back to the - // unaligned location, then restore the initial bytes at the aligned - // location. We should have no trouble doing this as those initial - // bytes at the aligned location should be able to be changed for the - // duration of this function call. - orig_dest = dest; - dest = (uint8_t *)((uint32_t)dest & ~3); - saved_word = *(uint32_t *)dest; - } - - if (query_irq() == IRQ_STATE_ENABLED) { - // we must disable USB irqs to prevent MSC contention with SD card - uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + // we must disable USB irqs to prevent MSC contention with SD card + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + if (query_irq() == IRQ_STATE_ENABLED && SD_DMA_BUFFER(SDIO, dest)) { #if SDIO_USE_GPDMA DMA_HandleTypeDef sd_dma; dma_init(&sd_dma, &SDMMC_DMA, DMA_PERIPH_TO_MEMORY, &sdmmc_handle); @@ -585,8 +568,6 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo sdmmc_handle.sd.hdmarx = NULL; } #endif - - restore_irq_pri(basepri); } else { #if MICROPY_HW_ENABLE_MMCARD if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_MMC) { @@ -600,13 +581,7 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo err = sdcard_wait_finished(); } } - - if (orig_dest != NULL) { - // move the read data to the non-aligned position, and restore the initial bytes - memmove(orig_dest, dest, num_blocks * SDCARD_BLOCK_SIZE); - memcpy(dest, &saved_word, orig_dest - dest); - } - + restore_irq_pri(basepri); return err; } @@ -616,28 +591,10 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n return err; } - // check that src pointer is aligned on a 4-byte boundary - if (((uint32_t)src & 3) != 0) { - // pointer is not aligned, so allocate a temporary block to do the write - uint8_t *src_aligned = m_new_maybe(uint8_t, SDCARD_BLOCK_SIZE); - if (src_aligned == NULL) { - return HAL_ERROR; - } - for (size_t i = 0; i < num_blocks; ++i) { - memcpy(src_aligned, src + i * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE); - err = sdcard_write_blocks(src_aligned, block_num + i, 1); - if (err != HAL_OK) { - break; - } - } - m_del(uint8_t, src_aligned, SDCARD_BLOCK_SIZE); - return err; - } - - if (query_irq() == IRQ_STATE_ENABLED) { - // we must disable USB irqs to prevent MSC contention with SD card - uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + // we must disable USB irqs to prevent MSC contention with SD card + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + if (query_irq() == IRQ_STATE_ENABLED && SD_DMA_BUFFER(SDIO, src)) { #if SDIO_USE_GPDMA DMA_HandleTypeDef sd_dma; dma_init(&sd_dma, &SDMMC_DMA, DMA_MEMORY_TO_PERIPH, &sdmmc_handle); @@ -678,8 +635,6 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n sdmmc_handle.sd.hdmatx = NULL; } #endif - - restore_irq_pri(basepri); } else { #if MICROPY_HW_ENABLE_MMCARD if (pyb_sdmmc_flags & PYB_SDMMC_FLAG_MMC) { @@ -693,6 +648,7 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n err = sdcard_wait_finished(); } } + restore_irq_pri(basepri); return err; } From dda0d213e2ece338eb03221abcd4133707a5bafa Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:22:01 +0100 Subject: [PATCH 29/45] stm32/dma: Add DMA_BUFFER macro. --- ports/stm32/dma.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index ee62a2e2056..62fb20a77cd 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -162,6 +162,30 @@ extern const dma_descr_t dma_SPI_5_TX; #endif +#if defined(STM32F7) +// NOTE: F7 CCM memory is accessible by GP-DMA. +#define DMA_BUFFER(p) (((uint32_t)p & 3) == 0) +#elif defined(STM32F4) +// NOTE: F4 CCM memory is not accessible by GP-DMA. +#define DMA_BUFFER(p) ((((uint32_t)p & 3) == 0) && ((uint32_t) p > 0x10010000)) +#elif defined(STM32H7) +#define DMA_BUFFER(p) ((((uint32_t)p & 3) == 0) && ((uint32_t) p > 0x20020000)) +#elif defined(STM32N6) +#define DMA_BUFFER(p) (((uint32_t)p & 3) == 0) +#else +#error Unsupported processor +#endif + +#if !defined(STM32H7) +#define SD_DMA_BUFFER(sd, p) DMA_BUFFER(p) +#else +// NOTE: H7 SDMMC1 DMA can only access D1 memory/devices, +// and SDMMC2 DMA can access D1, D2 and D3 memory/devices. +#define IS_D1_ADDR(p) ((((uint32_t) p >= 0x60000000) && ((uint32_t) p < 0xD0000000)) || \ + (((uint32_t) p >= 0x24000000) && ((uint32_t) p < 0x24080000))) +#define SD_DMA_BUFFER(sd, p) ((sd == SDMMC1) ? (DMA_BUFFER(p) && IS_D1_ADDR(p)) : DMA_BUFFER(p)) +#endif + // API that configures the DMA via the HAL. void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir, void *data); void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir, void *data); From 1d9b1f27a7e99cb7d4024145b112f8ad00720543 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 10 Aug 2025 16:45:17 +0200 Subject: [PATCH 30/45] stm32/stm32_it: Fix RTC macro. Signed-off-by: iabdalkader --- ports/stm32/stm32_it.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 897daaa15ab..0da3dcc90ce 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -582,7 +582,9 @@ void RTC_WKUP_IRQHandler(void) RTC->ISR &= ~RTC_ISR_WUTF; // clear wakeup interrupt flag #endif Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback + #ifdef __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); // Clear the EXTI's line Flag for RTC WakeUpTimer + #endif IRQ_EXIT(RTC_WKUP_IRQn); } #endif From 130043d58ea15bbbe6d04aebb9b8dfa4590d572d Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:30:11 +0100 Subject: [PATCH 31/45] stm32/dma: Export DMA handles. --- ports/stm32/dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index 346b6b6f70f..ec500b5e392 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -205,7 +205,7 @@ static const DMA_InitTypeDef dma_init_struct_dac = { }; #else // Default parameters to dma_init() for DAC tx -static const DMA_InitTypeDef dma_init_struct_dac = { +DMA_InitTypeDef dma_init_struct_dac = { #if defined(STM32F4) || defined(STM32F7) .Channel = 0, #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) @@ -916,7 +916,7 @@ static const uint8_t dma_irqn[NSTREAM] = { }; #endif -static DMA_HandleTypeDef *dma_handle[NSTREAM] = {NULL}; +DMA_HandleTypeDef *dma_handle[NSTREAM] = {NULL}; static uint8_t dma_last_sub_instance[NSTREAM]; static volatile uint32_t dma_enable_mask = 0; #if MICROPY_HW_DMA_ENABLE_AUTO_TURN_OFF @@ -1630,6 +1630,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir void dma_deinit(const dma_descr_t *dma_descr) { if (dma_descr != NULL) { + HAL_DMA_Abort(dma_handle[dma_descr->id]); #if !defined(STM32F0) HAL_NVIC_DisableIRQ(dma_irqn[dma_descr->id]); #endif From 04f3b107b0c7a20f0501567cedc11d69dab0a3c3 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:26:20 +0100 Subject: [PATCH 32/45] stm32/i2c: Ensure buffer is DMA-compatible before transfer. --- ports/stm32/pyb_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index dc907c638d5..73d8f6ec9cd 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -843,7 +843,7 @@ static mp_obj_t pyb_i2c_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t * pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data); // if option is set and IRQs are enabled then we can use DMA - bool use_dma = *self->use_dma && query_irq() == IRQ_STATE_ENABLED; + bool use_dma = (*self->use_dma && query_irq() == IRQ_STATE_ENABLED && DMA_BUFFER(bufinfo.buf)); DMA_HandleTypeDef tx_dma; if (use_dma) { @@ -1019,7 +1019,7 @@ static mp_obj_t pyb_i2c_mem_read(size_t n_args, const mp_obj_t *pos_args, mp_map } // if option is set and IRQs are enabled then we can use DMA - bool use_dma = *self->use_dma && query_irq() == IRQ_STATE_ENABLED; + bool use_dma = (*self->use_dma && query_irq() == IRQ_STATE_ENABLED && DMA_BUFFER(vstr.buf)); HAL_StatusTypeDef status; if (!use_dma) { From d0b7d155a76acba2a5ec4c1945403def8713c250 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:33:24 +0100 Subject: [PATCH 33/45] stm32/i2c: Fix I2C timings. --- ports/stm32/pyb_i2c.c | 54 +++++-------------------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 73d8f6ec9cd..3fe5706d7dc 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -197,10 +197,10 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = { // I2C TIMINGs obtained from the STHAL examples. #define MICROPY_HW_I2C_BAUDRATE_TIMING { \ - {PYB_I2C_SPEED_STANDARD, 0x40604E73}, \ - {PYB_I2C_SPEED_FULL, 0x00901954}, \ - {PYB_I2C_SPEED_FAST, 0x10810915}, \ -} + {PYB_I2C_SPEED_STANDARD, 0xE0701F28}, \ + {PYB_I2C_SPEED_FULL, 0x40900C22}, \ + {PYB_I2C_SPEED_FAST, 0x4030040B}, \ + } #define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL) #define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST) @@ -449,7 +449,7 @@ void pyb_i2c_deinit_all(void) { static void i2c_reset_after_error(I2C_HandleTypeDef *i2c) { // wait for bus-busy flag to be cleared, with a timeout - for (int timeout = 50; timeout > 0; --timeout) { + for (int timeout = 10; timeout > 0; --timeout) { if (!__HAL_I2C_GET_FLAG(i2c, I2C_FLAG_BUSY)) { // stop bit was generated and bus is back to normal return; @@ -489,50 +489,8 @@ void i2c_ev_irq_handler(mp_uint_t i2c_id) { return; } - #if defined(STM32F4) - - if (hi2c->Instance->SR1 & I2C_FLAG_SB) { - if (hi2c->State == HAL_I2C_STATE_BUSY_TX) { - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); - } else { - hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); - } - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - } else if (hi2c->Instance->SR1 & I2C_FLAG_ADDR) { - __IO uint32_t tmp_sr2; - if (hi2c->State == HAL_I2C_STATE_BUSY_RX) { - if (hi2c->XferCount == 1U) { - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - } else { - if (hi2c->XferCount == 2U) { - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - hi2c->Instance->CR1 |= I2C_CR1_POS; - } - hi2c->Instance->CR2 |= I2C_CR2_LAST; - } - } - tmp_sr2 = hi2c->Instance->SR2; - UNUSED(tmp_sr2); - } else if (hi2c->Instance->SR1 & I2C_FLAG_BTF && hi2c->State == HAL_I2C_STATE_BUSY_TX) { - if (hi2c->XferCount != 0U) { - hi2c->Instance->DR = *hi2c->pBuffPtr++; - hi2c->XferCount--; - } else { - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - if (hi2c->XferOptions != I2C_FIRST_FRAME) { - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - hi2c->Mode = HAL_I2C_MODE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - } - } - - #else - - // if not an F4 MCU, use the HAL's IRQ handler + // Use the HAL's IRQ handler HAL_I2C_EV_IRQHandler(hi2c); - - #endif } void i2c_er_irq_handler(mp_uint_t i2c_id) { From 63537fc573c8d7e352725f6060db56afdf6d153f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:29:22 +0100 Subject: [PATCH 34/45] stm32/spi: Ensure buffer is DMA-compatible before transfer. --- ports/stm32/spi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 330e4d47425..c9c9a6f4ef9 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -614,7 +614,7 @@ void spi_transfer(const spi_t *self, size_t len, const uint8_t *src, uint8_t *de if (dest == NULL) { // send only - if (len == 1 || query_irq() == IRQ_STATE_DISABLED) { + if (len == 1 || query_irq() == IRQ_STATE_DISABLED || !DMA_BUFFER(src)) { status = HAL_SPI_Transmit(self->spi, (uint8_t *)src, len, timeout); } else { DMA_HandleTypeDef tx_dma; @@ -640,7 +640,7 @@ void spi_transfer(const spi_t *self, size_t len, const uint8_t *src, uint8_t *de } } else if (src == NULL) { // receive only - if (len == 1 || query_irq() == IRQ_STATE_DISABLED) { + if (len == 1 || query_irq() == IRQ_STATE_DISABLED || !DMA_BUFFER(dest)) { status = HAL_SPI_Receive(self->spi, dest, len, timeout); } else { DMA_HandleTypeDef tx_dma, rx_dma; @@ -676,7 +676,7 @@ void spi_transfer(const spi_t *self, size_t len, const uint8_t *src, uint8_t *de } } else { // send and receive - if (len == 1 || query_irq() == IRQ_STATE_DISABLED) { + if (len == 1 || query_irq() == IRQ_STATE_DISABLED || !DMA_BUFFER(src) || !DMA_BUFFER(dest)) { status = HAL_SPI_TransmitReceive(self->spi, (uint8_t *)src, dest, len, timeout); } else { DMA_HandleTypeDef tx_dma, rx_dma; From 973243bd20d55bcc552826f148c2e47d906e4af0 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:31:24 +0100 Subject: [PATCH 35/45] stm32/spi: Export SPI handles. --- ports/stm32/spi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index c9c9a6f4ef9..6ec1f52560a 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -46,22 +46,22 @@ // SPI6_RX: DMA2_Stream6.CHANNEL_1 #if defined(MICROPY_HW_SPI1_SCK) -static SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SPI2_SCK) -static SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SPI3_SCK) -static SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SPI4_SCK) -static SPI_HandleTypeDef SPIHandle4 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle4 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SPI5_SCK) -static SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle5 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SPI6_SCK) -static SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL}; +SPI_HandleTypeDef SPIHandle6 = {.Instance = NULL}; #endif #if defined(MICROPY_HW_SUBGHZSPI_ID) static SPI_HandleTypeDef SPIHandleSubGhz = {.Instance = NULL}; From 0b5db700ed86b7ea26bffef1efa1c7242437ab90 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:31:57 +0100 Subject: [PATCH 36/45] stm32/spi: Deinit SPI DMA handles in spi_deinit. --- ports/stm32/spi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 6ec1f52560a..ea46b6513a1 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -510,6 +510,12 @@ int spi_init(const spi_t *self, bool enable_nss_pin) { } void spi_deinit(const spi_t *spi_obj) { + if (spi_obj->rx_dma_descr != NULL) { + dma_deinit(spi_obj->rx_dma_descr); + } + if (spi_obj->tx_dma_descr != NULL) { + dma_deinit(spi_obj->tx_dma_descr); + } SPI_HandleTypeDef *spi = spi_obj->spi; HAL_SPI_DeInit(spi); if (0) { From 3301c41d3657e1badcdb058640bf2acc823bfbc3 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 30 Nov 2024 14:32:36 +0100 Subject: [PATCH 37/45] stm32/spi: Disable WFI for H7. - See DM00257543 2.2.5 --- ports/stm32/spi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index ea46b6513a1..7b88155c2f8 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -598,7 +598,14 @@ static HAL_StatusTypeDef spi_wait_dma_finished(const spi_t *spi, uint32_t t_star enable_irq(irq_state); return HAL_OK; } + // See DM00257543 2.2.5 + // The DTCM-RAM is not accessible in read during Sleep mode (when the CPU clock is + // gated). When a read access to the DTCM-RAM is performed by an AHB bus master + // (that are the DMAs) while the CPU is in sleep mode (CPU clock is gated), the + // data is not transmitted to the AHB bus and the AHB master reads 0x0000_0000. + #if !defined(STM32F7) __WFI(); + #endif enable_irq(irq_state); if (HAL_GetTick() - t_start >= timeout) { return HAL_TIMEOUT; From c373becef807127cd320d2339a17ec149152a070 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 13 Apr 2025 08:55:23 +0200 Subject: [PATCH 38/45] alif: Fix CMSIS header. --- ports/alif/alif.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/alif/alif.mk b/ports/alif/alif.mk index d9e7c32578c..93cab3fdf5a 100644 --- a/ports/alif/alif.mk +++ b/ports/alif/alif.mk @@ -75,7 +75,7 @@ CFLAGS += $(INC) \ --specs=nosys.specs \ -D$(MCU_CORE)=1 \ -DCORE_$(MCU_CORE) \ - -DALIF_CMSIS_H="\"$(MCU_CORE).h\"" + -DALIF_CMSIS_H='' ifeq ($(MICROPY_FLOAT_IMPL),float) CFLAGS += -fsingle-precision-constant From 6a3453cc51769d68cb065e6375a3df9293c2bd15 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 20 May 2025 15:32:42 +0300 Subject: [PATCH 39/45] alif/boards/OPENMV_AE3: Update ROMFS size. --- ports/alif/boards/OPENMV_AE3/board.ld.S | 4 ++-- ports/alif/boards/OPENMV_AE3/mpconfigboard.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/alif/boards/OPENMV_AE3/board.ld.S b/ports/alif/boards/OPENMV_AE3/board.ld.S index 0d09bb15f87..539e24b1de2 100644 --- a/ports/alif/boards/OPENMV_AE3/board.ld.S +++ b/ports/alif/boards/OPENMV_AE3/board.ld.S @@ -3,8 +3,8 @@ /* Define ROMFS partition locations. */ #if CORE_M55_HP /* The HP core has access to the external OSPI flash and MRAM ROMFS partitions. */ -_micropy_hw_romfs_part0_start = 0xa1000000; -_micropy_hw_romfs_part0_size = 16M; +_micropy_hw_romfs_part0_start = 0xa0800000; +_micropy_hw_romfs_part0_size = 24M; _micropy_hw_romfs_part1_start = ORIGIN(MRAM_FS); _micropy_hw_romfs_part1_size = LENGTH(MRAM_FS); #else diff --git a/ports/alif/boards/OPENMV_AE3/mpconfigboard.h b/ports/alif/boards/OPENMV_AE3/mpconfigboard.h index 0495bc81c8a..a4981ce167e 100644 --- a/ports/alif/boards/OPENMV_AE3/mpconfigboard.h +++ b/ports/alif/boards/OPENMV_AE3/mpconfigboard.h @@ -67,8 +67,8 @@ extern void board_exit_standby(void); // This is used for alif.Flash() and USB MSC. #define MICROPY_HW_FLASH_STORAGE_BASE_ADDR (0) #define MICROPY_HW_FLASH_STORAGE_BYTES (32 * 1024 * 1024) -#define MICROPY_HW_FLASH_STORAGE_FS_BYTES (16 * 1024 * 1024) -#define MICROPY_HW_FLASH_STORAGE_ROMFS_BYTES (16 * 1024 * 1024) +#define MICROPY_HW_FLASH_STORAGE_FS_BYTES (8 * 1024 * 1024) +#define MICROPY_HW_FLASH_STORAGE_ROMFS_BYTES (24 * 1024 * 1024) // Murata 1YN configuration #define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "lib/cyw43-driver/firmware/w43439_sdio_1yn_7_95_59_combined.h" From 4635a001b781d15cc0fae425314574a21b68bdf2 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 20 Dec 2025 13:30:49 +0100 Subject: [PATCH 40/45] qemu: OpenMV build patch. Signed-off-by: iabdalkader --- ports/qemu/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/qemu/Makefile b/ports/qemu/Makefile index ba9c53841ae..31b225f60fe 100644 --- a/ports/qemu/Makefile +++ b/ports/qemu/Makefile @@ -239,7 +239,7 @@ SRC_QSTR += $(SRC_C) $(LIBM_SRC_C) ################################################################################ # Main targets -all: $(BUILD)/firmware.elf +all: $(OBJ) .PHONY: repl repl: $(BUILD)/firmware.elf From bbe328745ad70c54a19d35e7cde841120f79f387 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 Dec 2025 14:39:06 +1100 Subject: [PATCH 41/45] stm32/main: Enable all AHB5 GRP1 clocks in low power mode. The main functional change here is to make sure that the SDMMC1/2 clocks are enabled in low power mode; they were not previously enabled for SD card use, only WLAN. It doesn't hurt to unconditionally enable the clocks in low power, like all the other peripherals. Signed-off-by: Damien George --- ports/stm32/eth.c | 5 ----- ports/stm32/main.c | 2 +- ports/stm32/sdio.c | 4 ---- ports/stm32/usbd_conf.c | 2 -- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/ports/stm32/eth.c b/ports/stm32/eth.c index 60f2a23deca..7baaa89c627 100644 --- a/ports/stm32/eth.c +++ b/ports/stm32/eth.c @@ -370,11 +370,6 @@ static int eth_mac_init(eth_t *self) { __HAL_RCC_ETH1RX_CLK_SLEEP_ENABLE(); #elif defined(STM32N6) __HAL_RCC_ETH1_RELEASE_RESET(); - - __HAL_RCC_ETH1_CLK_SLEEP_ENABLE(); - __HAL_RCC_ETH1MAC_CLK_SLEEP_ENABLE(); - __HAL_RCC_ETH1TX_CLK_SLEEP_ENABLE(); - __HAL_RCC_ETH1RX_CLK_SLEEP_ENABLE(); #else __HAL_RCC_ETHMAC_RELEASE_RESET(); diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 8085a5e2576..6ae8061c413 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -409,13 +409,13 @@ void stm32_main(uint32_t reset_mode) { LL_MEM_EnableClockLowPower(LL_MEM_AXISRAM1 | LL_MEM_AXISRAM2 | LL_MEM_AXISRAM3 | LL_MEM_AXISRAM4 | LL_MEM_AXISRAM5 | LL_MEM_AXISRAM6 | LL_MEM_AHBSRAM1 | LL_MEM_AHBSRAM2 | LL_MEM_BKPSRAM | LL_MEM_FLEXRAM | LL_MEM_CACHEAXIRAM | LL_MEM_VENCRAM | LL_MEM_BOOTROM); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_XSPI2 | LL_AHB5_GRP1_PERIPH_XSPIM); LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_RTC | LL_APB4_GRP1_PERIPH_RTCAPB); LL_APB4_GRP1_EnableClockLowPower(LL_APB4_GRP1_PERIPH_RTC | LL_APB4_GRP1_PERIPH_RTCAPB); // Enable some AHB peripherals during sleep. LL_AHB1_GRP1_EnableClockLowPower(LL_AHB1_GRP1_PERIPH_ALL); // GPDMA1, ADC12 LL_AHB4_GRP1_EnableClockLowPower(LL_AHB4_GRP1_PERIPH_ALL); // GPIOA-Q, PWR, CRC + LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_ALL); // DMA2D, ETH, FMC, GFXMMU, GPU2D, HPDMA, XSPI, JPEG, MCE, CACHEAXI, NPU, OTG, PSSI, SDMMC // Enable some APB peripherals during sleep. LL_APB1_GRP1_EnableClockLowPower(LL_APB1_GRP1_PERIPH_ALL); // I2C, I3C, LPTIM, SPI, TIM, UART, WWDG diff --git a/ports/stm32/sdio.c b/ports/stm32/sdio.c index 9c18ae4213d..e1751619702 100644 --- a/ports/stm32/sdio.c +++ b/ports/stm32/sdio.c @@ -136,10 +136,6 @@ void sdio_init(uint32_t irq_pri) { mp_hal_pin_config_alt_static(MICROPY_HW_SDIO_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, STATIC_AF_SDMMC_CMD); SDMMC_CLK_ENABLE(); // enable SDIO peripheral - #if defined(STM32N6) - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_SDMMC1); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_SDMMC2); - #endif SDMMC_TypeDef *SDIO = SDMMC; #if defined(STM32F7) diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index 46d7985253d..d481aec1e49 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -279,8 +279,6 @@ static void mp_usbd_ll_init_hs(void) { LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTG1); LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTGPHY1); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTG1); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTGPHY1); // Select 24MHz clock. MODIFY_REG(USB1_HS_PHYC->USBPHYC_CR, USB_USBPHYC_CR_FSEL, 2 << USB_USBPHYC_CR_FSEL_Pos); From e091aa6208d2c3c49d46ce3c54804ae96a06ba47 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 17 Dec 2025 14:40:24 +1100 Subject: [PATCH 42/45] stm32/sdcard: Use high speed mode for SD transfers on H5/H7/N6. This doubles the speed of SD card transfers. Signed-off-by: Damien George --- ports/stm32/sdcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c index 481b467cefa..db055bd702c 100644 --- a/ports/stm32/sdcard.c +++ b/ports/stm32/sdcard.c @@ -105,7 +105,7 @@ #define SDIO_HARDWARE_FLOW_CONTROL_ENABLE SDMMC_HARDWARE_FLOW_CONTROL_ENABLE #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) -#define SDIO_TRANSFER_CLK_DIV SDMMC_NSpeed_CLK_DIV +#define SDIO_TRANSFER_CLK_DIV SDMMC_HSPEED_CLK_DIV #define SDIO_USE_GPDMA 0 #else #define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV From 366b6bd242fa068e4ee03a5c516e8cfa7d10c374 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sat, 27 Dec 2025 22:49:27 -0800 Subject: [PATCH 43/45] alif/boards/OPENMV_AE3: Make JTAG pins controllable as GPIOs. Allows user control of JTAG pins on the AE3 which are exposed via the B2B header. Signed-off-by: Kwabena W. Agyeman --- ports/alif/boards/OPENMV_AE3/pins.csv | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/alif/boards/OPENMV_AE3/pins.csv b/ports/alif/boards/OPENMV_AE3/pins.csv index 360b27af813..9ebd3b726bd 100644 --- a/ports/alif/boards/OPENMV_AE3/pins.csv +++ b/ports/alif/boards/OPENMV_AE3/pins.csv @@ -55,6 +55,10 @@ P6,P7_2 P7,P7_3 P8,P1_2 P9,P1_3 +P10,P4_4 +P11,P4_7 +P13,P4_5 +P14,P4_6 # UART buses UART1_TX,P0_5 From e2310e678d373b03dad4b67e43196da802edc035 Mon Sep 17 00:00:00 2001 From: Praful Mathur Date: Wed, 25 Mar 2026 21:48:21 -0700 Subject: [PATCH 44/45] Updated cyw43-driver to include fixes upstream for Client -> AP fixes Signed-off-by: Praful Mathur --- lib/cyw43-driver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cyw43-driver b/lib/cyw43-driver index dd7568229f3..055d64274b0 160000 --- a/lib/cyw43-driver +++ b/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit dd7568229f3bf7a37737b9e1ef250c26efe75b23 +Subproject commit 055d64274b014dd7b1c2fc94d26e8a18face7124 From b65c6780de02ee50e6b0e20d78898b29d22b0c5b Mon Sep 17 00:00:00 2001 From: Praful Mathur Date: Wed, 10 Jun 2026 18:23:33 -0700 Subject: [PATCH 45/45] mimxrt/lwip: size lwIP heap for video streaming Default 8KB lwIP heap holds only ~5 in-flight 1.4KB UDP pbufs, so fragmenting a ~40KB JPEG frame into ~30 RTP packets fails with ENOMEM mid-frame, and the MJPEG TCP socket cannot queue a whole frame. Raise MEM_SIZE to 128KB, TCP_MSS to 1460, TCP_SND_BUF to 32*MSS, and relocate the heap+memp pools into a dedicated .lwip section (OMV_LWIP_MEMORY) so DTCM is not exhausted. Signed-off-by: Praful Mathur --- ports/mimxrt/lwip_inc/lwipopts.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ports/mimxrt/lwip_inc/lwipopts.h b/ports/mimxrt/lwip_inc/lwipopts.h index cf25597f95c..2edf5cd4bd8 100644 --- a/ports/mimxrt/lwip_inc/lwipopts.h +++ b/ports/mimxrt/lwip_inc/lwipopts.h @@ -7,6 +7,28 @@ #define LWIP_RAND() trng_random_u32() +// Larger lwIP memory configuration for video streaming (MJPEG over TCP + +// RTP/JPEG over UDP). The 8KB common default holds only ~5 in-flight 1.4KB +// UDP pbufs, so fragmenting a ~40KB JPEG frame into ~30 RTP packets fails +// with ENOMEM mid-frame. RT1062 has ample RAM; use the high-throughput +// profile from lwipopts_common.h with a heap sized for one full frame burst. +// MEM_SIZE must hold a full JPEG frame queued on the MJPEG TCP socket +// (TCP_SND_BUF) plus a full ~30-packet RTP/UDP frame burst concurrently. +#define MEM_SIZE (128 * 1024) +#define TCP_MSS (1460) +#define TCP_WND (8 * TCP_MSS) +// One whole ~41KB MJPEG frame must fit in the send buffer: the asyncio event +// loop is blocked ~86ms per JPEG encode, so every extra TCP drain cycle costs +// a full encode period and divides the delivered MJPEG frame rate. +#define TCP_SND_BUF (32 * TCP_MSS) +#define MEMP_NUM_TCP_SEG (64) + +// Relocate the lwIP heap and memp pools out of DTCM (which has no headroom +// for the larger MEM_SIZE above) into the dedicated .lwip section placed in +// DRAM by the board linker config (OMV_LWIP_MEMORY). +#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) \ + __attribute__((section(".lwip"), aligned(MEM_ALIGNMENT))) u8_t variable_name[size] + // Include common lwIP configuration. #include "extmod/lwip-include/lwipopts_common.h"