From 2fc2c63a438b1511cb48cdbda4d7b116ba2d1c57 Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Mon, 31 Mar 2025 16:36:13 +0000 Subject: [PATCH 001/208] add-sensebox-eye-esp32s3 --- .../sensebox_mcu_esp32s2/mpconfigboard.h | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h index 9213a260ab86e..565e99d1c3973 100644 --- a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h @@ -7,26 +7,3 @@ #pragma once // Micropython setup - -#define MICROPY_HW_BOARD_NAME "senseBox MCU-S2 ESP32S2" -#define MICROPY_HW_MCU_NAME "ESP32S2" - -#define MICROPY_HW_NEOPIXEL (&pin_GPIO1) - -#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP 1 - -#define CIRCUITPY_BOARD_I2C (2) -#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO40, .sda = &pin_GPIO39}, \ - {.scl = &pin_GPIO42, .sda = &pin_GPIO45}} -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) - -#define DEFAULT_UART_BUS_RX (&pin_GPIO44) -#define DEFAULT_UART_BUS_TX (&pin_GPIO43) - -#define CIRCUITPY_BOARD_SPI (1) -#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO36, .mosi = &pin_GPIO35, .miso = &pin_GPIO37}} - -#define CIRCUITPY_BOARD_UART (1) -#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO43, .rx = &pin_GPIO44}} From 796ff375d5bfbe097c881c00425c8642b836257f Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Mon, 31 Mar 2025 16:39:22 +0000 Subject: [PATCH 002/208] add-sensebox-eye-esp32s3 --- .../boards/sensebox_eye_esp32s3/board.c | 9 +++ .../sensebox_eye_esp32s3/mpconfigboard.h | 18 +++++ .../sensebox_eye_esp32s3/mpconfigboard.mk | 21 ++++++ .../boards/sensebox_eye_esp32s3/pins.c | 74 +++++++++++++++++++ .../boards/sensebox_eye_esp32s3/sdkconfig | 19 +++++ 5 files changed, 141 insertions(+) create mode 100644 ports/espressif/boards/sensebox_eye_esp32s3/board.c create mode 100644 ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h create mode 100644 ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk create mode 100644 ports/espressif/boards/sensebox_eye_esp32s3/pins.c create mode 100644 ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/board.c b/ports/espressif/boards/sensebox_eye_esp32s3/board.c new file mode 100644 index 0000000000000..fea7fe2c3002e --- /dev/null +++ b/ports/espressif/boards/sensebox_eye_esp32s3/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h new file mode 100644 index 0000000000000..6f340abf66f9c --- /dev/null +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "senseBox-eye ESP32S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO14) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk new file mode 100644 index 0000000000000..8bfcda99a153b --- /dev/null +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk @@ -0,0 +1,21 @@ +USB_VID = 0x303A +USB_PID = 0x82D2 + +USB_PRODUCT = "senseBox-eye ESP32S3" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_ESPCAMERA = 1 +CIRCUITPY_AUDIOBUSIO = 1 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/pins.c b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c new file mode 100644 index 0000000000000..1788f8f1152ea --- /dev/null +++ b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c @@ -0,0 +1,74 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sscb_i2c, i2c, 2) + +static const mp_rom_obj_tuple_t camera_data_tuple = { + // The order matters. + // They must be ordered from low to high (CAM_D0, CAM_D1...CAM_D7). + + // Do not include any of the control pins in here. + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO11), + MP_ROM_PTR(&pin_GPIO9), + MP_ROM_PTR(&pin_GPIO8), + MP_ROM_PTR(&pin_GPIO10), + MP_ROM_PTR(&pin_GPIO12), + MP_ROM_PTR(&pin_GPIO18), + MP_ROM_PTR(&pin_GPIO17), + MP_ROM_PTR(&pin_GPIO16), + } +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D3), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D7), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCLK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_POWER), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig b/ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig new file mode 100644 index 0000000000000..919f4d9f345ff --- /dev/null +++ b/ports/espressif/boards/sensebox_eye_esp32s3/sdkconfig @@ -0,0 +1,19 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP +# Camera configuration +# +CONFIG_OV2640_SUPPORT=y +# CONFIG_OV7725_SUPPORT is not set +# CONFIG_OV3660_SUPPORT is not set +# end of Camera configuration +# end of Component config + +# end of Espressif IoT Development Framework Configuration From 4a66244810fb625acec56c5f7aa21354aa95af6f Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Mon, 31 Mar 2025 16:42:58 +0000 Subject: [PATCH 003/208] Revert "add-sensebox-eye-esp32s3" This reverts commit 2fc2c63a438b1511cb48cdbda4d7b116ba2d1c57. --- .../sensebox_mcu_esp32s2/mpconfigboard.h | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h index 565e99d1c3973..9213a260ab86e 100644 --- a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.h @@ -7,3 +7,26 @@ #pragma once // Micropython setup + +#define MICROPY_HW_BOARD_NAME "senseBox MCU-S2 ESP32S2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO1) + +#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP 1 + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO40, .sda = &pin_GPIO39}, \ + {.scl = &pin_GPIO42, .sda = &pin_GPIO45}} +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO36, .mosi = &pin_GPIO35, .miso = &pin_GPIO37}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO43, .rx = &pin_GPIO44}} From 8348b8b3b29733fe88c6114fc0c5a47c7df18ac9 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Mon, 7 Apr 2025 14:52:22 -0700 Subject: [PATCH 004/208] Added board definitions --- .../board.c | 9 ++++ .../mpconfigboard.h | 27 ++++++++++ .../mpconfigboard.mk | 31 +++++++++++ .../pins.c | 53 +++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c create mode 100644 ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c new file mode 100644 index 0000000000000..b44a1ae51e04b --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h new file mode 100644 index 0000000000000..0188cd9b519ae --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h @@ -0,0 +1,27 @@ + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython Nano" +#define MICROPY_HW_MCU_NAME "same51j20" +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PB22) +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define EXTERNAL_FLASH_QSPI_DUAL + +#define BOARD_HAS_CRYSTAL 1 + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB31) +#define DEFAULT_I2C_BUS_SDA (&pin_PB30) + +#define DEFAULT_SPI_BUS_SCK (&pin_PBA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA18) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk new file mode 100644 index 0000000000000..fcda6bf4b77a7 --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -0,0 +1,31 @@ +USB_VID = 0x04D8 +USB_PID = 0xE52B +USB_PRODUCT = "Microchip Curiosity CircuitPython Nano" +USB_MANUFACTURER = "Microchip Technology Inc" + +CHIP_VARIANT = SAME51J20A +CHIP_FAMILY = same51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ,SST26VF032B" +LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_BITMAPFILTER = 0 +CIRCUITPY_CANIO = 1 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_GIFIO = 0 +CIRCUITPY_JPEGIO = 0 + +CIRCUITPY_LTO_PARTITION = one + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c new file mode 100644 index 0000000000000..c6a9dd9c416af --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -0,0 +1,53 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_CAN_STDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, + { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 0f9462f35cbbad14d602a9fcae7ead20e8db51c2 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:11:34 -0700 Subject: [PATCH 005/208] Updated mpconfig.mk to use SST26VF016B. --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index fcda6bf4b77a7..666cec8ede16b 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -7,7 +7,7 @@ CHIP_VARIANT = SAME51J20A CHIP_FAMILY = same51 QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ,SST26VF032B" +EXTERNAL_FLASH_DEVICES = "SST26VF016B" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 From b2a11f0d851512508de9adf0c9e2f281c8404525 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:34:14 -0700 Subject: [PATCH 006/208] Updated pins.c to contain objects for I2C, SPI, UART, CAN --- .../pins.c | 96 +++++++++++-------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c index c6a9dd9c416af..aae64a8a2f86a 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -9,45 +9,61 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, - { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, - { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_CAN_STDBY), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, - { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, - { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, - { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, - { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, - { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, - { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, - { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, + + { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, + + { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 15b1d5f276fd30f8bcd5b3725dc53799c36e8caf Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:38:00 -0700 Subject: [PATCH 007/208] Changes to mpconfigboard.h and pins.c --- mpconfigboard.h | 37 ++++++++++++++++++++++++++ pins.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 mpconfigboard.h create mode 100644 pins.c diff --git a/mpconfigboard.h b/mpconfigboard.h new file mode 100644 index 0000000000000..673a584585148 --- /dev/null +++ b/mpconfigboard.h @@ -0,0 +1,37 @@ + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython Nano" +#define MICROPY_HW_MCU_NAME "same51j20" +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PB23) +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define EXTERNAL_FLASH_QSPI_DUAL + +#define BOARD_HAS_CRYSTAL 1 + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB31) +#define DEFAULT_I2C_BUS_SDA (&pin_PB30) + +#define LCD_SPI_BUS_SCK (&pin_PA05) +#define LCD_SPI_BUS_MOSI (&pin_PA04) +#define LCD_SPI_BUS_CS (&pin_PA07) +#define LCD_BACKLIGHT (&pin_PA06) + +#define SDCARD_SPI_BUS_SCK (&pin_PA17) +#define SDCARD_SPI_BUS_MOSI (&pin_PA16) +#define SDCARD_SPI_BUS_MISO (&pin_PA18) +#define SDCARD_SPI_BUS_CS (&pin_PA19) + +#define DEFAULT_CAN_BUS_TX (&pin_PB12) +#define DEFAULT_CAN_BUS_RX (&pin_PB13) +#define DEFAULT_CAN_BUS_STDBY (&pin_PB17) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) diff --git a/pins.c b/pins.c new file mode 100644 index 0000000000000..73cd7c64f18df --- /dev/null +++ b/pins.c @@ -0,0 +1,71 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, + + { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, + + { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 4b72af42624dc50b56ecd836015483940ef3f9b1 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 12:17:43 -0700 Subject: [PATCH 008/208] Delete pins.c --- pins.c | 71 ---------------------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 pins.c diff --git a/pins.c b/pins.c deleted file mode 100644 index 73cd7c64f18df..0000000000000 --- a/pins.c +++ /dev/null @@ -1,71 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries -// -// SPDX-License-Identifier: MIT - -#include "shared-bindings/board/__init__.h" - -static const mp_rom_map_elem_t board_module_globals_table[] = { - CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, - - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, - - { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, - - { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, - - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, - - { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, - - { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, - - { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, - - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, - - { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, - { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, - - { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, - { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, - { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, - - { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, - - { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, - { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, - - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, -}; -MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From c4285e8472f44b7f1bff796b65efd9200a2522db Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 12:17:59 -0700 Subject: [PATCH 009/208] Delete mpconfigboard.h --- mpconfigboard.h | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 mpconfigboard.h diff --git a/mpconfigboard.h b/mpconfigboard.h deleted file mode 100644 index 673a584585148..0000000000000 --- a/mpconfigboard.h +++ /dev/null @@ -1,37 +0,0 @@ - -#pragma once - -#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython Nano" -#define MICROPY_HW_MCU_NAME "same51j20" -#define CIRCUITPY_MCU_FAMILY samd51 - -#define MICROPY_HW_LED_STATUS (&pin_PB23) -#define MICROPY_HW_NEOPIXEL (&pin_PB22) - -#define EXTERNAL_FLASH_QSPI_DUAL - -#define BOARD_HAS_CRYSTAL 1 - -// USB is always used internally so skip the pin objects for it. -#define IGNORE_PIN_PA24 1 -#define IGNORE_PIN_PA25 1 - -#define DEFAULT_I2C_BUS_SCL (&pin_PB31) -#define DEFAULT_I2C_BUS_SDA (&pin_PB30) - -#define LCD_SPI_BUS_SCK (&pin_PA05) -#define LCD_SPI_BUS_MOSI (&pin_PA04) -#define LCD_SPI_BUS_CS (&pin_PA07) -#define LCD_BACKLIGHT (&pin_PA06) - -#define SDCARD_SPI_BUS_SCK (&pin_PA17) -#define SDCARD_SPI_BUS_MOSI (&pin_PA16) -#define SDCARD_SPI_BUS_MISO (&pin_PA18) -#define SDCARD_SPI_BUS_CS (&pin_PA19) - -#define DEFAULT_CAN_BUS_TX (&pin_PB12) -#define DEFAULT_CAN_BUS_RX (&pin_PB13) -#define DEFAULT_CAN_BUS_STDBY (&pin_PB17) - -#define DEFAULT_UART_BUS_RX (&pin_PA23) -#define DEFAULT_UART_BUS_TX (&pin_PA22) From 6742579e46d8ef7061baf31a41536f6df5a57a3e Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 12:19:21 -0700 Subject: [PATCH 010/208] Updated mpconfig.h and pins.c --- .../mpconfigboard.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h index 0188cd9b519ae..673a584585148 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h @@ -5,7 +5,7 @@ #define MICROPY_HW_MCU_NAME "same51j20" #define CIRCUITPY_MCU_FAMILY samd51 -#define MICROPY_HW_LED_STATUS (&pin_PB22) +#define MICROPY_HW_LED_STATUS (&pin_PB23) #define MICROPY_HW_NEOPIXEL (&pin_PB22) #define EXTERNAL_FLASH_QSPI_DUAL @@ -19,9 +19,19 @@ #define DEFAULT_I2C_BUS_SCL (&pin_PB31) #define DEFAULT_I2C_BUS_SDA (&pin_PB30) -#define DEFAULT_SPI_BUS_SCK (&pin_PBA17) -#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) -#define DEFAULT_SPI_BUS_MISO (&pin_PA18) +#define LCD_SPI_BUS_SCK (&pin_PA05) +#define LCD_SPI_BUS_MOSI (&pin_PA04) +#define LCD_SPI_BUS_CS (&pin_PA07) +#define LCD_BACKLIGHT (&pin_PA06) + +#define SDCARD_SPI_BUS_SCK (&pin_PA17) +#define SDCARD_SPI_BUS_MOSI (&pin_PA16) +#define SDCARD_SPI_BUS_MISO (&pin_PA18) +#define SDCARD_SPI_BUS_CS (&pin_PA19) + +#define DEFAULT_CAN_BUS_TX (&pin_PB12) +#define DEFAULT_CAN_BUS_RX (&pin_PB13) +#define DEFAULT_CAN_BUS_STDBY (&pin_PB17) #define DEFAULT_UART_BUS_RX (&pin_PA23) #define DEFAULT_UART_BUS_TX (&pin_PA22) From 0a5ce8d453d480d7fcfcc9800616a1bb38df9785 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 12:22:27 -0700 Subject: [PATCH 011/208] Switched to SST26VF064B flash --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index 666cec8ede16b..c6fbb75fe802b 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -6,9 +6,11 @@ USB_MANUFACTURER = "Microchip Technology Inc" CHIP_VARIANT = SAME51J20A CHIP_FAMILY = same51 -QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "SST26VF016B" +# QSPI_FLASH_FILESYSTEM = 1 +INTERNAL_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "SST26VF064B" LONGINT_IMPL = MPZ +CIRCUITPY_ULAB = 0 CIRCUITPY__EVE = 1 CIRCUITPY_BITMAPFILTER = 0 From 92aa962bdf53cdfe1737c8730ce3283d99074f7a Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 13:19:36 -0700 Subject: [PATCH 012/208] Added support for flash chips Microchip Quad SPI flash: SST26VF016B, SST26VF016B,SST26VF016B, SST26VF064B --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index c6fbb75fe802b..1a39d6ac11a4e 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -8,7 +8,7 @@ CHIP_FAMILY = same51 # QSPI_FLASH_FILESYSTEM = 1 INTERNAL_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "SST26VF064B" +EXTERNAL_FLASH_DEVICES = "SST26VF016B,SST26VF032B,SST26VF064B" LONGINT_IMPL = MPZ CIRCUITPY_ULAB = 0 From 6558a85eb9fe8b64f9c7d5e53db9dad06ed312a9 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:08:13 -0700 Subject: [PATCH 013/208] Removed dual QSPI for flash chips --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h index 673a584585148..71cd8829f665e 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h @@ -8,8 +8,6 @@ #define MICROPY_HW_LED_STATUS (&pin_PB23) #define MICROPY_HW_NEOPIXEL (&pin_PB22) -#define EXTERNAL_FLASH_QSPI_DUAL - #define BOARD_HAS_CRYSTAL 1 // USB is always used internally so skip the pin objects for it. From a9c9aa5c360870e9e4a6373196dd82b3c0a5f295 Mon Sep 17 00:00:00 2001 From: ross-satchell <59891338+ross-satchell@users.noreply.github.com> Date: Mon, 28 Apr 2025 15:38:56 -0700 Subject: [PATCH 014/208] Updated pins.c to add SD card CS pin and obj for lcd sd --- .../boards/microchip_curiosity_circuitpython_nano/pins.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c index aae64a8a2f86a..ef8a44f0874d9 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -19,6 +19,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, @@ -49,6 +51,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA19) }, { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, @@ -62,8 +65,14 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SDSPI), MP_ROM_PTR(&board_sdspi_obj) }, + { MP_ROM_QSTR(MP_QSTR_LCDSPI), MP_ROM_PTR(&board_lcdspi_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 992d50a455689aa949f4b5fcc38e29d56c6030de Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 28 Apr 2025 20:53:08 -0400 Subject: [PATCH 015/208] Fix up available SPI buses; swap I2C pins --- .../mpconfigboard.h | 22 +++++++------- .../pins.c | 30 ++++++++++++------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h index 71cd8829f665e..31559f318ada7 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h @@ -14,18 +14,16 @@ #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 -#define DEFAULT_I2C_BUS_SCL (&pin_PB31) -#define DEFAULT_I2C_BUS_SDA (&pin_PB30) - -#define LCD_SPI_BUS_SCK (&pin_PA05) -#define LCD_SPI_BUS_MOSI (&pin_PA04) -#define LCD_SPI_BUS_CS (&pin_PA07) -#define LCD_BACKLIGHT (&pin_PA06) - -#define SDCARD_SPI_BUS_SCK (&pin_PA17) -#define SDCARD_SPI_BUS_MOSI (&pin_PA16) -#define SDCARD_SPI_BUS_MISO (&pin_PA18) -#define SDCARD_SPI_BUS_CS (&pin_PA19) +#define DEFAULT_I2C_BUS_SCL (&pin_PB30) +#define DEFAULT_I2C_BUS_SDA (&pin_PB31) + +#define CIRCUITPY_BOARD_SPI (3) +// These correspond to the CIRCUITPY_BOARD_BUS_SINGLETON definitions in pins.c +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_PB03, .mosi = &pin_PB02, .miso = &pin_PB00}, /*board.SPI()*/ \ + {.clock = &pin_PA05, .mosi = &pin_PA04, .miso = NULL}, /*board.LCD_SPI()*/ \ + {.clock = &pin_PA17, .mosi = &pin_PA16, .miso = &pin_PA18}, /*board.SD_SPI()*/ \ +} #define DEFAULT_CAN_BUS_TX (&pin_PB12) #define DEFAULT_CAN_BUS_RX (&pin_PB13) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c index ef8a44f0874d9..93e96cb2b1120 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -6,6 +6,12 @@ #include "shared-bindings/board/__init__.h" +// The singleton for board.SPI() is already defined. +// board.LCD_SPI() +CIRCUITPY_BOARD_BUS_SINGLETON(lcd_spi, spi, 1) +// board.SD_SPI() +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 2) + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS @@ -19,7 +25,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, - + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, @@ -41,8 +47,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB31) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB31) }, { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, @@ -53,9 +59,16 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB00) }, { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, + + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, + + { MP_ROM_QSTR(MP_QSTR_SCK ), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, @@ -65,14 +78,11 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - { MP_ROM_QSTR(MP_QSTR_SDSPI), MP_ROM_PTR(&board_sdspi_obj) }, - { MP_ROM_QSTR(MP_QSTR_LCDSPI), MP_ROM_PTR(&board_lcdspi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_lcd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From a4af1be162842300e627b7f078ea88a195b86c96 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 28 Apr 2025 20:55:33 -0400 Subject: [PATCH 016/208] fix pre-commit formatting complaint --- .../boards/microchip_curiosity_circuitpython_nano/pins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c index 93e96cb2b1120..b4184e3cecd30 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -68,7 +68,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_SCK ), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, From 1ab8176e1dcfb8eccead10927b65f914a237bfa2 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 27 May 2025 17:04:03 +0200 Subject: [PATCH 017/208] mpconfig: Use RUN_BACKGROUND_TASKS as the micropython event hook This is a newer abstraction in micropython; it'll for instance allow background tasks to be checked once per ms in the internal select module modselect. Because `MICROPY_INTERNAL_EVENT_HOOK` is used in a few locations, our own CIRCUITPY-CHANGE call to `RUN_BACKGROUND_TASKS` can be nixed. Specifically, `mp_event_handle_nowait` calls `MICROPY_INTERNAL_EVENT_HOOK` so paths from it don't need `RUN_BACKGROUND_TASKS` anymore. --- py/circuitpy_mpconfig.h | 1 + py/scheduler.c | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index d6658867b7d1d..73d6d682e8c5b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -452,6 +452,7 @@ void background_callback_run_all(void); #define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS; #define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS; +#define MICROPY_INTERNAL_EVENT_HOOK (RUN_BACKGROUND_TASKS) // CIRCUITPY_AUTORELOAD_DELAY_MS = 0 will completely disable autoreload. #ifndef CIRCUITPY_AUTORELOAD_DELAY_MS diff --git a/py/scheduler.c b/py/scheduler.c index 91ef7e63b38f1..99952d28aca61 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -271,10 +271,6 @@ void mp_event_wait_indefinite(void) { MICROPY_EVENT_POLL_HOOK #else mp_event_handle_nowait(); - - // CIRCUITPY-CHANGE: don't starve CircuitPython background tasks - RUN_BACKGROUND_TASKS; - MICROPY_INTERNAL_WFE(-1); #endif } @@ -287,10 +283,6 @@ void mp_event_wait_ms(mp_uint_t timeout_ms) { MICROPY_EVENT_POLL_HOOK #else mp_event_handle_nowait(); - - // CIRCUITPY-CHANGE: don't starve CircuitPython background tasks - RUN_BACKGROUND_TASKS; - MICROPY_INTERNAL_WFE(timeout_ms); #endif } From 96636cfd85c1c710d868e8b63d056303fe5e7abf Mon Sep 17 00:00:00 2001 From: eightycc Date: Wed, 4 Jun 2025 13:24:04 -0700 Subject: [PATCH 018/208] Fix typo in https address of cortex toolchain. --- .devcontainer/cortex-m-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/cortex-m-toolchain.sh b/.devcontainer/cortex-m-toolchain.sh index 782b472fec2e2..38ecdb72a7b96 100755 --- a/.devcontainer/cortex-m-toolchain.sh +++ b/.devcontainer/cortex-m-toolchain.sh @@ -14,7 +14,7 @@ echo -e "[cortex-m-toolchain.sh] downloading and installing gcc-arm-non-eabi too cd /workspaces wget -qO gcc-arm-none-eabi.tar.xz \ - https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz + https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz tar -xJf gcc-arm-none-eabi.tar.xz ln -s arm-gnu-toolchain-14.2.Rel1-x86_64-arm-none-eabi gcc-arm-none-eabi From 313f826e0cebf4bcaa03bf90b21d2bb6d20d4ffb Mon Sep 17 00:00:00 2001 From: eightycc Date: Wed, 4 Jun 2025 13:25:22 -0700 Subject: [PATCH 019/208] atmel-samd: Release SERCOM with I2C deinit. --- ports/atmel-samd/common-hal/busio/I2C.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index e13b5410ae32a..da108709feaff 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -135,6 +135,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return; } + allow_reset_sercom(self->i2c_desc.device.hw); i2c_m_sync_disable(&self->i2c_desc); i2c_m_sync_deinit(&self->i2c_desc); From d78a9c7ba0b481c5d10ff6ce70874876560900a3 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 17 Jun 2025 17:24:03 -0400 Subject: [PATCH 020/208] curiosity: switch back to external flash filesystem --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index 1a39d6ac11a4e..408c4eca9fd60 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -6,8 +6,7 @@ USB_MANUFACTURER = "Microchip Technology Inc" CHIP_VARIANT = SAME51J20A CHIP_FAMILY = same51 -# QSPI_FLASH_FILESYSTEM = 1 -INTERNAL_FLASH_FILESYSTEM = 1 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "SST26VF016B,SST26VF032B,SST26VF064B" LONGINT_IMPL = MPZ CIRCUITPY_ULAB = 0 From b16d18e5d0fc7eee0e1ae38c2be44ca2d3055511 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 25 Jul 2025 18:27:01 -0400 Subject: [PATCH 021/208] espressif/common-hal/alarm/PinAlarm.c: return correct wakeup pin for ESP32 --- ports/espressif/common-hal/alarm/pin/PinAlarm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index 45f676fa5993f..8e3e46785f2e7 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -108,7 +108,17 @@ mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { #ifdef SOC_PM_SUPPORT_EXT0_WAKEUP if (cause == ESP_SLEEP_WAKEUP_EXT0) { - pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL); + int rtc_io_pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL); + // Look up the GPIO equivalent pin for this RTC GPIO pin. On ESP32, the numbering + // is different for RTC_GPIO and regular GPIO, and there's no mapping table. + // The RTC and GPIO pin numbers match for all other current chips, so we could skip this + // for those chips, but it's not expensive, and maybe there will be another mismatch in the future. + for (gpio_num_t gpio_num = 0; gpio_num < SOC_GPIO_PIN_COUNT; gpio_num++) { + if (rtc_io_number_get(gpio_num) == rtc_io_pin_number) { + pin_number = gpio_num; + break; + } + } } else { #endif #ifdef SOC_PM_SUPPORT_EXT1_WAKEUP From 2e183f4c00afcd280dd406cf22a72c6cd32d4e67 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 23 Jul 2025 15:50:53 -0700 Subject: [PATCH 022/208] Add support for quad color epaper highlight_color2 is now available for pixel value 0b11. Black is 0b00, white is 0b01 and highlight_color is 0b10. Also add support for multibit values written with one command when color_command isn't provided. --- shared-bindings/epaperdisplay/EPaperDisplay.c | 8 +++- shared-bindings/epaperdisplay/EPaperDisplay.h | 2 +- shared-module/displayio/ColorConverter.c | 41 ++++++++++++++----- shared-module/displayio/ColorConverter.h | 3 +- shared-module/displayio/Palette.h | 3 +- shared-module/displayio/__init__.c | 1 + shared-module/epaperdisplay/EPaperDisplay.c | 17 ++++++-- 7 files changed, 56 insertions(+), 19 deletions(-) diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.c b/shared-bindings/epaperdisplay/EPaperDisplay.c index 5d72df815d0a7..9f261d599ada9 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.c +++ b/shared-bindings/epaperdisplay/EPaperDisplay.c @@ -54,6 +54,7 @@ //| write_color_ram_command: Optional[int] = None, //| color_bits_inverted: bool = False, //| highlight_color: int = 0x000000, +//| highlight_color2: int = 0x000000, //| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer], //| refresh_time: float = 40, //| busy_pin: Optional[microcontroller.Pin] = None, @@ -97,6 +98,7 @@ //| :param int write_color_ram_command: Command used to write pixels values into the update region //| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color. //| :param int highlight_color: RGB888 of source color to highlight with third ePaper color. +//| :param int highlight_color2: RGB888 of source color to highlight with fourth ePaper color. //| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence //| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided. //| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy @@ -117,7 +119,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command, ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted, - ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, + ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_highlight_color2, ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state, ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, ARG_spectra6, ARG_two_byte_sequence_length, ARG_start_up_time, ARG_address_little_endian }; @@ -141,6 +143,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, { MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, + { MP_QSTR_highlight_color2, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, { MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} }, { MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, @@ -181,6 +184,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, mp_int_t write_color_ram_command = NO_COMMAND; mp_int_t highlight_color = args[ARG_highlight_color].u_int; + mp_int_t highlight_color2 = args[ARG_highlight_color2].u_int; if (args[ARG_write_color_ram_command].u_obj != mp_const_none) { write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj); } @@ -216,7 +220,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int, args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int, args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, - args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time, + args[ARG_color_bits_inverted].u_bool, highlight_color, highlight_color2, refresh_buf, refresh_buf_len, refresh_time, busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, args[ARG_spectra6].u_bool, two_byte_sequence_length, args[ARG_address_little_endian].u_bool diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.h b/shared-bindings/epaperdisplay/EPaperDisplay.h index 016a07f1490c5..afa90a514e2a5 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.h +++ b/shared-bindings/epaperdisplay/EPaperDisplay.h @@ -23,7 +23,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla uint16_t set_column_window_command, uint16_t set_row_window_command, uint16_t set_current_column_command, uint16_t set_current_row_command, uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, + uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2, const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index ae7d3f02d5127..d4e64ee286eb8 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -163,8 +163,13 @@ uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) { } } -void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) { - +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) { + if (pixel_chroma <= 16) { + if (!colorspace->grayscale) { + *color = 0; + } + return; + } int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) { if (colorspace->grayscale) { @@ -177,6 +182,21 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *co } } +void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) { + *color >>= 1; + if (pixel_chroma <= 16) { + return; + } + int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; + if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) { + *color = 2; + } + int16_t hue_diff2 = colorspace->fourcolor_hue - pixel_hue; + if ((-10 <= hue_diff2 && hue_diff2 <= 10) || hue_diff2 <= -220 || hue_diff2 >= 220) { + *color = 3; + } +} + void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color) { displayio_input_pixel_t input_pixel; input_pixel.pixel = input_color; @@ -313,18 +333,17 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit output_color->pixel = packed; output_color->opaque = true; return; - } else if (colorspace->tricolor) { + } else if (colorspace->tricolor || colorspace->fourcolor) { uint8_t luma = displayio_colorconverter_compute_luma(pixel); + uint8_t pixel_chroma = displayio_colorconverter_compute_chroma(pixel); output_color->pixel = luma >> (8 - colorspace->depth); - if (displayio_colorconverter_compute_chroma(pixel) <= 16) { - if (!colorspace->grayscale) { - output_color->pixel = 0; - } - output_color->opaque = true; - return; - } uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel); - displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, &output_color->pixel); + if (colorspace->tricolor) { + displayio_colorconverter_compute_tricolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel); + } else if (colorspace->fourcolor) { + displayio_colorconverter_compute_fourcolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel); + } + output_color->opaque = true; return; } else if (colorspace->grayscale && colorspace->depth <= 8) { uint8_t luma = displayio_colorconverter_compute_luma(pixel); diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h index d3dbedfe160ab..304004d566a95 100644 --- a/shared-module/displayio/ColorConverter.h +++ b/shared-module/displayio/ColorConverter.h @@ -43,4 +43,5 @@ uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888); -void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color); +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color); +void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color); diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index bb87a93d98133..24ae5c4b7a525 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -15,10 +15,11 @@ typedef struct { uint8_t depth; uint8_t bytes_per_cell; uint8_t tricolor_hue; - uint8_t tricolor_luma; + uint8_t fourcolor_hue; uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth. bool grayscale; bool tricolor; + bool fourcolor; bool sixcolor; // Spectra6 e-ink screens. bool sevencolor; // Acep e-ink screens. bool pixels_in_byte_share_row; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 4b467b75589d1..f3444241b3cca 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -198,6 +198,7 @@ void reset_displays(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { + display_buses[i].bus_base.type = &mp_type_NoneType; continue; #if CIRCUITPY_FOURWIRE } else if (display_bus_type == &fourwire_fourwire_type) { diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index a5a303d82ae75..e1f0a07f467ee 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -33,7 +33,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla uint16_t set_column_window_command, uint16_t set_row_window_command, uint16_t set_current_column_command, uint16_t set_current_row_command, uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, + uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2, const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, bool address_little_endian) { @@ -42,10 +42,16 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla if (highlight_color != 0x000000) { self->core.colorspace.tricolor = true; self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); - self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); } else { self->core.colorspace.tricolor = false; } + if (highlight_color != 0x000000 && highlight_color2 != 0x000000) { + self->core.colorspace.tricolor = false; + self->core.colorspace.fourcolor = true; + self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(highlight_color2); + } else { + self->core.colorspace.fourcolor = false; + } self->acep = acep || spectra6; self->core.colorspace.sixcolor = spectra6; self->core.colorspace.sevencolor = acep; @@ -54,6 +60,11 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla grayscale = false; core_grayscale = false; } + if ((highlight_color != 0x000000 || highlight_color2 != 0x000000) && write_color_ram_command == NO_COMMAND) { + color_depth = 2; + core_grayscale = false; + grayscale = false; + } displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true); displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height, @@ -90,7 +101,7 @@ void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdispla } // Clear the color memory if it isn't in use. - if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) { + if (highlight_color == 0x00 && highlight_color2 == 0x00 && write_color_ram_command != NO_COMMAND) { // TODO: Clear } From 69534be70910879209ce462ed0cddc6a709ce602 Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Tue, 29 Jul 2025 13:59:56 +0000 Subject: [PATCH 023/208] update pins --- .../boards/sensebox_eye_esp32s3/mpconfigboard.h | 2 +- .../sensebox_eye_esp32s3/mpconfigboard.mk | 3 --- .../boards/sensebox_eye_esp32s3/pins.c | 17 ++++++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h index 6f340abf66f9c..3908c492f1b01 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.h @@ -9,7 +9,7 @@ #define MICROPY_HW_BOARD_NAME "senseBox-eye ESP32S3" #define MICROPY_HW_MCU_NAME "ESP32S3" -#define MICROPY_HW_NEOPIXEL (&pin_GPIO14) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO45) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk index 8bfcda99a153b..9f43ff6f392d4 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk @@ -16,6 +16,3 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m CIRCUITPY_ESPCAMERA = 1 CIRCUITPY_AUDIOBUSIO = 1 - -# Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/pins.c b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c index 1788f8f1152ea..3d5b9f76763f7 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/pins.c +++ b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c @@ -33,17 +33,23 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + {MP_ROM_QSTR(MP_QSTR_BUTTON_SW), MP_ROM_PTR(&pin_GPIO47) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART_ENABLE), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO11) }, @@ -60,12 +66,13 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_PWDN), MP_ROM_PTR(&pin_GPIO46) }, - { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_SD_SCLK), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_SD_POWER), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_SD_ENABLE), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, From 7ea1ecf681b134f5227f1283262f8f15a8399201 Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Tue, 29 Jul 2025 14:09:42 +0000 Subject: [PATCH 024/208] include neopixel library --- ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk | 3 +++ ports/espressif/boards/sensebox_eye_esp32s3/pins.c | 1 + 2 files changed, 4 insertions(+) diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk index 9f43ff6f392d4..485c07f524dbc 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk @@ -16,3 +16,6 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m CIRCUITPY_ESPCAMERA = 1 CIRCUITPY_AUDIOBUSIO = 1 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel \ No newline at end of file diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/pins.c b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c index 3d5b9f76763f7..c218fafa918ce 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/pins.c +++ b/ports/espressif/boards/sensebox_eye_esp32s3/pins.c @@ -46,6 +46,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO48) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, From 704f4d3bcbabbe288487c9cce29509a60b4b94ea Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Tue, 29 Jul 2025 14:34:40 +0000 Subject: [PATCH 025/208] run pre-commit --- ports/espressif/README.rst | 2 +- ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/espressif/README.rst b/ports/espressif/README.rst index 63174fd167067..5630d4668b563 100644 --- a/ports/espressif/README.rst +++ b/ports/espressif/README.rst @@ -222,4 +222,4 @@ And follow the Espressif GDB tutorial `instructions for connecting Date: Tue, 29 Jul 2025 14:37:25 +0000 Subject: [PATCH 026/208] fix end of file --- ports/espressif/README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/espressif/README.rst b/ports/espressif/README.rst index 5630d4668b563..fe5542aafe46f 100644 --- a/ports/espressif/README.rst +++ b/ports/espressif/README.rst @@ -222,4 +222,3 @@ And follow the Espressif GDB tutorial `instructions for connecting Date: Tue, 29 Jul 2025 13:48:19 -0700 Subject: [PATCH 027/208] Fix other boards by adding new param --- ports/atmel-samd/boards/openbook_m4/board.c | 1 + ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c | 2 ++ ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c | 1 + ports/espressif/boards/heltec_vision_master_e290/board.c | 1 + ports/espressif/boards/heltec_wireless_paper/board.c | 1 + ports/espressif/boards/sqfmi_watchy/board.c | 1 + .../raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c | 2 ++ ports/raspberrypi/boards/pimoroni_badger2040/board.c | 1 + ports/raspberrypi/boards/pimoroni_badger2040w/board.c | 1 + ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c | 1 + ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c | 1 + 11 files changed, 13 insertions(+) diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 3ad2e162ecf3c..95027e817e8b8 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -76,6 +76,7 @@ void board_init(void) { NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually) false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, // refresh_display_sequence sizeof(refresh_sequence), 40, // refresh_time diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c index 6d4fcbf135e14..c4311474f6061 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -239,6 +239,7 @@ void board_init(void) { 0x26, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 ssd1680_display_refresh_sequence, sizeof(ssd1680_display_refresh_sequence), 1.0, // refresh_time &pin_GPIO5, // busy_pin @@ -273,6 +274,7 @@ void board_init(void) { 0x13, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 il0373_display_refresh_sequence, sizeof(il0373_display_refresh_sequence), 1.0, // refresh_time &pin_GPIO5, // busy_pin diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c index 88150dd401b97..b7f8bc50e714a 100644 --- a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c @@ -88,6 +88,7 @@ void board_init(void) { 0x26, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO48, // busy_pin diff --git a/ports/espressif/boards/heltec_vision_master_e290/board.c b/ports/espressif/boards/heltec_vision_master_e290/board.c index e392f65a76432..5911506ae2c3c 100644 --- a/ports/espressif/boards/heltec_vision_master_e290/board.c +++ b/ports/espressif/boards/heltec_vision_master_e290/board.c @@ -86,6 +86,7 @@ void board_init(void) { 0x26, // write_color_ram_command false, // color_bits_inverted 0xFF0000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO6, // busy_pin diff --git a/ports/espressif/boards/heltec_wireless_paper/board.c b/ports/espressif/boards/heltec_wireless_paper/board.c index 28fb6ae41b9a1..89e7a054b50c2 100644 --- a/ports/espressif/boards/heltec_wireless_paper/board.c +++ b/ports/espressif/boards/heltec_wireless_paper/board.c @@ -126,6 +126,7 @@ void board_init(void) { 0x10, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO7, // busy_pin diff --git a/ports/espressif/boards/sqfmi_watchy/board.c b/ports/espressif/boards/sqfmi_watchy/board.c index 393b8b759028a..535a3e11006fe 100644 --- a/ports/espressif/boards/sqfmi_watchy/board.c +++ b/ports/espressif/boards/sqfmi_watchy/board.c @@ -182,6 +182,7 @@ void board_init(void) { 0x26, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), (double)1.0, // refresh_time &pin_GPIO19, // busy_pin diff --git a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c index 19e18bd544bee..b7e75a475fd09 100644 --- a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c +++ b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c @@ -273,6 +273,7 @@ void board_init(void) { SSD_WRITE_RAM_RED, // write_color_ram_command false, // color_bits_inverted 0xFF0000, // highlight_color (RED for tri-color display) + 0x000000, // highlight_color2 _refresh_sequence_ssd1681, sizeof(_refresh_sequence_ssd1681), // refresh_display_command refresh_time, // refresh_time &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin @@ -307,6 +308,7 @@ void board_init(void) { NO_COMMAND, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color (RED for tri-color display) + 0x000000, // highlight_color2 _refresh_sequence_ssd1608, sizeof(_refresh_sequence_ssd1608), // refresh_display_command refresh_time, // refresh_time &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 5950d11da8a11..392a57cdc0c1b 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -295,6 +295,7 @@ void board_init(void) { DTM1, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO26, // busy_pin diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c index 7dc11af01eca3..01c448cd7ad52 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c @@ -295,6 +295,7 @@ void board_init(void) { DTM1, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), // refresh_display_command 1.0, // refresh_time &pin_GPIO26, // busy_pin diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c index 7969143ec6621..c7901b8649d78 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c @@ -89,6 +89,7 @@ void board_init(void) { NO_COMMAND, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), 28.0, // refresh_time NULL, // busy_pin diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c index 7c71e03b4281d..764c85ecb6bcf 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c @@ -148,6 +148,7 @@ void board_init(void) { NO_COMMAND, // write_color_ram_command false, // color_bits_inverted 0x000000, // highlight_color + 0x000000, // highlight_color2 refresh_sequence, sizeof(refresh_sequence), 28.0, // refresh_time NULL, // busy_pin From af67261469a516c4e6231a56ab0a7cbd98f72ca1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 29 Jul 2025 14:52:22 -0700 Subject: [PATCH 028/208] Tweak computation of new heap area size It now computes slightly more bytes to account for ATB size using truncated division. In other words, any remaining block space that doesn't fill an ATB byte won't be used. So, we round up our next area size to use an exact number of ATB bytes. Fixes #10451 --- py/gc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/py/gc.c b/py/gc.c index 338803dc245cc..2cf4dbb64a83b 100644 --- a/py/gc.c +++ b/py/gc.c @@ -311,8 +311,9 @@ void gc_add(void *start, void *end) { #if MICROPY_GC_SPLIT_HEAP_AUTO // CIRCUITPY-CHANGE: Added function to compute heap size with selective collect table static size_t compute_heap_size(size_t total_blocks) { - // Add two blocks to account for allocation alignment. - total_blocks += 2; + // Round up to the nearest multiple of BLOCKS_PER_ATB. Partial ATB blocks aren't supported and + // will result in a heap that is too small. + total_blocks = ((total_blocks + BLOCKS_PER_ATB - 1) / BLOCKS_PER_ATB) * BLOCKS_PER_ATB; size_t atb_bytes = (total_blocks + BLOCKS_PER_ATB - 1) / BLOCKS_PER_ATB; size_t ftb_bytes = 0; size_t ctb_bytes = 0; @@ -326,12 +327,13 @@ static size_t compute_heap_size(size_t total_blocks) { // Compute bytes needed to build a heap with total_blocks blocks. size_t total_heap = - atb_bytes + sizeof(mp_state_mem_area_t) + + atb_bytes + + ALLOC_TABLE_GAP_BYTE + ftb_bytes + ctb_bytes + pool_bytes - + ALLOC_TABLE_GAP_BYTE - + sizeof(mp_state_mem_area_t); + + BYTES_PER_BLOCK; // Extra block of bytes to account for end pointer alignment // Round up size to the nearest multiple of BYTES_PER_BLOCK. total_heap = (total_heap + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK; From 6e28ac3d16184c79a260df5e78159aa7db9ec450 Mon Sep 17 00:00:00 2001 From: Olivier Deveault Date: Mon, 28 Jul 2025 23:54:28 +0200 Subject: [PATCH 029/208] Translated using Weblate (French) Currently translated at 100.0% (1014 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/fr/ --- locale/fr.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index 3a53a97e8fa09..e2846046d93dc 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2025-06-30 16:01+0000\n" -"Last-Translator: MAE \n" +"PO-Revision-Date: 2025-07-29 22:07+0000\n" +"Last-Translator: Olivier Deveault \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -49,7 +49,7 @@ msgid "" "Press reset to exit safe mode.\n" msgstr "" "\n" -"Pour quitter le mode sans échec, appuyez sur reset.\n" +"Appuyer sur reset pour sortir du mode sans échec.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -57,7 +57,7 @@ msgid "" "You are in safe mode because:\n" msgstr "" "\n" -"Le mode sans échec est actif , car:\n" +"Le mode sans échec est actif pour cette raison:\n" #: py/obj.c msgid " File \"%q\"" @@ -2024,7 +2024,7 @@ msgstr "Format correct mais non supporté" #: main.c msgid "Running in safe mode! Not running saved code.\n" -msgstr "Mode sans- échec ! Le code sauvegardé n'est pas éxecuté.\n" +msgstr "Mode sans échec ! Le code sauvegardé n'est pas éxecuté.\n" #: shared-module/sdcardio/SDCard.c msgid "SD card CSD format not supported" From 16f4f65cc97536fd139dfa54a251cac47fb15d5b Mon Sep 17 00:00:00 2001 From: Jacques Supcik Date: Tue, 29 Jul 2025 00:06:36 +0200 Subject: [PATCH 030/208] Translated using Weblate (French) Currently translated at 100.0% (1014 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/fr/ --- locale/fr.po | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index e2846046d93dc..b542f8c98fadb 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -9,7 +9,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" "PO-Revision-Date: 2025-07-29 22:07+0000\n" -"Last-Translator: Olivier Deveault \n" +"Last-Translator: Jacques Supcik \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -1879,15 +1879,15 @@ msgstr "Plus tout autres modules présents sur le système de fichiers\n" #: shared-module/vectorio/Polygon.c msgid "Polygon needs at least 3 points" -msgstr "Polygon a besoin d'au moins 3 points" +msgstr "Un polygone a besoin d'au moins 3 points" #: supervisor/shared/safe_mode.c msgid "Power dipped. Make sure you are providing enough power." -msgstr "Chute de puissance.Apportez plus d'énergie." +msgstr "Chute de puissance. Assurez-vous de fournir assez de puissance." #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" -msgstr "Le tampon de préfixe doit être sur la pile" +msgstr "Le tampon de préfixe doit être sur le tas" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" @@ -1919,11 +1919,12 @@ msgstr "Programme trop long" #: shared-bindings/rclcpy/Publisher.c msgid "Publishers can only be created from a parent node" -msgstr "Les Publishers ne peuvent etre crées que du noeud parent" +msgstr "Les Publishers ne peuvent être créés qu'à partir du nœud parent" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." -msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." +msgstr "" +"L'attribut \"pull\" n'est pas utilisé quand la direction est \"output\"." #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" From 0e26ab4dafd1eac79a1fd8acf96b78ae0e426c0d Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Wed, 30 Jul 2025 06:41:24 +0000 Subject: [PATCH 031/208] update USB_MANUFACTURER for senseBox boards --- ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk | 2 +- ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk index 8bfcda99a153b..55e822c5dea4a 100644 --- a/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk +++ b/ports/espressif/boards/sensebox_eye_esp32s3/mpconfigboard.mk @@ -2,7 +2,7 @@ USB_VID = 0x303A USB_PID = 0x82D2 USB_PRODUCT = "senseBox-eye ESP32S3" -USB_MANUFACTURER = "Espressif" +USB_MANUFACTURER = "senseBox" IDF_TARGET = esp32s3 diff --git a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk index 9d3fbecabde71..6b97c870cc032 100644 --- a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x303A USB_PID = 0x81B9 USB_PRODUCT = "senseBox MCU-S2 ESP32S2" -USB_MANUFACTURER = "Espressif" +USB_MANUFACTURER = "senseBox" IDF_TARGET = esp32s2 From fd2627cf950d4a0987b3b79a0ad12f019be8a1dd Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 30 Jul 2025 12:45:15 -0500 Subject: [PATCH 032/208] Support mono to stereo conversion in `audiomixer.Mixer` --- shared-module/audiocore/__init__.c | 4 +- shared-module/audiocore/__init__.h | 2 +- shared-module/audiodelays/Chorus.c | 2 +- shared-module/audiodelays/Echo.c | 2 +- shared-module/audiodelays/MultiTapDelay.c | 2 +- shared-module/audiodelays/PitchShift.c | 2 +- shared-module/audiofilters/Distortion.c | 2 +- shared-module/audiofilters/Filter.c | 2 +- shared-module/audiofilters/Phaser.c | 2 +- shared-module/audiofreeverb/Freeverb.c | 2 +- shared-module/audiomixer/Mixer.c | 161 +++++++++++++++++----- shared-module/audiomixer/MixerVoice.c | 2 +- 12 files changed, 142 insertions(+), 43 deletions(-) diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c index bf80403137996..2ee683d75e1cd 100644 --- a/shared-module/audiocore/__init__.c +++ b/shared-module/audiocore/__init__.c @@ -196,12 +196,12 @@ void audiosample_convert_s16s_u8s(uint8_t *buffer_out, const int16_t *buffer_in, } } -void audiosample_must_match(audiosample_base_t *self, mp_obj_t other_in) { +void audiosample_must_match(audiosample_base_t *self, mp_obj_t other_in, bool allow_mono_to_stereo) { const audiosample_base_t *other = audiosample_check(other_in); if (other->sample_rate != self->sample_rate) { mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_sample_rate); } - if (other->channel_count != self->channel_count) { + if ((!allow_mono_to_stereo || (allow_mono_to_stereo && self->channel_count != 2)) && other->channel_count != self->channel_count) { mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_channel_count); } if (other->bits_per_sample != self->bits_per_sample) { diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h index 875ac90ecc5c1..920fe752c3822 100644 --- a/shared-module/audiocore/__init__.h +++ b/shared-module/audiocore/__init__.h @@ -89,7 +89,7 @@ static inline void audiosample_get_buffer_structure_checked(mp_obj_t self_in, bo audiosample_get_buffer_structure(audiosample_check(self_in), single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); } -void audiosample_must_match(audiosample_base_t *self, mp_obj_t other); +void audiosample_must_match(audiosample_base_t *self, mp_obj_t other, bool allow_mono_to_stereo); void audiosample_convert_u8m_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes); void audiosample_convert_u8s_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes); diff --git a/shared-module/audiodelays/Chorus.c b/shared-module/audiodelays/Chorus.c index 1609cc5f94684..9262c6b4de195 100644 --- a/shared-module/audiodelays/Chorus.c +++ b/shared-module/audiodelays/Chorus.c @@ -166,7 +166,7 @@ bool common_hal_audiodelays_chorus_get_playing(audiodelays_chorus_obj_t *self) { } void common_hal_audiodelays_chorus_play(audiodelays_chorus_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c index 78764d9099a1c..0ca5fc8a7502e 100644 --- a/shared-module/audiodelays/Echo.c +++ b/shared-module/audiodelays/Echo.c @@ -204,7 +204,7 @@ bool common_hal_audiodelays_echo_get_playing(audiodelays_echo_obj_t *self) { } void common_hal_audiodelays_echo_play(audiodelays_echo_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiodelays/MultiTapDelay.c b/shared-module/audiodelays/MultiTapDelay.c index 7b702ecf1154a..9c33a5eaee750 100644 --- a/shared-module/audiodelays/MultiTapDelay.c +++ b/shared-module/audiodelays/MultiTapDelay.c @@ -285,7 +285,7 @@ bool common_hal_audiodelays_multi_tap_delay_get_playing(audiodelays_multi_tap_de } void common_hal_audiodelays_multi_tap_delay_play(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiodelays/PitchShift.c b/shared-module/audiodelays/PitchShift.c index ac349da0dd50a..3b8c1a07c7b16 100644 --- a/shared-module/audiodelays/PitchShift.c +++ b/shared-module/audiodelays/PitchShift.c @@ -143,7 +143,7 @@ bool common_hal_audiodelays_pitch_shift_get_playing(audiodelays_pitch_shift_obj_ } void common_hal_audiodelays_pitch_shift_play(audiodelays_pitch_shift_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiofilters/Distortion.c b/shared-module/audiofilters/Distortion.c index ec5fe084e56d3..c4b6b7566ad0d 100644 --- a/shared-module/audiofilters/Distortion.c +++ b/shared-module/audiofilters/Distortion.c @@ -141,7 +141,7 @@ bool common_hal_audiofilters_distortion_get_playing(audiofilters_distortion_obj_ } void common_hal_audiofilters_distortion_play(audiofilters_distortion_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiofilters/Filter.c b/shared-module/audiofilters/Filter.c index 19b567532eb8e..4cedc810abad6 100644 --- a/shared-module/audiofilters/Filter.c +++ b/shared-module/audiofilters/Filter.c @@ -143,7 +143,7 @@ bool common_hal_audiofilters_filter_get_playing(audiofilters_filter_obj_t *self) } void common_hal_audiofilters_filter_play(audiofilters_filter_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiofilters/Phaser.c b/shared-module/audiofilters/Phaser.c index 81d9c0bea3083..01b938c3a0027 100644 --- a/shared-module/audiofilters/Phaser.c +++ b/shared-module/audiofilters/Phaser.c @@ -130,7 +130,7 @@ bool common_hal_audiofilters_phaser_get_playing(audiofilters_phaser_obj_t *self) } void common_hal_audiofilters_phaser_play(audiofilters_phaser_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiofreeverb/Freeverb.c b/shared-module/audiofreeverb/Freeverb.c index d910536013604..28779bdcc84b2 100644 --- a/shared-module/audiofreeverb/Freeverb.c +++ b/shared-module/audiofreeverb/Freeverb.c @@ -195,7 +195,7 @@ bool common_hal_audiofreeverb_freeverb_get_playing(audiofreeverb_freeverb_obj_t } void common_hal_audiofreeverb_freeverb_play(audiofreeverb_freeverb_obj_t *self, mp_obj_t sample, bool loop) { - audiosample_must_match(&self->base, sample); + audiosample_must_match(&self->base, sample, false); self->sample = sample; self->loop = loop; diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 2c727a5c0cdde..2f510dd1338aa 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -154,9 +154,30 @@ static inline uint32_t pack8(uint32_t val) { return ((val & 0xff000000) >> 16) | ((val & 0xff00) >> 8); } +static inline uint32_t copy16lsb(uint32_t val) { + val &= 0x0000ffff; + return val | (val << 16); +} + +static inline uint32_t copy16msb(uint32_t val) { + val &= 0xffff0000; + return val | (val >> 16); +} + +static inline uint32_t copy8lsb(uint32_t val) { + val &= 0x00ff; + return val | (val << 8); +} + +static inline uint32_t copy8msb(uint32_t val) { + val &= 0xff00; + return val | (val >> 8); +} + static void mix_down_one_voice(audiomixer_mixer_obj_t *self, audiomixer_mixervoice_obj_t *voice, bool voices_active, uint32_t *word_buffer, uint32_t length) { + audiosample_base_t *sample = MP_OBJ_TO_PTR(voice->sample); while (length != 0) { if (voice->buffer_length == 0) { if (!voice->more_data) { @@ -179,13 +200,23 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, uint32_t *src = voice->remaining_buffer; #if CIRCUITPY_SYNTHIO - uint32_t n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + uint32_t n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(voice->buffer_length << 1, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); #else - uint32_t n = MIN(voice->buffer_length, length); + uint32_t n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + n = MIN(voice->buffer_length, length); + } else { + n = MIN(voice->buffer_length << 1, length); + } uint16_t level = voice->level; #endif @@ -193,61 +224,129 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (!voices_active) { if (MP_LIKELY(self->base.bits_per_sample == 16)) { if (MP_LIKELY(self->base.samples_signed)) { - for (uint32_t i = 0; i < n; i++) { - uint32_t v = src[i]; - word_buffer[i] = mult16signed(v, level); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t v = src[i]; + word_buffer[i] = mult16signed(v, level); + } + } else { + for (uint32_t i = 0; i < n; i += 2) { + uint32_t v = src[i >> 1]; + v = mult16signed(v, level); + word_buffer[i] = copy16lsb(v); + word_buffer[i + 1] = copy16msb(v); + } } } else { - for (uint32_t i = 0; i < n; i++) { - uint32_t v = src[i]; - v = tosigned16(v); - word_buffer[i] = mult16signed(v, level); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t v = src[i]; + v = tosigned16(v); + word_buffer[i] = mult16signed(v, level); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t v = src[i >> 1]; + v = tosigned16(v); + v = mult16signed(v, level); + word_buffer[i] = copy16lsb(v); + word_buffer[i + 1] = copy16msb(v); + } } } } else { uint16_t *hword_buffer = (uint16_t *)word_buffer; uint16_t *hsrc = (uint16_t *)src; - for (uint32_t i = 0; i < n * 2; i++) { - uint32_t word = unpack8(hsrc[i]); - if (MP_LIKELY(!self->base.samples_signed)) { - word = tosigned16(word); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n * 2; i++) { + uint32_t word = unpack8(hsrc[i]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + word = mult16signed(word, level); + hword_buffer[i] = pack8(word); + } + } else { + for (uint32_t i = 0; i + 1 < n * 2; i += 2) { + uint32_t word = unpack8(hsrc[i >> 1]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + word = mult16signed(word, level); + word = pack8(word); + hword_buffer[i] = copy8lsb(word); + hword_buffer[i + 1] = copy8msb(word); } - word = mult16signed(word, level); - hword_buffer[i] = pack8(word); } } } else { if (MP_LIKELY(self->base.bits_per_sample == 16)) { if (MP_LIKELY(self->base.samples_signed)) { - for (uint32_t i = 0; i < n; i++) { - uint32_t word = src[i]; - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t word = src[i >> 1]; + word = mult16signed(word, level); + word_buffer[i] = add16signed(copy16lsb(word), word_buffer[i]); + word_buffer[i + 1] = add16signed(copy16msb(word), word_buffer[i + 1]); + } } } else { - for (uint32_t i = 0; i < n; i++) { - uint32_t word = src[i]; - word = tosigned16(word); - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + word = tosigned16(word); + word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t word = src[i >> 1]; + word = tosigned16(word); + word = mult16signed(word, level); + word_buffer[i] = add16signed(copy16lsb(word), word_buffer[i]); + word_buffer[i + 1] = add16signed(copy16msb(word), word_buffer[i + 1]); + } } } } else { uint16_t *hword_buffer = (uint16_t *)word_buffer; uint16_t *hsrc = (uint16_t *)src; - for (uint32_t i = 0; i < n * 2; i++) { - uint32_t word = unpack8(hsrc[i]); - if (MP_LIKELY(!self->base.samples_signed)) { - word = tosigned16(word); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n * 2; i++) { + uint32_t word = unpack8(hsrc[i]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + word = mult16signed(word, level); + word = add16signed(word, unpack8(hword_buffer[i])); + hword_buffer[i] = pack8(word); + } + } else { + for (uint32_t i = 0; i + 1 < n * 2; i += 2) { + uint32_t word = unpack8(hsrc[i >> 1]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + word = mult16signed(word, level); + hword_buffer[i] = pack8(add16signed(copy16lsb(word), unpack8(hword_buffer[i]))); + hword_buffer[i + 1] = pack8(add16signed(copy16msb(word), unpack8(hword_buffer[i + 1]))); } - word = mult16signed(word, level); - word = add16signed(word, unpack8(hword_buffer[i])); - hword_buffer[i] = pack8(word); } } } length -= n; word_buffer += n; - voice->remaining_buffer += n; - voice->buffer_length -= n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + voice->remaining_buffer += n; + voice->buffer_length -= n; + } else { + voice->remaining_buffer += n >> 1; + voice->buffer_length -= n >> 1; + } } if (length && !voices_active) { diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index e0be869aa8e44..96f3baf406880 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -47,7 +47,7 @@ void common_hal_audiomixer_mixervoice_set_loop(audiomixer_mixervoice_obj_t *self } void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample_in, bool loop) { - audiosample_must_match(&self->parent->base, sample_in); + audiosample_must_match(&self->parent->base, sample_in, true); // cast is safe, checked by must_match audiosample_base_t *sample = MP_OBJ_TO_PTR(sample_in); self->sample = sample; From c92efd66db3b9c66679c3b6752ecbb38612ab4f8 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 30 Jul 2025 13:26:04 -0500 Subject: [PATCH 033/208] Add `MixerVoice.panning` --- shared-bindings/audiomixer/MixerVoice.c | 26 +++++++++ shared-bindings/audiomixer/MixerVoice.h | 2 + shared-module/audiomixer/Mixer.c | 70 +++++++++++++++---------- shared-module/audiomixer/MixerVoice.c | 17 ++++++ shared-module/audiomixer/MixerVoice.h | 2 + 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index fc292d4ea2f68..b87bd4d6525cb 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -114,6 +114,31 @@ MP_PROPERTY_GETSET(audiomixer_mixervoice_level_obj, (mp_obj_t)&audiomixer_mixervoice_get_level_obj, (mp_obj_t)&audiomixer_mixervoice_set_level_obj); +//| panning: synthio.BlockInput +//| """Defines the channel(s) in which the voice appears, as a floating point number between +//| -1 and 1. If your board does not support synthio, this property will only accept a float +//| value. This property is ignored if `audiomixer.Mixer.channel_count=1`. +//| +//| -1 is left channel only, 0 is both channels, and 1 is right channel. For fractional values, +//| the note plays at full amplitude in one channel and partial amplitude in the other channel. +//| For instance -.5 plays at full amplitude in the left channel and 1/2 amplitude in the right +//| channel.""" +static mp_obj_t audiomixer_mixervoice_obj_get_panning(mp_obj_t self_in) { + return common_hal_audiomixer_mixervoice_get_panning(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_panning_obj, audiomixer_mixervoice_obj_get_panning); + +static mp_obj_t audiomixer_mixervoice_obj_set_panning(mp_obj_t self_in, mp_obj_t panning_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixervoice_set_panning(self, panning_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiomixer_mixervoice_set_panning_obj, audiomixer_mixervoice_obj_set_panning); + +MP_PROPERTY_GETSET(audiomixer_mixervoice_panning_obj, + (mp_obj_t)&audiomixer_mixervoice_get_panning_obj, + (mp_obj_t)&audiomixer_mixervoice_set_panning_obj); + //| loop: bool //| """Get or set the loop status of the currently playing sample.""" static mp_obj_t audiomixer_mixervoice_obj_get_loop(mp_obj_t self_in) { @@ -158,6 +183,7 @@ static const mp_rom_map_elem_t audiomixer_mixervoice_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixervoice_playing_obj) }, { MP_ROM_QSTR(MP_QSTR_level), MP_ROM_PTR(&audiomixer_mixervoice_level_obj) }, + { MP_ROM_QSTR(MP_QSTR_panning), MP_ROM_PTR(&audiomixer_mixervoice_panning_obj) }, { MP_ROM_QSTR(MP_QSTR_loop), MP_ROM_PTR(&audiomixer_mixervoice_loop_obj) }, }; static MP_DEFINE_CONST_DICT(audiomixer_mixervoice_locals_dict, audiomixer_mixervoice_locals_dict_table); diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h index fe350eb1a7592..d60820f7f5734 100644 --- a/shared-bindings/audiomixer/MixerVoice.h +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -18,6 +18,8 @@ void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t *self); void common_hal_audiomixer_mixervoice_end(audiomixer_mixervoice_obj_t *self); mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t gain); +mp_obj_t common_hal_audiomixer_mixervoice_get_panning(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_panning(audiomixer_mixervoice_obj_t *self, mp_obj_t value); bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *self); diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 2f510dd1338aa..ebbb410388f23 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -92,22 +92,22 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { } __attribute__((always_inline)) -static inline uint32_t mult16signed(uint32_t val, int32_t mul) { +static inline uint32_t mult16signed(uint32_t val, int32_t mul[2]) { #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) mul <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits enum { shift = 15 }; // shift is done automatically - asm volatile ("smulwb %0, %1, %2" : "=r" (lo) : "r" (mul), "r" (val)); - asm volatile ("smulwt %0, %1, %2" : "=r" (hi) : "r" (mul), "r" (val)); + asm volatile ("smulwb %0, %1, %2" : "=r" (lo) : "r" (mul[0]), "r" (val)); + asm volatile ("smulwt %0, %1, %2" : "=r" (hi) : "r" (mul[1]), "r" (val)); asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); asm volatile ("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack return val; #else uint32_t result = 0; - float mod_mul = (float)mul / (float)((1 << 15) - 1); for (int8_t i = 0; i < 2; i++) { + float mod_mul = (float)mul[i] / (float)((1 << 15) - 1); int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); int32_t intermediate = (int32_t)(ai * mod_mul); if (intermediate > SHRT_MAX) { @@ -174,6 +174,8 @@ static inline uint32_t copy8msb(uint32_t val) { return val | (val >> 8); } +#define ALMOST_ONE (MICROPY_FLOAT_CONST(32767.) / 32768) + static void mix_down_one_voice(audiomixer_mixer_obj_t *self, audiomixer_mixervoice_obj_t *voice, bool voices_active, uint32_t *word_buffer, uint32_t length) { @@ -210,6 +212,7 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); + int16_t panning = synthio_block_slot_get_scaled(&voice->panning, -ALMOST_ONE, ALMOST_ONE); #else uint32_t n; if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { @@ -218,8 +221,24 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, n = MIN(voice->buffer_length << 1, length); } uint16_t level = voice->level; + int16_t panning = voice->panning; #endif + uint16_t left_panning_scaled = 32768, right_panning_scaled = 32768; + if (MP_LIKELY(self->base.channel_count == 2)) { + if (panning >= 0) { + right_panning_scaled = 32767 - panning; + } else { + left_panning_scaled = 32767 + panning; + } + } + + int32_t loudness[2] = { level, level }; + if (MP_LIKELY(self->base.channel_count == 2)) { + loudness[0] = (left_panning_scaled * loudness[0]) >> 15; + loudness[1] = (right_panning_scaled * loudness[1]) >> 15; + } + // First active voice gets copied over verbatim. if (!voices_active) { if (MP_LIKELY(self->base.bits_per_sample == 16)) { @@ -227,14 +246,13 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { for (uint32_t i = 0; i < n; i++) { uint32_t v = src[i]; - word_buffer[i] = mult16signed(v, level); + word_buffer[i] = mult16signed(v, loudness); } } else { for (uint32_t i = 0; i < n; i += 2) { uint32_t v = src[i >> 1]; - v = mult16signed(v, level); - word_buffer[i] = copy16lsb(v); - word_buffer[i + 1] = copy16msb(v); + word_buffer[i] = mult16signed(copy16lsb(v), loudness); + word_buffer[i + 1] = mult16signed(copy16msb(v), loudness); } } } else { @@ -242,15 +260,14 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, for (uint32_t i = 0; i < n; i++) { uint32_t v = src[i]; v = tosigned16(v); - word_buffer[i] = mult16signed(v, level); + word_buffer[i] = mult16signed(v, loudness); } } else { for (uint32_t i = 0; i + 1 < n; i += 2) { uint32_t v = src[i >> 1]; v = tosigned16(v); - v = mult16signed(v, level); - word_buffer[i] = copy16lsb(v); - word_buffer[i + 1] = copy16msb(v); + word_buffer[i] = mult16signed(copy16lsb(v), loudness); + word_buffer[i + 1] = mult16signed(copy16msb(v), loudness); } } } @@ -263,7 +280,7 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(!self->base.samples_signed)) { word = tosigned16(word); } - word = mult16signed(word, level); + word = mult16signed(word, loudness); hword_buffer[i] = pack8(word); } } else { @@ -272,10 +289,8 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(!self->base.samples_signed)) { word = tosigned16(word); } - word = mult16signed(word, level); - word = pack8(word); - hword_buffer[i] = copy8lsb(word); - hword_buffer[i + 1] = copy8msb(word); + hword_buffer[i] = pack8(mult16signed(copy16lsb(word), loudness)); + hword_buffer[i + 1] = pack8(mult16signed(copy16msb(word), loudness)); } } } @@ -285,14 +300,13 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { for (uint32_t i = 0; i < n; i++) { uint32_t word = src[i]; - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + word_buffer[i] = add16signed(mult16signed(word, loudness), word_buffer[i]); } } else { for (uint32_t i = 0; i + 1 < n; i += 2) { uint32_t word = src[i >> 1]; - word = mult16signed(word, level); - word_buffer[i] = add16signed(copy16lsb(word), word_buffer[i]); - word_buffer[i + 1] = add16signed(copy16msb(word), word_buffer[i + 1]); + word_buffer[i] = add16signed(mult16signed(copy16lsb(word), loudness), word_buffer[i]); + word_buffer[i + 1] = add16signed(mult16signed(copy16msb(word), loudness), word_buffer[i + 1]); } } } else { @@ -300,15 +314,14 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, for (uint32_t i = 0; i < n; i++) { uint32_t word = src[i]; word = tosigned16(word); - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + word_buffer[i] = add16signed(mult16signed(word, loudness), word_buffer[i]); } } else { for (uint32_t i = 0; i + 1 < n; i += 2) { uint32_t word = src[i >> 1]; word = tosigned16(word); - word = mult16signed(word, level); - word_buffer[i] = add16signed(copy16lsb(word), word_buffer[i]); - word_buffer[i + 1] = add16signed(copy16msb(word), word_buffer[i + 1]); + word_buffer[i] = add16signed(mult16signed(copy16lsb(word), loudness), word_buffer[i]); + word_buffer[i + 1] = add16signed(mult16signed(copy16msb(word), loudness), word_buffer[i + 1]); } } } @@ -321,7 +334,7 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(!self->base.samples_signed)) { word = tosigned16(word); } - word = mult16signed(word, level); + word = mult16signed(word, loudness); word = add16signed(word, unpack8(hword_buffer[i])); hword_buffer[i] = pack8(word); } @@ -331,9 +344,8 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (MP_LIKELY(!self->base.samples_signed)) { word = tosigned16(word); } - word = mult16signed(word, level); - hword_buffer[i] = pack8(add16signed(copy16lsb(word), unpack8(hword_buffer[i]))); - hword_buffer[i + 1] = pack8(add16signed(copy16msb(word), unpack8(hword_buffer[i + 1]))); + hword_buffer[i] = pack8(add16signed(mult16signed(copy16lsb(word), loudness), unpack8(hword_buffer[i]))); + hword_buffer[i + 1] = pack8(add16signed(mult16signed(copy16msb(word), loudness), unpack8(hword_buffer[i + 1]))); } } } diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index 96f3baf406880..6c23a39215cbc 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -16,6 +16,7 @@ void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self) { self->sample = NULL; common_hal_audiomixer_mixervoice_set_level(self, mp_obj_new_float(1.0)); + common_hal_audiomixer_mixervoice_set_panning(self, mp_obj_new_float(0.0)); } void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent) { @@ -38,6 +39,22 @@ void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *sel #endif } +mp_obj_t common_hal_audiomixer_mixervoice_get_panning(audiomixer_mixervoice_obj_t *self) { + #if CIRCUITPY_SYNTHIO + return self->panning.obj; + #else + return mp_obj_new_float((mp_float_t)self->panning / ((1 << 15) - 1)); + #endif +} + +void common_hal_audiomixer_mixervoice_set_panning(audiomixer_mixervoice_obj_t *self, mp_obj_t arg) { + #if CIRCUITPY_SYNTHIO + synthio_block_assign_slot(arg, &self->panning, MP_QSTR_panning); + #else + self->panning = (uint16_t)(mp_arg_validate_obj_float_range(arg, -1, 1, MP_QSTR_panning) * ((1 << 15) - 1)); + #endif +} + bool common_hal_audiomixer_mixervoice_get_loop(audiomixer_mixervoice_obj_t *self) { return self->loop; } diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h index dd9095515459a..75e7d47faa33d 100644 --- a/shared-module/audiomixer/MixerVoice.h +++ b/shared-module/audiomixer/MixerVoice.h @@ -23,7 +23,9 @@ typedef struct { uint32_t buffer_length; #if CIRCUITPY_SYNTHIO synthio_block_slot_t level; + synthio_block_slot_t panning; #else uint16_t level; + int16_t panning; #endif } audiomixer_mixervoice_obj_t; From fb84062800e85a826ab08a9b4fc8f5626599647c Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 30 Jul 2025 14:05:24 -0500 Subject: [PATCH 034/208] Fix bitshift operation on atmel-samd --- shared-module/audiomixer/Mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index ebbb410388f23..b27eafb71a98c 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -94,7 +94,8 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { __attribute__((always_inline)) static inline uint32_t mult16signed(uint32_t val, int32_t mul[2]) { #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) - mul <<= 16; + mul[0] <<= 16; + mul[1] <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits enum { shift = 15 }; // shift is done automatically From f94f564a41e7821f1c34354e19c1bbc53394cc84 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 30 Jul 2025 14:15:05 -0500 Subject: [PATCH 035/208] Fix docstring reference --- shared-bindings/audiomixer/MixerVoice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index b87bd4d6525cb..128c214d447f8 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -117,7 +117,7 @@ MP_PROPERTY_GETSET(audiomixer_mixervoice_level_obj, //| panning: synthio.BlockInput //| """Defines the channel(s) in which the voice appears, as a floating point number between //| -1 and 1. If your board does not support synthio, this property will only accept a float -//| value. This property is ignored if `audiomixer.Mixer.channel_count=1`. +//| value. This property is ignored if ``audiomixer.Mixer.channel_count=1``. //| //| -1 is left channel only, 0 is both channels, and 1 is right channel. For fractional values, //| the note plays at full amplitude in one channel and partial amplitude in the other channel. From f1d20b277181483a55869c2600a4ef159af506e5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 30 Jul 2025 17:33:21 -0400 Subject: [PATCH 036/208] .github/actions/deps/ports/nordic/action.yml: Change URL for nrfutil --- .github/actions/deps/ports/nordic/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deps/ports/nordic/action.yml b/.github/actions/deps/ports/nordic/action.yml index 5f08b17ca7a68..96754be9507c5 100644 --- a/.github/actions/deps/ports/nordic/action.yml +++ b/.github/actions/deps/ports/nordic/action.yml @@ -5,7 +5,7 @@ runs: steps: - name: Get nrfutil 7+ run: | - wget https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil + wget https://files.nordicsemi.com/artifactory/swtools/external/nrfutil/executables/x86_64-unknown-linux-gnu/nrfutil chmod +x nrfutil ./nrfutil install nrf5sdk-tools mkdir -p $HOME/.local/bin From 58b13f731d0dd8bfc0ed329486a01afec9f72a90 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Fri, 1 Aug 2025 08:45:33 +0000 Subject: [PATCH 037/208] fix picodvi refresh rates (use 60Hz) This implements video mode timing changes suggested by @WolfWings in circuitpython issue #10242. Previously, picodvi was set so that 640x480 and 720x400 used refresh rates faster than 60Hz. These changes lower the refresh rate to 60Hz which should hopefully be compatible with a wider range of HDMI devices. --- .../common-hal/picodvi/Framebuffer_RP2350.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c index 79ec315d497e4..2dc19558314cb 100644 --- a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c @@ -54,15 +54,15 @@ #define SYNC_V1_H1 (TMDS_CTRL_11 | (TMDS_CTRL_00 << 10) | (TMDS_CTRL_00 << 20)) #define MODE_720_H_SYNC_POLARITY 0 -#define MODE_720_H_FRONT_PORCH 24 -#define MODE_720_H_SYNC_WIDTH 64 -#define MODE_720_H_BACK_PORCH 88 +#define MODE_720_H_FRONT_PORCH 8 +#define MODE_720_H_SYNC_WIDTH 32 +#define MODE_720_H_BACK_PORCH 40 #define MODE_720_H_ACTIVE_PIXELS 720 #define MODE_720_V_SYNC_POLARITY 0 #define MODE_720_V_FRONT_PORCH 3 #define MODE_720_V_SYNC_WIDTH 4 -#define MODE_720_V_BACK_PORCH 13 +#define MODE_720_V_BACK_PORCH 218 #define MODE_720_V_ACTIVE_LINES 400 #define MODE_640_H_SYNC_POLARITY 0 @@ -74,7 +74,7 @@ #define MODE_640_V_SYNC_POLARITY 0 #define MODE_640_V_FRONT_PORCH 10 #define MODE_640_V_SYNC_WIDTH 2 -#define MODE_640_V_BACK_PORCH 33 +#define MODE_640_V_BACK_PORCH 133 #define MODE_640_V_ACTIVE_LINES 480 #define MODE_720_V_TOTAL_LINES ( \ From 173a94661bc8371ee5639ba47db4d82af78951ad Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 1 Aug 2025 13:51:35 -0400 Subject: [PATCH 038/208] correct board.UART() pins on Feather ESP32-S2/S3 also touch up some other files to be identical --- .../mpconfigboard.h | 4 ++-- .../mpconfigboard.mk | 3 +++ .../adafruit_feather_esp32s2_reverse_tft/sdkconfig | 14 ++++++++++++++ .../mpconfigboard.h | 4 ++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h index 42b51434edfd3..f2ec187abde63 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h @@ -23,7 +23,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) -#define DEFAULT_UART_BUS_RX (&pin_GPIO34) -#define DEFAULT_UART_BUS_TX (&pin_GPIO35) +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO39) #define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk index 06a1bf706d345..a0be8c7a5ca0a 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk @@ -13,3 +13,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Already have a display. +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig index e69de29bb2d1d..e962866216039 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h index c11780faf41ea..5053a1b2b589b 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h @@ -23,7 +23,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) -#define DEFAULT_UART_BUS_RX (&pin_GPIO34) -#define DEFAULT_UART_BUS_TX (&pin_GPIO35) +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO39) #define DOUBLE_TAP_PIN (&pin_GPIO34) From efc45dea15e43c8b91f15b8f12573fff246e88c9 Mon Sep 17 00:00:00 2001 From: MAE Date: Sat, 2 Aug 2025 09:45:08 +0200 Subject: [PATCH 039/208] Translated using Weblate (Spanish) Currently translated at 99.6% (1010 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/es/ --- locale/es.po | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/locale/es.po b/locale/es.po index fa7377b5b53d5..85a03408b7517 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2025-07-17 04:01+0000\n" -"Last-Translator: Jean Serrano \n" +"PO-Revision-Date: 2025-08-03 08:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -1803,10 +1803,9 @@ msgid "PWM slice channel A already in use" msgstr "Segmento del PWM canal A ya esta en uso" #: shared-bindings/spitarget/SPITarget.c -#, fuzzy msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -"Búferes de paquetes para transferencia SPI deben de ser de igual longitud" +"Búferes de paquetes para transferencia SPI deben de ser de igual longitud." #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" From e3f61544f563de33d4c991c48b982185a932bd2d Mon Sep 17 00:00:00 2001 From: MAE Date: Sat, 2 Aug 2025 09:57:57 +0200 Subject: [PATCH 040/208] Translated using Weblate (French) Currently translated at 99.9% (1013 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/fr/ --- locale/fr.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locale/fr.po b/locale/fr.po index b542f8c98fadb..f871c669f93ed 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2025-07-29 22:07+0000\n" -"Last-Translator: Jacques Supcik \n" +"PO-Revision-Date: 2025-08-03 08:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -3972,7 +3972,7 @@ msgstr "seules les tranches avec 'step=1' (cad None) sont supportées" #: py/vm.c msgid "opcode" -msgstr "opcode" +msgstr "" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c #: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c From 23bf5a52e1863ec8e2873f141b723958bdf9ccca Mon Sep 17 00:00:00 2001 From: MAE Date: Sat, 2 Aug 2025 09:46:40 +0200 Subject: [PATCH 041/208] Translated using Weblate (Polish) Currently translated at 52.3% (531 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pl/ --- locale/pl.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locale/pl.po b/locale/pl.po index 9b20c513e7a09..66bf686097992 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2025-07-23 09:07+0000\n" -"Last-Translator: MuskoM \n" +"PO-Revision-Date: 2025-08-03 08:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: pl\n" "Language: pl\n" "MIME-Version: 1.0\n" @@ -90,8 +90,8 @@ msgstr "%%c wymaga int lub char" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" -"%d pinów adresowalnych, %d pinów rgb oraz %d płytek wskazują na wysokość " -"%d, nie %d" +"%d pinów adresowalnych, %d pinów rgb oraz %d płytek wskazują na wysokość %d, " +"nie %d" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" From 3aa680cf9c47f3399fa62a902b678a747c575fd2 Mon Sep 17 00:00:00 2001 From: Peggy Date: Mon, 4 Aug 2025 16:19:06 -0700 Subject: [PATCH 042/208] Add os.urandom module to ports/analog for MAX32690_apard I added a port-specific module, os.urandom() to ports/analog. Now users can generate random numbers from the TRNG hardware. The following code generates 3 random numbers and prints them in hex: import os print(os.urandom(3).hex()) Files I modiied: * ports/analog/Makefile: added INC and SRC for TRNG * ports/mpconfigport.mk: enabled CIRCUITPY_RANDOM * ports/analog/common-hal/os/__init__.c: implemented common_hal_os_urandom() * ports/analog/supervisor/port.c: initialized the TRNG object --- ports/analog/Makefile | 7 +++++-- ports/analog/common-hal/os/__init__.c | 7 ++++++- ports/analog/mpconfigport.mk | 2 +- ports/analog/supervisor/port.c | 12 ++++++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ports/analog/Makefile b/ports/analog/Makefile index 08b245c5897e3..0d4d05f136804 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -83,7 +83,8 @@ INC += \ -I$(PERIPH_SRC)/ICC \ -I$(PERIPH_SRC)/TMR \ -I$(PERIPH_SRC)/RTC \ - -I$(PERIPH_SRC)/UART + -I$(PERIPH_SRC)/UART \ + -I$(PERIPH_SRC)/TRNG INC += -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/GCC @@ -116,7 +117,9 @@ SRC_MAX32 += \ $(PERIPH_SRC)/TMR/tmr_$(DIE_TYPE).c \ $(PERIPH_SRC)/UART/uart_common.c \ $(PERIPH_SRC)/UART/uart_$(DIE_TYPE).c \ - $(PERIPH_SRC)/UART/uart_revb.c + $(PERIPH_SRC)/UART/uart_revb.c \ + $(PERIPH_SRC)/TRNG/trng_revb.c \ + $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c SRC_C += $(SRC_MAX32) \ boards/$(BOARD)/board.c \ diff --git a/ports/analog/common-hal/os/__init__.c b/ports/analog/common-hal/os/__init__.c index 7b607cf6b3c4b..04667db8b5896 100644 --- a/ports/analog/common-hal/os/__init__.c +++ b/ports/analog/common-hal/os/__init__.c @@ -15,9 +15,14 @@ // #include "peripherals/periph.h" +// true random number generator, TRNG +#include "trng.h" + bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { #if (HAS_TRNG) - // todo (low prior): implement + // get a random number of "length" number of bytes + MXC_TRNG_Random(buffer, length); + return true; #else #endif return false; diff --git a/ports/analog/mpconfigport.mk b/ports/analog/mpconfigport.mk index 1729a284a3f47..221730106d269 100644 --- a/ports/analog/mpconfigport.mk +++ b/ports/analog/mpconfigport.mk @@ -51,7 +51,7 @@ CIRCUITPY_BITBANGIO ?= 1 # Requires Microcontroller CIRCUITPY_TOUCHIO ?= 1 # Requires OS -CIRCUITPY_RANDOM ?= 0 +CIRCUITPY_RANDOM ?= 1 # Requires busio.UART CIRCUITPY_CONSOLE_UART ?= 0 # Does nothing without I2C diff --git a/ports/analog/supervisor/port.c b/ports/analog/supervisor/port.c index ad003c12ed9e0..ff05ff2d28709 100644 --- a/ports/analog/supervisor/port.c +++ b/ports/analog/supervisor/port.c @@ -44,6 +44,9 @@ #include "mxc_delay.h" #include "rtc.h" +// true random number generator, TRNG +#include "trng.h" + // msec to RTC subsec ticks (4 kHz) /* Converts a time in milleseconds to equivalent RSSA register value */ #define MSEC_TO_SS_ALARM(x) (0 - ((x * 4096) / 1000)) @@ -112,9 +115,18 @@ safe_mode_t port_init(void) { } ; + // enable TRNG (true random number generator) + #ifdef CIRCUITPY_RANDOM + MXC_TRNG_Init(); + #endif + return SAFE_MODE_NONE; } +void TRNG_IRQHandler(void) { + MXC_TRNG_Handler(); +} + void RTC_IRQHandler(void) { // Read flags to clear int flags = MXC_RTC_GetFlags(); From 06f1ac33e02657a9fd33ad1b18a47b7be06615fc Mon Sep 17 00:00:00 2001 From: Peggy Date: Tue, 5 Aug 2025 11:34:20 -0700 Subject: [PATCH 043/208] update licenses --- ports/analog/Makefile | 1 + ports/analog/common-hal/os/__init__.c | 1 + ports/analog/mpconfigport.mk | 1 + 3 files changed, 3 insertions(+) diff --git a/ports/analog/Makefile b/ports/analog/Makefile index 0d4d05f136804..ce9082c5e255a 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -2,6 +2,7 @@ # # SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +# SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. # # SPDX-License-Identifier: MIT diff --git a/ports/analog/common-hal/os/__init__.c b/ports/analog/common-hal/os/__init__.c index 04667db8b5896..508b40798e22b 100644 --- a/ports/analog/common-hal/os/__init__.c +++ b/ports/analog/common-hal/os/__init__.c @@ -2,6 +2,7 @@ // // SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries // SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. // // SPDX-License-Identifier: MIT diff --git a/ports/analog/mpconfigport.mk b/ports/analog/mpconfigport.mk index 221730106d269..67f1f79fb8121 100644 --- a/ports/analog/mpconfigport.mk +++ b/ports/analog/mpconfigport.mk @@ -2,6 +2,7 @@ # # SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries # SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +# SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. # # SPDX-License-Identifier: MIT From 2c83897670fdb0208869f09391ce16f351eb39bd Mon Sep 17 00:00:00 2001 From: MAE Date: Tue, 5 Aug 2025 19:39:51 +0200 Subject: [PATCH 044/208] Translated using Weblate (Polish) Currently translated at 52.4% (532 of 1014 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pl/ --- locale/pl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/pl.po b/locale/pl.po index 66bf686097992..2e55f983e0027 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2025-08-03 08:01+0000\n" +"PO-Revision-Date: 2025-08-06 18:01+0000\n" "Last-Translator: MAE \n" "Language-Team: pl\n" "Language: pl\n" @@ -204,7 +204,7 @@ msgstr "" #: py/argcheck.c msgid "%q must be >= %d" -msgstr "" +msgstr "%q musi być >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" From c097441cb8fce14a9b44c1b00525d36d02b0bedd Mon Sep 17 00:00:00 2001 From: CDarius Date: Fri, 8 Aug 2025 16:59:49 +0200 Subject: [PATCH 045/208] Refactor/fix M5Bus pins definitions --- ports/espressif/boards/m5stack_cores3/pins.c | 24 ++++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/ports/espressif/boards/m5stack_cores3/pins.c b/ports/espressif/boards/m5stack_cores3/pins.c index 2ebb225277ded..223a6932c4c05 100644 --- a/ports/espressif/boards/m5stack_cores3/pins.c +++ b/ports/espressif/boards/m5stack_cores3/pins.c @@ -28,7 +28,7 @@ CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - // M5 Bus (except I2S & PORT B) + // M5 Bus (except I2S) { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, @@ -36,33 +36,37 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_PORTC_RX), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_A18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_PORTC_TX), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, - // Port B - { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, - // I2S { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_ROM_PTR(&pin_GPIO33) }, - { MP_ROM_QSTR(MP_QSTR_IS2_DATA), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IS2_DATA_OUT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IS2_DATA_IN), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_IS2_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, // Camera From 7dc07f5830cd2d52824b11adf8648e1de983f4e1 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Fri, 8 Aug 2025 20:50:45 +0000 Subject: [PATCH 046/208] update tinyusb submodule commit This is the latest upstream commit. There were many changes in the past the 3 months since the last submodule update. In particular, there were some fixes for descriptor parsing and better stability when devices are unplugged. See issue #10556. --- lib/tinyusb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tinyusb b/lib/tinyusb index 542e5b4550a01..5fb3c09963bca 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 542e5b4550a01d034b78308d77c408ed89427513 +Subproject commit 5fb3c09963bca362e535788e289d4b3518da5973 From b739a86fd5bcdddaf873470ffa86eab890ac82ca Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 8 Aug 2025 12:02:45 -0700 Subject: [PATCH 047/208] Refactor EPaperDisplay args into struct Claude helped with initial prompt: > Refactor common_hal_epaperdisplay_epaperdisplay_construct so that the current arguments are struct fields and then the function only takes the struct. Also add a macro that initializes it to default values. And one follow up prompt before minor manual cleanup and testing: > Clean up board files by removing settings that match the default. In particular bools that are false should be default, commands with NO_COMMAND and highlight color as 0. For issue #10528 --- ports/atmel-samd/boards/openbook_m4/board.c | 54 +++----- .../adafruit_magtag_2.9_grayscale/board.c | 115 +++++++--------- .../elecrow_crowpanel_4_2_epaper/board.c | 57 ++++---- .../boards/heltec_vision_master_e290/board.c | 64 +++++---- .../boards/heltec_wireless_paper/board.c | 56 +++----- ports/espressif/boards/sqfmi_watchy/board.c | 62 ++++----- .../bradanlanestudio_explorer_rp2040/board.c | 123 ++++++++---------- .../boards/pimoroni_badger2040/board.c | 55 +++----- .../boards/pimoroni_badger2040w/board.c | 55 +++----- .../boards/pimoroni_inky_frame_5_7/board.c | 54 +++----- .../boards/pimoroni_inky_frame_7_3/board.c | 55 +++----- shared-bindings/epaperdisplay/EPaperDisplay.c | 51 ++++++-- shared-bindings/epaperdisplay/EPaperDisplay.h | 89 +++++++++++-- shared-module/epaperdisplay/EPaperDisplay.c | 81 +++++------- 14 files changed, 452 insertions(+), 519 deletions(-) diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 95027e817e8b8..fb75cac3a4ee7 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -53,42 +53,24 @@ void board_init(void) { epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct(display, - bus, - start_sequence, - sizeof(start_sequence), - 0, // start up time - stop_sequence, - sizeof(stop_sequence), - 300, // width - 400, // height - 300, // RAM width - 400, // RAM height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x13, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually) - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, // refresh_display_sequence - sizeof(refresh_sequence), - 40, // refresh_time - &pin_PA01, // busy_pin - false, // busy_state - 5, // seconds_per_frame - false, // chip_select (don't always toggle chip select) - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = start_sequence; + args.start_sequence_len = sizeof(start_sequence); + args.stop_sequence = stop_sequence; + args.stop_sequence_len = sizeof(stop_sequence); + args.width = 300; + args.height = 400; + args.ram_width = 300; + args.ram_height = 400; + args.rotation = 270; + args.write_black_ram_command = 0x13; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 40.0; + args.busy_pin = &pin_PA01; + args.seconds_per_frame = 5.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c index c4311474f6061..d37233b7f2420 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -217,75 +217,54 @@ void board_init(void) { display->base.type = &epaperdisplay_epaperdisplay_type; if (is_ssd1680) { - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - ssd1680_display_start_sequence, sizeof(ssd1680_display_start_sequence), - 0, // start up time - ssd1680_display_stop_sequence, sizeof(ssd1680_display_stop_sequence), - 296, // width - 128, // height - 250, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - 0x44, // set_column_window_command - 0x45, // set_row_window_command - 0x4e, // set_current_column_command - 0x4f, // set_current_row_command - 0x24, // write_black_ram_command - false, // black_bits_inverted - 0x26, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - ssd1680_display_refresh_sequence, sizeof(ssd1680_display_refresh_sequence), - 1.0, // refresh_time - &pin_GPIO5, // busy_pin - true, // busy_state - 5.0, // seconds_per_frame - false, // always_toggle_chip_select - true, // grayscale - false, // acep - false, // spectra6 - true, // two_byte_sequence_length - true); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = ssd1680_display_start_sequence; + args.start_sequence_len = sizeof(ssd1680_display_start_sequence); + args.stop_sequence = ssd1680_display_stop_sequence; + args.stop_sequence_len = sizeof(ssd1680_display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 250; + args.ram_height = 296; + args.rotation = 270; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4e; + args.set_current_row_command = 0x4f; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.refresh_sequence = ssd1680_display_refresh_sequence; + args.refresh_sequence_len = sizeof(ssd1680_display_refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO5; + args.busy_state = true; + args.seconds_per_frame = 5.0; + args.grayscale = true; + args.two_byte_sequence_length = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } else { - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - il0373_display_start_sequence, sizeof(il0373_display_start_sequence), - 0, // start up time - il0373_display_stop_sequence, sizeof(il0373_display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - 0x13, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - il0373_display_refresh_sequence, sizeof(il0373_display_refresh_sequence), - 1.0, // refresh_time - &pin_GPIO5, // busy_pin - false, // busy_state - 5.0, // seconds_per_frame - false, // always_toggle_chip_select - true, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = il0373_display_start_sequence; + args.start_sequence_len = sizeof(il0373_display_start_sequence); + args.stop_sequence = il0373_display_stop_sequence; + args.stop_sequence_len = sizeof(il0373_display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = 0x10; + args.write_color_ram_command = 0x13; + args.refresh_sequence = il0373_display_refresh_sequence; + args.refresh_sequence_len = sizeof(il0373_display_refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO5; + args.seconds_per_frame = 5.0; + args.grayscale = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } } diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c index b7f8bc50e714a..04f5f92f85ba9 100644 --- a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c @@ -63,43 +63,30 @@ void board_init(void) { 0, // Polarity 0); // Phase -// Set up the DisplayIO epaper object + // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 1, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 400, // width - 300, // height - 400, // ram_width - 300, // ram_height - 0, // colstart - 0, // rowstart - 0, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x24, // write_black_ram_command - false, // black_bits_inverted - 0x26, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO48, // busy_pin - true, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 400; + args.height = 300; + args.ram_width = 400; + args.ram_height = 300; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO48; + args.busy_state = true; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/espressif/boards/heltec_vision_master_e290/board.c b/ports/espressif/boards/heltec_vision_master_e290/board.c index 5911506ae2c3c..9749f5c704881 100644 --- a/ports/espressif/boards/heltec_vision_master_e290/board.c +++ b/ports/espressif/boards/heltec_vision_master_e290/board.c @@ -61,43 +61,37 @@ void board_init(void) { 0, // Polarity 0); // Phase -// Set up the DisplayIO epaper object + // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 250, // ram_width - 296, // ram_height - 8, // colstart - 0, // rowstart - 90, // rotation - 0x44, // set_column_window_command - 0x45, // set_row_window_command - 0x4E, // set_current_column_command - 0x4F, // set_current_row_command - 0x24, // write_black_ram_command - false, // black_bits_inverted - 0x26, // write_color_ram_command - false, // color_bits_inverted - 0xFF0000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO6, // busy_pin - true, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - true); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 250; + args.ram_height = 296; + args.colstart = 8; + args.rotation = 90; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4E; + args.set_current_row_command = 0x4F; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.highlight_color = 0xFF0000; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO6; + args.busy_state = true; + args.seconds_per_frame = 2.0; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/espressif/boards/heltec_wireless_paper/board.c b/ports/espressif/boards/heltec_wireless_paper/board.c index 89e7a054b50c2..c796a9be8843d 100644 --- a/ports/espressif/boards/heltec_wireless_paper/board.c +++ b/ports/espressif/boards/heltec_wireless_paper/board.c @@ -101,43 +101,29 @@ void board_init(void) { 0, // Polarity 0); // Phase -// Set up the DisplayIO epaper object + // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 250, // width - 122, // height - 128, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x13, // write_black_ram_command - false, // black_bits_inverted - 0x10, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO7, // busy_pin - false, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 250; + args.height = 122; + args.ram_width = 128; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = 0x13; + args.write_color_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO7; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/espressif/boards/sqfmi_watchy/board.c b/ports/espressif/boards/sqfmi_watchy/board.c index 535a3e11006fe..297190b53e200 100644 --- a/ports/espressif/boards/sqfmi_watchy/board.c +++ b/ports/espressif/boards/sqfmi_watchy/board.c @@ -160,41 +160,33 @@ void board_init(void) { epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - (double)0.01, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 200, // width - 200, // height - 200, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 0, // rotation - 0x44, // set_column_window_command - 0x45, // set_row_window_command - 0x4E, // set_current_column_command - 0x4F, // set_current_row_command - 0x24, // write_black_ram_command - true, // black_bits_inverted - 0x26, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), - (double)1.0, // refresh_time - &pin_GPIO19, // busy_pin - true, // busy_state - (double)5.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - true // address_little_endian - ); + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 0.01; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 200; + args.height = 200; + args.ram_width = 200; + args.ram_height = 296; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4E; + args.set_current_row_command = 0x4F; + args.write_black_ram_command = 0x24; + args.black_bits_inverted = true; + args.write_color_ram_command = 0x26; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO19; + args.busy_state = true; + args.seconds_per_frame = 5.0; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } bool board_requests_safe_mode(void) { diff --git a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c index b7e75a475fd09..35e128627bc0b 100644 --- a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c +++ b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c @@ -251,75 +251,62 @@ void board_init(void) { if ((vid_setting == 1) || // DCNextGen SSD1681 BWR rotated 270 (vid_setting == 3) || // Explorer SSD1681 BW rotated 0 (vid_setting == 4)) { // Explorer SSD1681 BWR rotated 0 - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - _start_sequence_ssd1681, sizeof(_start_sequence_ssd1681), - 1.0, // start up time - _stop_sequence_ssd1681, sizeof(_stop_sequence_ssd1681), - WIDTH, // width - HEIGHT, // height - WIDTH, // ram_width - HEIGHT + 0x60, // ram_height RAM is actually only 200 bits high but we use 296 to match the 9 bits - 0, // colstart - 0, // rowstart - rotation, // rotation - SSD_SET_RAMXPOS, // set_column_window_command - SSD_SET_RAMYPOS, // set_row_window_command - SSD_SET_RAMXCOUNT, // set_current_column_command - SSD_SET_RAMYCOUNT, // set_current_row_command - SSD_WRITE_RAM_BLK, // write_black_ram_command - false, // black_bits_inverted - SSD_WRITE_RAM_RED, // write_color_ram_command - false, // color_bits_inverted - 0xFF0000, // highlight_color (RED for tri-color display) - 0x000000, // highlight_color2 - _refresh_sequence_ssd1681, sizeof(_refresh_sequence_ssd1681), // refresh_display_command - refresh_time, // refresh_time - &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin - true, // busy_state - seconds_per_frame, // seconds_per_frame (does not seem the user can change this) - true, // always_toggle_chip_select - false, // not grayscale - false, // not acep - false, // not spectra6 - false, // not two_byte_sequence_length - true); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = _start_sequence_ssd1681; + args.start_sequence_len = sizeof(_start_sequence_ssd1681); + args.start_up_time = 1.0; + args.stop_sequence = _stop_sequence_ssd1681; + args.stop_sequence_len = sizeof(_stop_sequence_ssd1681); + args.width = WIDTH; + args.height = HEIGHT; + args.ram_width = WIDTH; + args.ram_height = HEIGHT + 0x60; + args.rotation = rotation; + args.set_column_window_command = SSD_SET_RAMXPOS; + args.set_row_window_command = SSD_SET_RAMYPOS; + args.set_current_column_command = SSD_SET_RAMXCOUNT; + args.set_current_row_command = SSD_SET_RAMYCOUNT; + args.write_black_ram_command = SSD_WRITE_RAM_BLK; + args.write_color_ram_command = SSD_WRITE_RAM_RED; + args.highlight_color = 0xFF0000; + args.refresh_sequence = _refresh_sequence_ssd1681; + args.refresh_sequence_len = sizeof(_refresh_sequence_ssd1681); + args.refresh_time = refresh_time; + args.busy_pin = &pin_GPIO9; + args.busy_state = true; + args.seconds_per_frame = seconds_per_frame; + args.always_toggle_chip_select = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } else if (vid_setting == 2) { // Explorer SSD1608 BW - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - _start_sequence_ssd1608, sizeof(_start_sequence_ssd1608), - 1.0, // start up time - _stop_sequence_ssd1608, sizeof(_stop_sequence_ssd1608), - WIDTH, // width - HEIGHT, // height - WIDTH, // ram_width - HEIGHT /* + 0x60 */, // ram_height RAM is actually only 200 bits high but we use 296 to match the 9 bits - 0, // colstart - 0, // rowstart - rotation, // rotation - SSD_SET_RAMXPOS, // set_column_window_command - SSD_SET_RAMYPOS, // set_row_window_command - SSD_SET_RAMXCOUNT, // set_current_column_command - SSD_SET_RAMYCOUNT, // set_current_row_command - SSD_WRITE_RAM_BLK, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color (RED for tri-color display) - 0x000000, // highlight_color2 - _refresh_sequence_ssd1608, sizeof(_refresh_sequence_ssd1608), // refresh_display_command - refresh_time, // refresh_time - &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin - true, // busy_state - seconds_per_frame, // seconds_per_frame (does not seem the user can change this) - true, // always_toggle_chip_select - false, // not grayscale - false, // not acep - false, // not spectra6 - false, // not two_byte_sequence_length - true); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = _start_sequence_ssd1608; + args.start_sequence_len = sizeof(_start_sequence_ssd1608); + args.start_up_time = 1.0; + args.stop_sequence = _stop_sequence_ssd1608; + args.stop_sequence_len = sizeof(_stop_sequence_ssd1608); + args.width = WIDTH; + args.height = HEIGHT; + args.ram_width = WIDTH; + args.ram_height = HEIGHT; + args.rotation = rotation; + args.set_column_window_command = SSD_SET_RAMXPOS; + args.set_row_window_command = SSD_SET_RAMYPOS; + args.set_current_column_command = SSD_SET_RAMXCOUNT; + args.set_current_row_command = SSD_SET_RAMYCOUNT; + args.write_black_ram_command = SSD_WRITE_RAM_BLK; + args.write_color_ram_command = NO_COMMAND; + args.refresh_sequence = _refresh_sequence_ssd1608; + args.refresh_sequence_len = sizeof(_refresh_sequence_ssd1608); + args.refresh_time = refresh_time; + args.busy_pin = &pin_GPIO9; + args.busy_state = true; + args.seconds_per_frame = seconds_per_frame; + args.always_toggle_chip_select = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } else { // what should happen if this firmware is installed on some other board? // currently, we mark the display as None diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 392a57cdc0c1b..07cc512b9a58e 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -273,40 +273,27 @@ void board_init(void) { // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - DTM2, // write_black_ram_command - true, // black_bits_inverted - DTM1, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO26, // busy_pin - false, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = DTM2; + args.black_bits_inverted = true; + args.write_color_ram_command = DTM1; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO26; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c index 01c448cd7ad52..b992bcd6a1e37 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c @@ -273,40 +273,27 @@ void board_init(void) { // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - DTM2, // write_black_ram_command - true, // black_bits_inverted - DTM1, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO26, // busy_pin - false, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = DTM2; + args.black_bits_inverted = true; + args.write_color_ram_command = DTM1; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO26; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c index c7901b8649d78..4bf7518c6a8df 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c @@ -67,40 +67,26 @@ void board_init(void) { epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 1.0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 600, // width - 448, // height - 640, // ram_width - 480, // ram_height - 0, // colstart - 0, // rowstart - 0, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), - 28.0, // refresh_time - NULL, // busy_pin - false, // busy_state - 40.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - true, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 600; + args.height = 448; + args.ram_width = 640; + args.ram_height = 480; + args.write_black_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 28.0; + args.busy_pin = NULL; + args.seconds_per_frame = 40.0; + args.acep = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c index 764c85ecb6bcf..763a91a255569 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c @@ -126,40 +126,27 @@ void board_init(void) { epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 1.0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 800, // width - 480, // height - 800, // ram_width - 480, // ram_height - 0, // colstart - 0, // rowstart - 180, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - 0x000000, // highlight_color2 - refresh_sequence, sizeof(refresh_sequence), - 28.0, // refresh_time - NULL, // busy_pin - false, // busy_state - 30.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - true, // acep - false, // spectra6 - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 800; + args.height = 480; + args.ram_width = 800; + args.ram_height = 480; + args.rotation = 180; + args.write_black_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 28.0; + args.busy_pin = NULL; + args.seconds_per_frame = 30.0; + args.acep = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.c b/shared-bindings/epaperdisplay/EPaperDisplay.c index 9f261d599ada9..cd9c18e27d526 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.c +++ b/shared-bindings/epaperdisplay/EPaperDisplay.c @@ -211,20 +211,43 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, } self->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - self, - display_bus, - start_bufinfo.buf, start_bufinfo.len, start_up_time, stop_bufinfo.buf, stop_bufinfo.len, - args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int, - args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, - args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int, - args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int, - args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, - args[ARG_color_bits_inverted].u_bool, highlight_color, highlight_color2, refresh_buf, refresh_buf_len, refresh_time, - busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, - args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, args[ARG_spectra6].u_bool, - two_byte_sequence_length, args[ARG_address_little_endian].u_bool - ); + epaperdisplay_construct_args_t construct_args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + construct_args.bus = display_bus; + construct_args.start_sequence = start_bufinfo.buf; + construct_args.start_sequence_len = start_bufinfo.len; + construct_args.start_up_time = start_up_time; + construct_args.stop_sequence = stop_bufinfo.buf; + construct_args.stop_sequence_len = stop_bufinfo.len; + construct_args.width = args[ARG_width].u_int; + construct_args.height = args[ARG_height].u_int; + construct_args.ram_width = args[ARG_ram_width].u_int; + construct_args.ram_height = args[ARG_ram_height].u_int; + construct_args.colstart = args[ARG_colstart].u_int; + construct_args.rowstart = args[ARG_rowstart].u_int; + construct_args.rotation = rotation; + construct_args.set_column_window_command = args[ARG_set_column_window_command].u_int; + construct_args.set_row_window_command = args[ARG_set_row_window_command].u_int; + construct_args.set_current_column_command = args[ARG_set_current_column_command].u_int; + construct_args.set_current_row_command = args[ARG_set_current_row_command].u_int; + construct_args.write_black_ram_command = args[ARG_write_black_ram_command].u_int; + construct_args.black_bits_inverted = args[ARG_black_bits_inverted].u_bool; + construct_args.write_color_ram_command = write_color_ram_command; + construct_args.color_bits_inverted = args[ARG_color_bits_inverted].u_bool; + construct_args.highlight_color = highlight_color; + construct_args.highlight_color2 = highlight_color2; + construct_args.refresh_sequence = refresh_buf; + construct_args.refresh_sequence_len = refresh_buf_len; + construct_args.refresh_time = refresh_time; + construct_args.busy_pin = busy_pin; + construct_args.busy_state = args[ARG_busy_state].u_bool; + construct_args.seconds_per_frame = seconds_per_frame; + construct_args.always_toggle_chip_select = args[ARG_always_toggle_chip_select].u_bool; + construct_args.grayscale = args[ARG_grayscale].u_bool; + construct_args.acep = args[ARG_advanced_color_epaper].u_bool; + construct_args.spectra6 = args[ARG_spectra6].u_bool; + construct_args.two_byte_sequence_length = two_byte_sequence_length; + construct_args.address_little_endian = args[ARG_address_little_endian].u_bool; + common_hal_epaperdisplay_epaperdisplay_construct(self, &construct_args); return self; } diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.h b/shared-bindings/epaperdisplay/EPaperDisplay.h index afa90a514e2a5..83f0b0377fe6c 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.h +++ b/shared-bindings/epaperdisplay/EPaperDisplay.h @@ -15,19 +15,84 @@ extern const mp_obj_type_t epaperdisplay_epaperdisplay_type; #define NO_COMMAND 0x100 +typedef struct { + mp_obj_t bus; + const uint8_t *start_sequence; + uint16_t start_sequence_len; + mp_float_t start_up_time; + const uint8_t *stop_sequence; + uint16_t stop_sequence_len; + uint16_t width; + uint16_t height; + uint16_t ram_width; + uint16_t ram_height; + int16_t colstart; + int16_t rowstart; + uint16_t rotation; + uint16_t set_column_window_command; + uint16_t set_row_window_command; + uint16_t set_current_column_command; + uint16_t set_current_row_command; + uint16_t write_black_ram_command; + bool black_bits_inverted; + uint16_t write_color_ram_command; + bool color_bits_inverted; + uint32_t highlight_color; + uint32_t highlight_color2; + const uint8_t *refresh_sequence; + uint16_t refresh_sequence_len; + mp_float_t refresh_time; + const mcu_pin_obj_t *busy_pin; + bool busy_state; + mp_float_t seconds_per_frame; + bool always_toggle_chip_select; + bool grayscale; + bool acep; + bool spectra6; + bool two_byte_sequence_length; + bool address_little_endian; +} epaperdisplay_construct_args_t; + +#define EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS { \ + .bus = mp_const_none, \ + .start_sequence = NULL, \ + .start_sequence_len = 0, \ + .start_up_time = 0.0, \ + .stop_sequence = NULL, \ + .stop_sequence_len = 0, \ + .width = 0, \ + .height = 0, \ + .ram_width = 0, \ + .ram_height = 0, \ + .colstart = 0, \ + .rowstart = 0, \ + .rotation = 0, \ + .set_column_window_command = NO_COMMAND, \ + .set_row_window_command = NO_COMMAND, \ + .set_current_column_command = NO_COMMAND, \ + .set_current_row_command = NO_COMMAND, \ + .write_black_ram_command = NO_COMMAND, \ + .black_bits_inverted = false, \ + .write_color_ram_command = NO_COMMAND, \ + .color_bits_inverted = false, \ + .highlight_color = 0x000000, \ + .highlight_color2 = 0x000000, \ + .refresh_sequence = NULL, \ + .refresh_sequence_len = 0, \ + .refresh_time = 0.0, \ + .busy_pin = NULL, \ + .busy_state = false, \ + .seconds_per_frame = 0.0, \ + .always_toggle_chip_select = false, \ + .grayscale = false, \ + .acep = false, \ + .spectra6 = false, \ + .two_byte_sequence_length = false, \ + .address_little_endian = false \ +} + void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, - const uint8_t *stop_sequence, uint16_t stop_sequence_len, - uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, - int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t set_column_window_command, uint16_t set_row_window_command, - uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2, - const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, - bool always_toggle_chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, - bool address_little_endian); + const epaperdisplay_construct_args_t *args); bool common_hal_epaperdisplay_epaperdisplay_refresh(epaperdisplay_epaperdisplay_obj_t *self); diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index e1f0a07f467ee..556db6ae22002 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -26,82 +26,73 @@ #define DELAY 0x80 void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, - const uint8_t *stop_sequence, uint16_t stop_sequence_len, - uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, - int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t set_column_window_command, uint16_t set_row_window_command, - uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint32_t highlight_color2, - const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, - bool chip_select, bool grayscale, bool acep, bool spectra6, bool two_byte_sequence_length, bool address_little_endian) { + const epaperdisplay_construct_args_t *args) { uint16_t color_depth = 1; bool core_grayscale = true; - if (highlight_color != 0x000000) { + if (args->highlight_color != 0x000000) { self->core.colorspace.tricolor = true; - self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); + self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(args->highlight_color); } else { self->core.colorspace.tricolor = false; } - if (highlight_color != 0x000000 && highlight_color2 != 0x000000) { + if (args->highlight_color != 0x000000 && args->highlight_color2 != 0x000000) { self->core.colorspace.tricolor = false; self->core.colorspace.fourcolor = true; - self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(highlight_color2); + self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(args->highlight_color2); } else { self->core.colorspace.fourcolor = false; } - self->acep = acep || spectra6; - self->core.colorspace.sixcolor = spectra6; - self->core.colorspace.sevencolor = acep; + self->acep = args->acep || args->spectra6; + self->core.colorspace.sixcolor = args->spectra6; + self->core.colorspace.sevencolor = args->acep; + bool grayscale = args->grayscale; if (self->acep) { color_depth = 4; // bits. 7 colors + clean grayscale = false; core_grayscale = false; } - if ((highlight_color != 0x000000 || highlight_color2 != 0x000000) && write_color_ram_command == NO_COMMAND) { + if ((args->highlight_color != 0x000000 || args->highlight_color2 != 0x000000) && args->write_color_ram_command == NO_COMMAND) { color_depth = 2; core_grayscale = false; grayscale = false; } - displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true); - displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height, - colstart, rowstart, - set_column_window_command, set_row_window_command, set_current_column_command, set_current_row_command, - false /* data_as_commands */, chip_select, - false /* SH1107_addressing */, address_little_endian); + displayio_display_core_construct(&self->core, args->width, args->height, args->rotation, color_depth, core_grayscale, true, 1, true, true); + displayio_display_bus_construct(&self->bus, args->bus, args->ram_width, args->ram_height, + args->colstart, args->rowstart, + args->set_column_window_command, args->set_row_window_command, args->set_current_column_command, args->set_current_row_command, + false /* data_as_commands */, args->always_toggle_chip_select, + false /* SH1107_addressing */, args->address_little_endian); - self->write_black_ram_command = write_black_ram_command; - self->black_bits_inverted = black_bits_inverted; - self->write_color_ram_command = write_color_ram_command; - self->color_bits_inverted = color_bits_inverted; - self->refresh_time = refresh_time * 1000; - self->busy_state = busy_state; + self->write_black_ram_command = args->write_black_ram_command; + self->black_bits_inverted = args->black_bits_inverted; + self->write_color_ram_command = args->write_color_ram_command; + self->color_bits_inverted = args->color_bits_inverted; + self->refresh_time = args->refresh_time * 1000; + self->busy_state = args->busy_state; self->refreshing = false; - self->milliseconds_per_frame = seconds_per_frame * 1000; - self->chip_select = chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED; + self->milliseconds_per_frame = args->seconds_per_frame * 1000; + self->chip_select = args->always_toggle_chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED; self->grayscale = grayscale; - self->start_sequence = start_sequence; - self->start_sequence_len = start_sequence_len; - self->start_up_time_ms = start_up_time * 1000; - self->stop_sequence = stop_sequence; - self->stop_sequence_len = stop_sequence_len; - self->refresh_sequence = refresh_sequence; - self->refresh_sequence_len = refresh_sequence_len; + self->start_sequence = args->start_sequence; + self->start_sequence_len = args->start_sequence_len; + self->start_up_time_ms = args->start_up_time * 1000; + self->stop_sequence = args->stop_sequence; + self->stop_sequence_len = args->stop_sequence_len; + self->refresh_sequence = args->refresh_sequence; + self->refresh_sequence_len = args->refresh_sequence_len; self->busy.base.type = &mp_type_NoneType; - self->two_byte_sequence_length = two_byte_sequence_length; - if (busy_pin != NULL) { + self->two_byte_sequence_length = args->two_byte_sequence_length; + if (args->busy_pin != NULL) { self->busy.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin); - common_hal_never_reset_pin(busy_pin); + common_hal_digitalio_digitalinout_construct(&self->busy, args->busy_pin); + common_hal_never_reset_pin(args->busy_pin); } // Clear the color memory if it isn't in use. - if (highlight_color == 0x00 && highlight_color2 == 0x00 && write_color_ram_command != NO_COMMAND) { + if (args->highlight_color == 0x00 && args->highlight_color2 == 0x00 && args->write_color_ram_command != NO_COMMAND) { // TODO: Clear } From d7b467fd2df9809d96710bce1644c829a3db390d Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Tue, 12 Aug 2025 04:36:44 +0000 Subject: [PATCH 048/208] Update Pico-PIO-USB to latest (0.7.2) (as suggested by tannewt in issue #10556) --- ports/raspberrypi/lib/Pico-PIO-USB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/raspberrypi/lib/Pico-PIO-USB b/ports/raspberrypi/lib/Pico-PIO-USB index 032a469e79f6a..675543bcc9baa 160000 --- a/ports/raspberrypi/lib/Pico-PIO-USB +++ b/ports/raspberrypi/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit 032a469e79f6a4ba40760d7868e6db26e15002d7 +Subproject commit 675543bcc9baa8170f868ab7ba316d418dbcf41f From 592d3f705eb7c525dc963d8a891ed8b26d3675d4 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Tue, 12 Aug 2025 04:48:20 +0000 Subject: [PATCH 049/208] Turn off SAMD21 options to reduce image size As suggested by tannewt in PR #10559, this turns off codeop for Feather M0 and errno for the Metro M0 and Redboard Turbo. This is trying to free up enough space to fit the latest TinyUSB and Pico-PIO-USB submodule updates. --- ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk | 1 + ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk | 1 + ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk | 1 + 3 files changed, 3 insertions(+) diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index 004181148415a..783e2cb565783 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -10,4 +10,5 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY_CODEOP = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index d758d6878fb7f..d4801359cf8c5 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -11,4 +11,5 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index 64049e8d5981c..b34dfb3d2e624 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -11,4 +11,5 @@ EXTERNAL_FLASH_DEVICES = "W25Q32FV" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 From c3e38623758cf53f2755d7011a285da15c5c4c09 Mon Sep 17 00:00:00 2001 From: CDarius Date: Tue, 12 Aug 2025 12:06:00 +0200 Subject: [PATCH 050/208] Fixed I2S spelling and separated pin aliases --- ports/espressif/boards/m5stack_cores3/pins.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ports/espressif/boards/m5stack_cores3/pins.c b/ports/espressif/boards/m5stack_cores3/pins.c index 223a6932c4c05..8b40d9e84842a 100644 --- a/ports/espressif/boards/m5stack_cores3/pins.c +++ b/ports/espressif/boards/m5stack_cores3/pins.c @@ -32,42 +32,55 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_RX), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_A18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_TX), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO1) }, { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, // I2S { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_ROM_PTR(&pin_GPIO33) }, - { MP_ROM_QSTR(MP_QSTR_IS2_DATA_OUT), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IS2_DATA_IN), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_IS2_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_OUT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_IN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, // Camera { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, From 57c9797b3f32f521ea2dc22dd498fc73e336b7a5 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Tue, 12 Aug 2025 09:17:03 -0500 Subject: [PATCH 051/208] Add tempo property --- shared-bindings/synthio/MidiTrack.c | 22 ++++++++++++++++++++++ shared-bindings/synthio/MidiTrack.h | 3 +++ shared-module/synthio/MidiTrack.c | 9 +++++++++ 3 files changed, 34 insertions(+) diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c index 9add8f1745c83..db75a543c613d 100644 --- a/shared-bindings/synthio/MidiTrack.c +++ b/shared-bindings/synthio/MidiTrack.c @@ -115,6 +115,27 @@ static void check_for_deinit(synthio_miditrack_obj_t *self) { //| """32 bit value that tells how quickly samples are played in Hertz (cycles per second).""" //| +//| tempo: int +//| """Tempo of the streamed events, in MIDI ticks per second.""" +//| +static mp_obj_t synthio_miditrack_obj_get_tempo(mp_obj_t self_in) { + synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_int(common_hal_synthio_miditrack_get_tempo(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_get_tempo_obj, synthio_miditrack_obj_get_tempo); + +static mp_obj_t synthio_miditrack_obj_set_tempo(mp_obj_t self_in, mp_obj_t arg) { + synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_synthio_miditrack_set_tempo(self, mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(synthio_miditrack_set_tempo_obj, synthio_miditrack_obj_set_tempo); +MP_PROPERTY_GETSET(synthio_miditrack_tempo_obj, + (mp_obj_t)&synthio_miditrack_get_tempo_obj, + (mp_obj_t)&synthio_miditrack_set_tempo_obj); + //| error_location: Optional[int] //| """Offset, in bytes within the midi data, of a decoding error""" //| @@ -141,6 +162,7 @@ static const mp_rom_map_elem_t synthio_miditrack_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_error_location), MP_ROM_PTR(&synthio_miditrack_error_location_obj) }, + { MP_ROM_QSTR(MP_QSTR_tempo), MP_ROM_PTR(&synthio_miditrack_tempo_obj) }, AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(synthio_miditrack_locals_dict, synthio_miditrack_locals_dict_table); diff --git a/shared-bindings/synthio/MidiTrack.h b/shared-bindings/synthio/MidiTrack.h index 72b217e9613b1..cb154d3996b1a 100644 --- a/shared-bindings/synthio/MidiTrack.h +++ b/shared-bindings/synthio/MidiTrack.h @@ -15,3 +15,6 @@ void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, const void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self); mp_int_t common_hal_synthio_miditrack_get_error_location(synthio_miditrack_obj_t *self); + +mp_int_t common_hal_synthio_miditrack_get_tempo(synthio_miditrack_obj_t *self); +void common_hal_synthio_miditrack_set_tempo(synthio_miditrack_obj_t *self, mp_int_t value); diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c index 94430289bda10..df8e5bdbea1b2 100644 --- a/shared-module/synthio/MidiTrack.c +++ b/shared-module/synthio/MidiTrack.c @@ -116,6 +116,15 @@ mp_int_t common_hal_synthio_miditrack_get_error_location(synthio_miditrack_obj_t return self->error_location; } +mp_int_t common_hal_synthio_miditrack_get_tempo(synthio_miditrack_obj_t *self) { + return self->tempo; +} + +void common_hal_synthio_miditrack_set_tempo(synthio_miditrack_obj_t *self, mp_int_t value) { + mp_int_t val = mp_arg_validate_int_min(value, 1, MP_QSTR_tempo); + self->tempo = val; +} + void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, bool single_channel_output, uint8_t channel) { synthio_synth_reset_buffer(&self->synth, single_channel_output, channel); From d2867b4607f582e151e5e4acd3446fda7c1ad5fd Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 19 Aug 2025 13:58:15 -0500 Subject: [PATCH 052/208] update frozen libraries --- frozen/Adafruit_CircuitPython_FakeRequests | 2 +- frozen/Adafruit_CircuitPython_HTTPServer | 2 +- frozen/Adafruit_CircuitPython_LED_Animation | 2 +- frozen/Adafruit_CircuitPython_PortalBase | 2 +- frozen/Adafruit_CircuitPython_SSD1680 | 2 +- frozen/Adafruit_CircuitPython_UC8151D | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frozen/Adafruit_CircuitPython_FakeRequests b/frozen/Adafruit_CircuitPython_FakeRequests index aa034280ebfed..020121e90c630 160000 --- a/frozen/Adafruit_CircuitPython_FakeRequests +++ b/frozen/Adafruit_CircuitPython_FakeRequests @@ -1 +1 @@ -Subproject commit aa034280ebfed80c245827ff1d49a098ace64b03 +Subproject commit 020121e90c6306147f91b8079b75f3d14ff86138 diff --git a/frozen/Adafruit_CircuitPython_HTTPServer b/frozen/Adafruit_CircuitPython_HTTPServer index b70106b17bbfa..c43147a016ffd 160000 --- a/frozen/Adafruit_CircuitPython_HTTPServer +++ b/frozen/Adafruit_CircuitPython_HTTPServer @@ -1 +1 @@ -Subproject commit b70106b17bbfa0070f8573e1e06e384d9d4577de +Subproject commit c43147a016ffd13c57a0923730bc6a83afefb4ad diff --git a/frozen/Adafruit_CircuitPython_LED_Animation b/frozen/Adafruit_CircuitPython_LED_Animation index 5d13d0966a775..8af05705962e8 160000 --- a/frozen/Adafruit_CircuitPython_LED_Animation +++ b/frozen/Adafruit_CircuitPython_LED_Animation @@ -1 +1 @@ -Subproject commit 5d13d0966a775369eca5b137cfef9583dfa8bb42 +Subproject commit 8af05705962e8bb7d2f8003e6a70916a9a51b863 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index 3dce5bca3bcd2..c87f120723e9f 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit 3dce5bca3bcd27354becc6d3ecf82244f1e26ffe +Subproject commit c87f120723e9fa742e3da25eaf33f3be1ae33715 diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 index b7d511711c8f5..d6aa01c4f8fa1 160000 --- a/frozen/Adafruit_CircuitPython_SSD1680 +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -1 +1 @@ -Subproject commit b7d511711c8f5557082d9c4307a89ecdec608727 +Subproject commit d6aa01c4f8fa1004430bfcdd4db2219183425693 diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D index 776b932ebf769..4ebf9c2854376 160000 --- a/frozen/Adafruit_CircuitPython_UC8151D +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -1 +1 @@ -Subproject commit 776b932ebf76937e464ab2656834e7a1c1e3434b +Subproject commit 4ebf9c2854376a06766a6ae4732a4537a766fb75 From e0f51355b3f353b3361470ec7b86515b17b5e977 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 20 Aug 2025 11:02:16 -0400 Subject: [PATCH 053/208] allow HID usage of zero; at least one device does this --- shared-bindings/usb_hid/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 7c9c354e4de10..a4a0e8680e531 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -98,7 +98,7 @@ static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args const uint16_t usage_page = usage_page_arg; const mp_int_t usage_arg = args[ARG_usage].u_int; - mp_arg_validate_int_range(usage_arg, 1, 0xFFFF, MP_QSTR_usage); + mp_arg_validate_int_range(usage_arg, 0, 0xFFFF, MP_QSTR_usage); const uint16_t usage = usage_arg; mp_obj_t report_ids = args[ARG_report_ids].u_obj; From 525d18541c0a01374dfe82c0bd39c917098d177b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 21 Aug 2025 19:14:21 -0400 Subject: [PATCH 054/208] espressif/mpconfigport.mk: make more readable; restore audio on espressif boards --- ports/espressif/mpconfigport.mk | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index f05df8c07c87a..42bf3418f9639 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -61,7 +61,7 @@ CIRCUITPY_ALARM_TOUCH ?= 0 CIRCUITPY_ANALOGBUFIO ?= 1 CIRCUITPY_AUDIOBUSIO ?= 1 CIRCUITPY_AUDIOBUSIO_PDMIN ?= 0 -CIRCUITPY_AUDIOIO ?= 0 +CIRCUITPY_AUDIOIO ?= 1 CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BLEIO_NATIVE ?= 1 CIRCUITPY_CANIO ?= 1 @@ -89,11 +89,11 @@ CIRCUITPY_WATCHDOG ?= 1 CIRCUITPY_WIFI ?= 1 CIRCUITPY_SOCKETPOOL_IPV6 ?= 1 -# Conditionally turn off modules/features +# Conditionally turn off modules/features per chip type +#### esp32 ############################################################ ifeq ($(IDF_TARGET),esp32) # Modules CIRCUITPY_ALARM_TOUCH = 1 -CIRCUITPY_AUDIOIO ?= 1 CIRCUITPY_RGBMATRIX = 0 # SDMMC not supported yet @@ -102,6 +102,7 @@ CIRCUITPY_SDIOIO = 0 # Has no USB CIRCUITPY_USB_DEVICE = 0 +#### esp32c2 ########################################################## else ifeq ($(IDF_TARGET),esp32c2) # C2 ROM spits out the UART at 74880 when connected to a 26mhz crystal! @@ -128,6 +129,9 @@ CIRCUITPY_ANALOGBUFIO = 0 # No I2S CIRCUITPY_AUDIOBUSIO = 0 +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No RMT CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_PULSEIO = 0 @@ -142,6 +146,7 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0 CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 +#### esp32c3 ########################################################## else ifeq ($(IDF_TARGET),esp32c3) # Modules CIRCUITPY_ESPCAMERA = 0 @@ -151,6 +156,9 @@ CIRCUITPY_MEMORYMAP = 0 # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No PCNT peripheral CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_COUNTIO = 0 @@ -165,6 +173,7 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0 CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 +#### esp32c6 ########################################################## else ifeq ($(IDF_TARGET),esp32c6) # Modules CIRCUITPY_ESPCAMERA = 0 @@ -172,6 +181,9 @@ CIRCUITPY_ESPULP = 0 CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_RGBMATRIX = 0 +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No space for this CIRCUITPY_AUDIOBUSIO = 0 @@ -187,6 +199,7 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0 CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 +#### esp32h2 ########################################################## else ifeq ($(IDF_TARGET),esp32h2) # Modules CIRCUITPY_ESPCAMERA = 0 @@ -194,6 +207,9 @@ CIRCUITPY_ESPULP = 0 CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_RGBMATRIX = 0 +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 @@ -210,8 +226,12 @@ CIRCUITPY_WIFI = 0 CIRCUITPY_MAX3421E = 0 +#### esp32p4 ########################################################## else ifeq ($(IDF_TARGET),esp32p4) +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No wifi # TODO: Support ESP32-C6 coprocessor on some boards. CIRCUITPY_BLEIO_NATIVE = 0 @@ -246,10 +266,12 @@ CIRCUITPY_PARALLELDISPLAYBUS = 0 # Library doesn't support P4 yet it seems CIRCUITPY_ESPCAMERA = 0 +#### esp32s2 ########################################################## else ifeq ($(IDF_TARGET),esp32s2) # Modules -CIRCUITPY_ALARM_TOUCH = 1 +CIRCUITPY_ALARM_TOUCH = $(CIRCUITPY_ALARM) CIRCUITPY_AUDIOIO ?= 1 + # No BLE in hw CIRCUITPY_BLEIO_NATIVE = 0 @@ -258,12 +280,19 @@ CIRCUITPY_SDIOIO = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0 +#### esp32s3 ########################################################## else ifeq ($(IDF_TARGET),esp32s3) + # Modules -CIRCUITPY_ALARM_TOUCH = 1 +CIRCUITPY_ALARM_TOUCH = $(CIRCUITPY_ALARM) CIRCUITPY_AUDIOBUSIO_PDMIN = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 + endif +#### end chip-specific choices ######################################## # No room for large modules on 2MB boards # 2MB boards have a single firmware partition, and can't do dualbank. From a4833325125343bf4f3292a5b6a9b9ccf3aa33b0 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Fri, 22 Aug 2025 11:34:33 -0500 Subject: [PATCH 055/208] Scale current duration when tempo is adjusted --- shared-module/synthio/MidiTrack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c index df8e5bdbea1b2..1cccd440fad9e 100644 --- a/shared-module/synthio/MidiTrack.c +++ b/shared-module/synthio/MidiTrack.c @@ -122,6 +122,7 @@ mp_int_t common_hal_synthio_miditrack_get_tempo(synthio_miditrack_obj_t *self) { void common_hal_synthio_miditrack_set_tempo(synthio_miditrack_obj_t *self, mp_int_t value) { mp_int_t val = mp_arg_validate_int_min(value, 1, MP_QSTR_tempo); + self->synth.span.dur = (uint32_t)self->synth.span.dur * self->tempo / val; self->tempo = val; } From 7b5587cf5f5088278ab494d01a16311f7b85899b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 22 Aug 2025 13:55:05 -0400 Subject: [PATCH 056/208] shrink some boards and for some boards make the turned-off modules consistent --- .../boards/feather_m4_express/mpconfigboard.mk | 1 + .../boards/itsybitsy_m4_express/mpconfigboard.mk | 6 ++++-- .../boards/metro_m4_express/mpconfigboard.mk | 1 + .../boards/seeeduino_wio_terminal/mpconfigboard.mk | 10 +++++++++- .../boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk | 2 ++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 4958581056e68..f780ea4aa3d0f 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -14,6 +14,7 @@ CIRCUITPY__EVE = 1 CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index 27bf8c165da88..be22cb94fae92 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -10,11 +10,13 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY__EVE = 1 CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_GIFIO = 0 CIRCUITPY_JPEGIO = 0 -CIRCUITPY_TILEPALETTEMAPPER = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 55a307ed4e308..d5aef01a0374f 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -14,6 +14,7 @@ CIRCUITPY__EVE = 1 CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk index dd8afd51f6e60..4ade6a148315d 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk @@ -9,6 +9,14 @@ CHIP_FAMILY = samd51 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_SHARPDISPLAY = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk index 515b6da5c07c4..9ca2eee157748 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk @@ -9,4 +9,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 2MB CIRCUITPY_DUALBANK = 0 +CIRCUITPY_JPEGIO = 0 + CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 From 687d0cbf20371f7f7143093233a4c50cf4a1764c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 22 Aug 2025 21:51:07 -0400 Subject: [PATCH 057/208] shrink overflowing boards after #10529 --- ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk | 1 + .../atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk | 4 ++++ ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk index 3dbef7c576a13..76c60b4464639 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk @@ -16,6 +16,7 @@ CIRCUITPY_EPAPERDISPLAY = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_I2CDISPLAYBUS = 0 CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_PARALLELDISPLAYBUS = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_SHARPDISPLAY = 0 diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk index 69cd5b0e2863e..cb7e690c6c02d 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -11,9 +11,13 @@ EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 0 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 + # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk index 73c56fb5fbab3..8fae53c0101f9 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -10,9 +10,13 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q16JVxM, W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 From 055034f5b4878c846eb1e3f8010327e682326082 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 22 Aug 2025 22:07:27 -0400 Subject: [PATCH 058/208] fix busio.UART.Parity documentation indentation --- shared-bindings/busio/UART.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 5f1d301b675be..4714c3ee0733a 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -368,14 +368,14 @@ static mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); -//| class Parity: -//| """Enum-like class to define the parity used to verify correct data transfer.""" +//| class Parity: +//| """Enum-like class to define the parity used to verify correct data transfer.""" //| -//| ODD: int -//| """Total number of ones should be odd.""" +//| ODD: int +//| """Total number of ones should be odd.""" //| -//| EVEN: int -//| """Total number of ones should be even.""" +//| EVEN: int +//| """Total number of ones should be even.""" //| //| const mp_obj_type_t busio_uart_parity_type; From 6e37d1b27bbe7d4a2c7f50e33773fff82007d83f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 26 Aug 2025 18:00:28 -0400 Subject: [PATCH 059/208] claim usb_host pins on construction --- ports/mimxrt10xx/common-hal/usb_host/Port.c | 3 +++ ports/raspberrypi/common-hal/usb_host/Port.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ports/mimxrt10xx/common-hal/usb_host/Port.c b/ports/mimxrt10xx/common-hal/usb_host/Port.c index 31af4ed582332..a7e73ab5b5c49 100644 --- a/ports/mimxrt10xx/common-hal/usb_host/Port.c +++ b/ports/mimxrt10xx/common-hal/usb_host/Port.c @@ -47,5 +47,8 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, self->dp = dp; self->dm = dm; + claim_pin(dp); + claim_pin(dm); + return self; } diff --git a/ports/raspberrypi/common-hal/usb_host/Port.c b/ports/raspberrypi/common-hal/usb_host/Port.c index 5439b39bf3aa3..b8a49725030ea 100644 --- a/ports/raspberrypi/common-hal/usb_host/Port.c +++ b/ports/raspberrypi/common-hal/usb_host/Port.c @@ -146,6 +146,8 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, self->base.type = &usb_host_port_type; self->dp = dp; self->dm = dm; + claim_pin(dp); + claim_pin(dm); PIO pio = pio_get_instance(pio_cfg.pio_tx_num); From 2efb47a038f49817ec39091818d6ec237b290612 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 27 Aug 2025 10:34:49 -0400 Subject: [PATCH 060/208] update pico-sdk submodule to raspberrypi 2.2.0 and cyw43-driver to v1.1.0 --- .gitmodules | 2 +- ports/raspberrypi/Makefile | 5 ++++- ports/raspberrypi/lib/cyw43-driver | 2 +- ports/raspberrypi/sdk | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index b1ec0f9faee7f..b89769942af7f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -172,7 +172,7 @@ url = https://github.com/adafruit/Adafruit_CircuitPython_SimpleMath [submodule "ports/raspberrypi/sdk"] path = ports/raspberrypi/sdk - url = https://github.com/adafruit/pico-sdk.git + url = https://github.com/raspberrypi/pico-sdk.git branch = force_inline_critical_section_2.1.1 [submodule "data/nvm.toml"] path = data/nvm.toml diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index ba2db8a750825..b75d542325166 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -25,7 +25,8 @@ INC_CYW43 := \ CFLAGS_CYW43 := \ -DCYW43_LWIP=1 \ -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 \ - -DCYW43_USE_SPI \ + -DCYW43_USE_SPI=1 \ + -DUSE_SDIOIT=0 \ -DIGNORE_GPIO25 \ -DIGNORE_GPIO23 \ -DIGNORE_GPIO24 \ @@ -125,6 +126,7 @@ INC += \ -isystem sdk/src/rp2_common/hardware_powman/include/ \ -isystem sdk/src/rp2_common/hardware_pwm/include/ \ -isystem sdk/src/rp2_common/hardware_resets/include/ \ + -isystem sdk/src/rp2_common/hardware_rcp/include/ \ -isystem sdk/src/rp2_common/hardware_rtc/include/ \ -isystem sdk/src/rp2_common/hardware_spi/include/ \ -isystem sdk/src/rp2_common/hardware_sync/include/ \ @@ -149,6 +151,7 @@ INC += \ -isystem sdk/src/rp2_common/pico_float/include/ \ -isystem sdk/src/rp2_common/pico_runtime/include/ \ -isystem sdk/src/rp2_common/pico_runtime_init/include/ \ + -isystem sdk/src/rp2_common/pico_platform_common/include/ \ -isystem sdk/src/rp2_common/pico_platform_compiler/include/ \ -isystem sdk/src/rp2_common/pico_platform_sections/include/ \ -isystem sdk/src/rp2_common/pico_platform_panic/include/ \ diff --git a/ports/raspberrypi/lib/cyw43-driver b/ports/raspberrypi/lib/cyw43-driver index c1075d4bc4404..dd7568229f3bf 160000 --- a/ports/raspberrypi/lib/cyw43-driver +++ b/ports/raspberrypi/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit c1075d4bc440422cf2b2fd12c64a1f53f77660ee +Subproject commit dd7568229f3bf7a37737b9e1ef250c26efe75b23 diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk index 96b363a15598d..a1438dff1d38b 160000 --- a/ports/raspberrypi/sdk +++ b/ports/raspberrypi/sdk @@ -1 +1 @@ -Subproject commit 96b363a15598d0a17a77542ba63150b7d3fa5fd5 +Subproject commit a1438dff1d38bd9c65dbd693f0e5db4b9ae91779 From 048a904fb469d16b5dc90a0e1fb687f4a84b244d Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 27 Aug 2025 17:06:36 -0400 Subject: [PATCH 061/208] shrink some samd21 boards --- ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h | 2 ++ ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk | 1 + ports/atmel-samd/boards/snekboard/mpconfigboard.mk | 3 +++ 3 files changed, 6 insertions(+) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h index be48cb810550e..8fdf20f186b00 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h @@ -20,6 +20,8 @@ #define SPI_FLASH_SCK_PIN &pin_PA09 #define SPI_FLASH_CS_PIN &pin_PA13 +#define BOARD_HAS_CRYSTAL 1 + #define DEFAULT_I2C_BUS_SCL (&pin_PA23) #define DEFAULT_I2C_BUS_SDA (&pin_PA22) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 573a69bee327c..bd068adc943e2 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk index d19e606319b63..441853c554df9 100644 --- a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk +++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk @@ -9,3 +9,6 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" LONGINT_IMPL = MPZ + +CIRCUITPY_CODEOP = 0 +CIRCUITPY_RAINBOWIO = 0 From 57b25b5f3abf39e7ebbab97f4cc0cdbfa73c4d53 Mon Sep 17 00:00:00 2001 From: Peggy Date: Wed, 27 Aug 2025 14:07:34 -0700 Subject: [PATCH 062/208] Add RTC module to ports/analog for MAX32690_apard I added a port-specific module, RTC to ports/analog. Now the analog port is capable of handling `rtc.set_time_source()`, `rtc.RTC()` and `r.datetime()`. Note that the RTC calibration functions are not implemented and is planned for near future. The implementation in the RTC module also enables two functions in the time module, which are `time.time()` and `time.localtime()`. The following example prints the current time every second: import time import rtc r = rtc.RTC) r.datetime = time.struct_Time((2000, 1, 1, 1, 1, 1, 0, -1, -1)) while(True): current_time = r.datetime print(current_time) time.sleep(1) Files I modified: * ports/analog/common-hal/rtc/RTC.c * ports/analog/common-hal/rtc/RTC.h * ports/analog/common-hal/rtc/__init__.c * ports/analog/mpconfigport.mk --- ports/analog/common-hal/rtc/RTC.c | 42 ++++++++++++++++++++++++++ ports/analog/common-hal/rtc/RTC.h | 11 +++++++ ports/analog/common-hal/rtc/__init__.c | 6 ++++ ports/analog/mpconfigport.mk | 2 +- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 ports/analog/common-hal/rtc/RTC.c create mode 100644 ports/analog/common-hal/rtc/RTC.h create mode 100644 ports/analog/common-hal/rtc/__init__.c diff --git a/ports/analog/common-hal/rtc/RTC.c b/ports/analog/common-hal/rtc/RTC.c new file mode 100644 index 0000000000000..c9d2258c1ece1 --- /dev/null +++ b/ports/analog/common-hal/rtc/RTC.c @@ -0,0 +1,42 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Nick Moore for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2019 Artur Pacholec +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "shared/timeutils/timeutils.h" +#include "supervisor/port.h" + +// This is the time in seconds since 2000 that the RTC was started. +// TODO: Change the offset to ticks so that it can be a subsecond adjustment. +static uint32_t rtc_offset = 0; + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + timeutils_seconds_since_2000_to_struct_time(rtc_offset + ticks_s, tm); +} + +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + uint32_t epoch_s = timeutils_seconds_since_2000( + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec + ); + rtc_offset = epoch_s - ticks_s; +} + +// the calibration function will be implemented in near future +// the RTC oscillator on my MAX32690-APARD is only off by 0.001 second +// the inaccuracy is still tolerable +int common_hal_rtc_get_calibration(void) { + return 0; +} + +void common_hal_rtc_set_calibration(int calibration) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_calibration); +} diff --git a/ports/analog/common-hal/rtc/RTC.h b/ports/analog/common-hal/rtc/RTC.h new file mode 100644 index 0000000000000..590bc93ab5231 --- /dev/null +++ b/ports/analog/common-hal/rtc/RTC.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Noralf Trønnes +// SPDX-FileCopyrightText: Copyright (c) 2019 Artur Pacholec +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern void rtc_reset(void); diff --git a/ports/analog/common-hal/rtc/__init__.c b/ports/analog/common-hal/rtc/__init__.c new file mode 100644 index 0000000000000..ddf788bb0b5ad --- /dev/null +++ b/ports/analog/common-hal/rtc/__init__.c @@ -0,0 +1,6 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT diff --git a/ports/analog/mpconfigport.mk b/ports/analog/mpconfigport.mk index 67f1f79fb8121..97ead8efdfb0f 100644 --- a/ports/analog/mpconfigport.mk +++ b/ports/analog/mpconfigport.mk @@ -24,7 +24,7 @@ INTERNAL_FLASH_FILESYSTEM = 1 # Plan to implement CIRCUITPY_BUSIO ?= 0 -CIRCUITPY_RTC ?= 0 +CIRCUITPY_RTC ?= 1 # Other modules (may or may not implement): CIRCUITPY_ANALOGIO ?= 0 From 795d40f594339703e7f7e5b60fe9ade606dcdb61 Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Thu, 28 Aug 2025 18:02:38 +0200 Subject: [PATCH 063/208] fix MICROPY_HW_MCU_NAME --- ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h | 2 +- ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h index 72b1e1d04399f..097cbd8baa301 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: MIT #define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350" -#define MICROPY_HW_MCU_NAME "rp2350b" +#define MICROPY_HW_MCU_NAME "rp2350a" #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h index d9e62abb1edd2..576299d939cfb 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: MIT #define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350W" -#define MICROPY_HW_MCU_NAME "rp2350A" +#define MICROPY_HW_MCU_NAME "rp2350a" #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) From c74929a3d4576b29f4269a4bc448263833693336 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Fri, 29 Aug 2025 09:48:33 -0500 Subject: [PATCH 064/208] moving cron workflows from adabot repo --- .github/workflows/bundle_cron.yml | 58 +++++++++++++++++++ .github/workflows/learn_cron.yml | 41 ++++++++++++++ .github/workflows/reports_cron.yml | 91 ++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 .github/workflows/bundle_cron.yml create mode 100644 .github/workflows/learn_cron.yml create mode 100644 .github/workflows/reports_cron.yml diff --git a/.github/workflows/bundle_cron.yml b/.github/workflows/bundle_cron.yml new file mode 100644 index 0000000000000..cf1d51a3aa8fb --- /dev/null +++ b/.github/workflows/bundle_cron.yml @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2019 Michael Schroeder +# +# SPDX-License-Identifier: MIT + +name: Update Bundles + +on: + schedule: + - cron: 0 5 * * * + workflow_dispatch: + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + steps: + - name: repository + env: + OWNER_IS_ADAFRUIT: ${{ startswith(github.repository, 'adafruit/') }} + run: | + echo "This workflow will only run if Adafruit is the repository owner." + echo "Repository owner is Adafruit: $OWNER_IS_ADAFRUIT" + update-bundles: + runs-on: ubuntu-latest + # Only run the build on Adafruit's repository. Forks won't have the secrets. + # Its necessary to do this here, since 'schedule' events cannot (currently) + # be limited (they run on all forks' default branches). + if: startswith(github.repository, 'adafruit/') + steps: + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Load contributor cache + uses: actions/cache@v4 + with: + key: "contributor-cache" + path: "contributors.json" + - name: Versions + run: | + python3 --version + - uses: actions/checkout@v4 + with: + repository: 'adafruit/adabot' + submodules: true + - name: Install deps + run: | + pip install -r requirements.txt + - name: Run adabot.circuitpython_bundle + env: + ADABOT_EMAIL: ${{ secrets.ADABOT_EMAIL }} + ADABOT_GITHUB_USER: ${{ secrets.ADABOT_GITHUB_USER }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + BIGQUERY_PRIVATE_KEY: ${{ secrets.BIGQUERY_PRIVATE_KEY }} + BIGQUERY_CLIENT_EMAIL: ${{ secrets.BIGQUERY_CLIENT_EMAIL }} + run: | + python3 -u -m adabot.circuitpython_bundle diff --git a/.github/workflows/learn_cron.yml b/.github/workflows/learn_cron.yml new file mode 100644 index 0000000000000..540b95a63b5f3 --- /dev/null +++ b/.github/workflows/learn_cron.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2021 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +name: Tag Learning System Guides + +on: + schedule: + - cron: 0 5 * * * + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + if: ${{ (github.repository_owner != 'adafruit') }} + steps: + - run: | + echo "This workflow is only intended to run in the adafruit fork" + + update-learn: + runs-on: ubuntu-latest + # Only run the build if the access token has been configured. THs will be + # the case on Adafruit's repository. Its necessary to do this here, since + # 'schedule' events cannot (currently) be limited (they run on all forks' + # default branches). + if: ${{ (github.repository_owner == 'adafruit') }} + steps: + - uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/Adafruit_Learning_System_Guides + token: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + - name: Tag a release + env: + ADABOT_EMAIL: ${{ secrets.ADABOT_EMAIL }} + run: | + git config --global user.name adabot + git config --global user.email "$ADABOT_EMAIL" + TAG_NAME=`date +%Y%m%d` + git tag $TAG_NAME + git push origin $TAG_NAME diff --git a/.github/workflows/reports_cron.yml b/.github/workflows/reports_cron.yml new file mode 100644 index 0000000000000..652e0379fd2ca --- /dev/null +++ b/.github/workflows/reports_cron.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2019 Michael Schroeder +# +# SPDX-License-Identifier: MIT + +name: Run Daily Reports + +on: + schedule: + # The actor (github.actor) that runs the cron job may be the user who created the cron job + # initially. It does not appear to be settable via a secret or environment variable. + - cron: 15 5 * * * + workflow_dispatch: + + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + steps: + - name: repository + env: + OWNER_IS_ADAFRUIT: ${{ startswith(github.repository, 'adafruit/') }} + run: | + echo "This workflow will only run if Adafruit is the repository owner." + echo "Repository owner is Adafruit: $OWNER_IS_ADAFRUIT" + run-reports: + runs-on: ubuntu-latest + # Only run the build on Adafruit's repository. Forks won't have the secrets. + # Its necessary to do this here, since 'schedule' events cannot (currently) + # be limited (they run on all forks' default branches). + if: startswith(github.repository, 'adafruit/') + env: + ADABOT_GITHUB_USER: ${{ secrets.ADABOT_GITHUB_USER }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + RTD_TOKEN: ${{ secrets.RTD_TOKEN }} + BIGQUERY_PRIVATE_KEY: ${{ secrets.BIGQUERY_PRIVATE_KEY }} + BIGQUERY_CLIENT_EMAIL: ${{ secrets.BIGQUERY_CLIENT_EMAIL }} + steps: + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: 3.11 + - name: Versions + run: | + python3 --version + - uses: actions/checkout@v4 + with: + repository: 'adafruit/adabot' + submodules: true + - name: Install deps + run: | + pip install -r requirements.txt + - name: Make Directory For Report Files + run: mkdir -p bin/adabot + - name: Set Date Variable + id: today + run: | + echo date=$( + date +%Y%m%d + ) >> $GITHUB_OUTPUT + - name: Run adabot.circuitpython_libraries + env: + # LIB_CHECK_CP_FILE is for circuitpython_libraries.py output + LIB_CHECK_CP_FILE: bin/adabot/circuitpython_library_report_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.circuitpython_libraries -o $LIB_CHECK_CP_FILE + continue-on-error: true + - name: Run adabot.circuitpython_library_download_stats + env: + # LIB_DL_STATS_FILE is for future Bundle and PyPi download stats script + LIB_DL_STATS_FILE: bin/adabot/library_download_stats_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.circuitpython_library_download_stats -o $LIB_DL_STATS_FILE + continue-on-error: true + - name: Run adabot.arduino_libraries + env: + # LIB_CHECK_ARD_FILE is for arduino_libraries.py output + LIB_CHECK_ARD_FILE: bin/adabot/arduino_library_report_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.arduino_libraries -o $LIB_CHECK_ARD_FILE + continue-on-error: true + - name: Check For Files + run: | + ls bin/adabot + - name: Upload Reports To AWS S3 + if: ${{ github.event_name != 'workflow_dispatch' }} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/adabot/ s3://adafruit-circuit-python/adabot/bin/reports/ --recursive --no-progress --region us-east-1" From 92a87a4c834e992d021ef8d445cb512d63eb51a8 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Fri, 29 Aug 2025 09:55:55 -0500 Subject: [PATCH 065/208] spelling fixes --- .github/workflows/bundle_cron.yml | 2 +- .github/workflows/learn_cron.yml | 4 ++-- .github/workflows/reports_cron.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bundle_cron.yml b/.github/workflows/bundle_cron.yml index cf1d51a3aa8fb..606707d4102f1 100644 --- a/.github/workflows/bundle_cron.yml +++ b/.github/workflows/bundle_cron.yml @@ -24,7 +24,7 @@ jobs: update-bundles: runs-on: ubuntu-latest # Only run the build on Adafruit's repository. Forks won't have the secrets. - # Its necessary to do this here, since 'schedule' events cannot (currently) + # It's necessary to do this here, since 'schedule' events cannot (currently) # be limited (they run on all forks' default branches). if: startswith(github.repository, 'adafruit/') steps: diff --git a/.github/workflows/learn_cron.yml b/.github/workflows/learn_cron.yml index 540b95a63b5f3..6100e6637c20e 100644 --- a/.github/workflows/learn_cron.yml +++ b/.github/workflows/learn_cron.yml @@ -20,8 +20,8 @@ jobs: update-learn: runs-on: ubuntu-latest - # Only run the build if the access token has been configured. THs will be - # the case on Adafruit's repository. Its necessary to do this here, since + # Only run the build if the access token has been configured. This will be + # the case on Adafruit's repository. It's necessary to do this here, since # 'schedule' events cannot (currently) be limited (they run on all forks' # default branches). if: ${{ (github.repository_owner == 'adafruit') }} diff --git a/.github/workflows/reports_cron.yml b/.github/workflows/reports_cron.yml index 652e0379fd2ca..b4e9a43024e27 100644 --- a/.github/workflows/reports_cron.yml +++ b/.github/workflows/reports_cron.yml @@ -27,7 +27,7 @@ jobs: run-reports: runs-on: ubuntu-latest # Only run the build on Adafruit's repository. Forks won't have the secrets. - # Its necessary to do this here, since 'schedule' events cannot (currently) + # It's necessary to do this here, since 'schedule' events cannot (currently) # be limited (they run on all forks' default branches). if: startswith(github.repository, 'adafruit/') env: From dd44278f778ee1c714f31fe8b9e7aff3a9dc6b5b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 29 Aug 2025 12:37:39 -0400 Subject: [PATCH 066/208] update frozen libraries --- frozen/Adafruit_CircuitPython_DotStar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index 163f2f166aee1..4b0ba649e5abd 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit 163f2f166aee11d82303492bb1e5af4937e57b62 +Subproject commit 4b0ba649e5abdebead5b9a47a6c695d67c2c25fa From 91f6426c0f2ee5bae3a379a49ea29d3c8be1ce07 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 29 Aug 2025 10:06:06 -0700 Subject: [PATCH 067/208] Fix DVI blanking during SPI transactions SPI was using DMA to transfer to PSRAM. When a cache miss occurs, the DMA can't switch to another transfer and throws off DVI timing. So, only use DMA with SPI when the buffers are in SRAM. This will slow down SPI transactions when the FIFOs are empty and the CPU is busy running a background task. It will still be correct though since we control the SPI clock. Fixes #10557 --- ports/raspberrypi/common-hal/busio/SPI.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index d20bc4d7d10aa..4735d1284f98e 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -182,7 +182,10 @@ static bool _transfer(busio_spi_obj_t *self, chan_tx = dma_claim_unused_channel(false); chan_rx = dma_claim_unused_channel(false); } - bool use_dma = chan_rx >= 0 && chan_tx >= 0; + bool has_dma_channels = chan_rx >= 0 && chan_tx >= 0; + // Only use DMA if both data buffers are in SRAM. Otherwise, we'll stall the DMA with PSRAM or flash cache misses. + bool data_in_sram = data_in >= (uint8_t *)SRAM_BASE && data_out >= (uint8_t *)SRAM_BASE; + bool use_dma = has_dma_channels && data_in_sram; if (use_dma) { dma_channel_config c = dma_channel_get_default_config(chan_tx); channel_config_set_transfer_data_size(&c, DMA_SIZE_8); From 7fd8b4835789f4a9b2d6bb60b55eac445b9f744f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 29 Aug 2025 11:00:43 -0700 Subject: [PATCH 068/208] Fix lvfontio memory allocation with fixed width fonts There was a branch of the loading that failed to set max_slots. This led to unpredicatable allocation failures. Fixes #10560 --- shared-module/lvfontio/OnDiskFont.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared-module/lvfontio/OnDiskFont.c b/shared-module/lvfontio/OnDiskFont.c index 0cf65301d2270..368bd381475b1 100644 --- a/shared-module/lvfontio/OnDiskFont.c +++ b/shared-module/lvfontio/OnDiskFont.c @@ -253,9 +253,10 @@ static bool load_font_header(lvfontio_ondiskfont_t *self, FIL *file, size_t *max *max_slots = advance_count[1] * 2 + advance_count[0]; } } + } else { + *max_slots = advance_count[0] + advance_count[1]; } - found_glyf = true; } From 059b0e712aa3b496d747187f9b4d7e7a35495afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brad=C3=A1n=20Lane?= Date: Fri, 29 Aug 2025 14:28:39 -0400 Subject: [PATCH 069/208] force neopixel_write into build --- .../atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk index 33165c8cfc5d0..11f090ed76305 100644 --- a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk @@ -38,7 +38,7 @@ CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 0 - +CIRCUITPY_NEOPIXEL_WRITE = 1 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID From 81afa660785ceb18a501b059cb3f0133d97e4db7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 29 Aug 2025 11:56:36 -0700 Subject: [PATCH 070/208] Fix display glitch during neopixel update The DMA can get stalled by DMA to/from PSRAM. So, copy the data into SRAM when we need to. Fail if we can't. Fixes #10564 --- .../common-hal/rp2pio/StateMachine.c | 90 +++++++++++++++---- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index fefecf05ff715..74b9a7f0c31b0 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -853,25 +853,64 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, // This implementation is based on SPI but varies because the tx and rx buffers // may be different lengths and occur at different times or speeds. - // Use DMA for large transfers if channels are available. - // Don't exceed FIFO size. - const size_t dma_min_size_threshold = self->fifo_depth; int chan_tx = -1; int chan_rx = -1; size_t len = MAX(out_len, in_len); bool tx = data_out != NULL; bool rx = data_in != NULL; - bool use_dma = len >= dma_min_size_threshold || swap_out || swap_in; + bool free_data_out = false; + bool free_data_in = false; + uint8_t *sram_data_out = (uint8_t *)data_out; + uint8_t *sram_data_in = data_in; + bool tx_fits_in_fifo = (out_len / out_stride_in_bytes) <= self->fifo_depth; + bool rx_fits_in_fifo = (in_len / in_stride_in_bytes) <= self->fifo_depth; + bool use_dma = !(tx_fits_in_fifo && rx_fits_in_fifo) || swap_out || swap_in; + if (use_dma) { - // Use DMA channels to service the two FIFOs + // We can only reliably use DMA for SRAM buffers. So, if we're given PSRAM buffers, + // then copy them to SRAM first. If we can't, then fail. + // Use DMA channels to service the two FIFOs. Fail if we can't allocate DMA channels. if (tx) { + if (data_out < (uint8_t *)SRAM_BASE) { + // Try to allocate a temporary buffer for DMA transfer + uint8_t *temp_buffer = (uint8_t *)port_malloc(len, true); + if (temp_buffer == NULL) { + mp_printf(&mp_plat_print, "Failed to allocate temporary buffer for DMA tx\n"); + return false; + } + memcpy(temp_buffer, data_out, len); + sram_data_out = temp_buffer; + free_data_out = true; + } chan_tx = dma_claim_unused_channel(false); // DMA allocation failed... if (chan_tx < 0) { + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + port_free(sram_data_in); + } return false; } } if (rx) { + if (data_in < (uint8_t *)SRAM_BASE) { + // Try to allocate a temporary buffer for DMA transfer + uint8_t *temp_buffer = (uint8_t *)port_malloc(len, true); + if (temp_buffer == NULL) { + mp_printf(&mp_plat_print, "Failed to allocate temporary buffer for DMA rx\n"); + if (chan_tx >= 0) { + dma_channel_unclaim(chan_tx); + } + if (free_data_out) { + port_free(sram_data_out); + } + return false; + } + sram_data_in = temp_buffer; + free_data_in = true; + } chan_rx = dma_claim_unused_channel(false); // DMA allocation failed... if (chan_rx < 0) { @@ -879,6 +918,12 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, if (chan_tx >= 0) { dma_channel_unclaim(chan_tx); } + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + port_free(sram_data_in); + } return false; } } @@ -910,7 +955,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, channel_config_set_bswap(&c, swap_out); dma_channel_configure(chan_tx, &c, tx_destination, - data_out, + sram_data_out, out_len / out_stride_in_bytes, false); channel_mask |= 1u << chan_tx; @@ -923,7 +968,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, channel_config_set_write_increment(&c, true); channel_config_set_bswap(&c, swap_in); dma_channel_configure(chan_rx, &c, - data_in, + sram_data_in, rx_source, in_len / in_stride_in_bytes, false); @@ -950,8 +995,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, self->pio->fdebug = stall_mask; } - // If we have claimed only one channel successfully, we should release immediately. This also - // releases the DMA after use_dma has been done. + // Release the DMA channels after use_dma has been done. if (chan_rx >= 0) { dma_channel_unclaim(chan_rx); } @@ -960,31 +1004,31 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, } if (!use_dma && !(self->user_interruptible && mp_hal_is_interrupted())) { - // Use software for small transfers, or if couldn't claim two DMA channels + // Use software for small transfers size_t rx_remaining = in_len / in_stride_in_bytes; size_t tx_remaining = out_len / out_stride_in_bytes; while (rx_remaining || tx_remaining) { while (tx_remaining && !pio_sm_is_tx_fifo_full(self->pio, self->state_machine)) { if (out_stride_in_bytes == 1) { - *tx_destination = *data_out; + *tx_destination = *sram_data_out; } else if (out_stride_in_bytes == 2) { - *((uint16_t *)tx_destination) = *((uint16_t *)data_out); + *((uint16_t *)tx_destination) = *((uint16_t *)sram_data_out); } else if (out_stride_in_bytes == 4) { - *((uint32_t *)tx_destination) = *((uint32_t *)data_out); + *((uint32_t *)tx_destination) = *((uint32_t *)sram_data_out); } - data_out += out_stride_in_bytes; + sram_data_out += out_stride_in_bytes; --tx_remaining; } while (rx_remaining && !pio_sm_is_rx_fifo_empty(self->pio, self->state_machine)) { if (in_stride_in_bytes == 1) { - *data_in = (uint8_t)*rx_source; + *sram_data_in = (uint8_t)*rx_source; } else if (in_stride_in_bytes == 2) { - *((uint16_t *)data_in) = *((uint16_t *)rx_source); + *((uint16_t *)sram_data_in) = *((uint16_t *)rx_source); } else if (in_stride_in_bytes == 4) { - *((uint32_t *)data_in) = *((uint32_t *)rx_source); + *((uint32_t *)sram_data_in) = *((uint32_t *)rx_source); } - data_in += in_stride_in_bytes; + sram_data_in += in_stride_in_bytes; --rx_remaining; } RUN_BACKGROUND_TASKS; @@ -996,7 +1040,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, self->pio->fdebug = stall_mask; } // Wait for the state machine to finish transmitting the data we've queued - // up. + // up (either from the CPU or via DMA.) if (tx) { while (!pio_sm_is_tx_fifo_empty(self->pio, self->state_machine) || (self->wait_for_txstall && (self->pio->fdebug & stall_mask) == 0)) { @@ -1006,6 +1050,14 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, } } } + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + // Copy the data from the SRAM buffer to the user PSRAM buffer. + memcpy(data_in, sram_data_in, len); + port_free(sram_data_in); + } return true; } From 4b2624a27baabe499efb5b46805cdd82599f2f58 Mon Sep 17 00:00:00 2001 From: bradanlane Date: Fri, 29 Aug 2025 16:35:32 -0400 Subject: [PATCH 071/208] Enable CIRCUITPY_PIXELBUF in mpconfigboard.mk --- .../atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk index 11f090ed76305..894037ec0148a 100644 --- a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk @@ -39,6 +39,7 @@ CIRCUITPY_RTC = 0 CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_NEOPIXEL_WRITE = 1 +CIRCUITPY_PIXELBUF = 1 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID From 3c44c9d908952305349bb79ce032249a4e505835 Mon Sep 17 00:00:00 2001 From: bradanlane Date: Fri, 29 Aug 2025 17:41:57 -0400 Subject: [PATCH 072/208] Update mpconfigboard.mk to incorporate limited changes suggested by halbert. --- .../boards/bradanlanestudio_coin_m0/mpconfigboard.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk index 894037ec0148a..9a2cdcd668ed2 100644 --- a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk @@ -18,7 +18,7 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" -LONGINT_IMPL = NONE +LONGINT_IMPL = MPZ # the M0 Coin has limited functionality and many modules can be eliminated @@ -26,7 +26,7 @@ LONGINT_IMPL = NONE # Disable modules that are unusable on this special-purpose board. -CIRCUITPY_FULL_BUILD = 0 +CIRCUITPY_FULL_BUILD = 1 CIRCUITPY_AUDIOIO = 1 CIRCUITPY_DISPLAYIO = 0 From a4a383630267c8fecf216900aec4b1e8b4f00642 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 31 Aug 2025 00:09:32 -0500 Subject: [PATCH 073/208] Fix radio union types --- shared-bindings/wifi/Radio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index a267dea11c1ff..9a7d445fd0473 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -99,7 +99,7 @@ MP_PROPERTY_GETSET(wifi_radio_enabled_obj, (mp_obj_t)&wifi_radio_get_enabled_obj, (mp_obj_t)&wifi_radio_set_enabled_obj); -//| hostname: Union[str | ReadableBuffer] +//| hostname: Union[str, ReadableBuffer] //| """Hostname for wifi interface. When the hostname is altered after interface started/connected //| the changes would only be reflected once the interface restarts/reconnects.""" static mp_obj_t wifi_radio_get_hostname(mp_obj_t self_in) { @@ -325,8 +325,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_station_obj, wifi_radio_stop_station); //| def start_ap( //| self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = b"", +//| ssid: Union[str, ReadableBuffer], +//| password: Union[str, ReadableBuffer] = b"", //| *, //| channel: int = 1, //| authmode: Iterable[AuthMode] = (), @@ -438,11 +438,11 @@ MP_PROPERTY_GETTER(wifi_radio_ap_active_obj, //| def connect( //| self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = b"", +//| ssid: Union[str, ReadableBuffer], +//| password: Union[str, ReadableBuffer] = b"", //| *, //| channel: int = 0, -//| bssid: Optional[Union[str | ReadableBuffer]] = None, +//| bssid: Optional[Union[str, ReadableBuffer]] = None, //| timeout: Optional[float] = None, //| ) -> None: //| """Connects to the given ssid and waits for an ip address. Reconnections are handled From 36feb41bf5d3b15a43532ba0ec6b218cf2067f94 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 31 Aug 2025 00:29:41 -0500 Subject: [PATCH 074/208] Fix struct_time type hints --- shared-bindings/time/__init__.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 504cd07d90111..8a591da368858 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -83,6 +83,16 @@ static mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, s } //| class struct_time: +//| tm_year: int +//| tm_mon: int +//| tm_mday: int +//| tm_hour: int +//| tm_min: int +//| tm_sec: int +//| tm_wday: int +//| tm_yday: int +//| tm_isdst: int +//| //| def __init__(self, time_tuple: Sequence[int]) -> None: //| """Structure used to capture a date and time. Can be constructed from a `struct_time`, `tuple`, `list`, or `namedtuple` with 9 elements. //| @@ -210,7 +220,7 @@ static mp_obj_t time_monotonic_ns(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); -//| def localtime(secs: int) -> struct_time: +//| def localtime(secs: Optional[int] = None) -> struct_time: //| """Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in //| local time. If secs is not provided or None, the current time as returned //| by time() is used. From 5480bd47684b0e0b3537a2f365bc94b2c0361633 Mon Sep 17 00:00:00 2001 From: allexok Date: Tue, 2 Sep 2025 17:28:09 +0200 Subject: [PATCH 075/208] Add Ai-On-The-Edge-Cam board --- .../prokyber_ai_on_the_edge_cam/board.c | 9 ++ .../mpconfigboard.h | 22 +++++ .../mpconfigboard.mk | 14 +++ .../boards/prokyber_ai_on_the_edge_cam/pins.c | 99 +++++++++++++++++++ .../prokyber_ai_on_the_edge_cam/sdkconfig | 14 +++ 5 files changed, 158 insertions(+) create mode 100644 ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c create mode 100644 ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h create mode 100644 ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk create mode 100644 ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c create mode 100644 ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c new file mode 100644 index 0000000000000..a3a9eec047145 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h new file mode 100644 index 0000000000000..2114fecf373a4 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Prokyber Ai-On-The-Edge-Cam" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO12) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO48) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk new file mode 100644 index 0000000000000..82419bb80745c --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x1209 +USB_PID = 0xDABB +USB_PRODUCT = "AI-ON-THE-EDGE-CAM" +USB_MANUFACTURER = "Prokyber" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m +CIRCUITPY_ESP_PSRAM_SIZE = 8MB diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c new file mode 100644 index 0000000000000..b11b33877c34b --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c @@ -0,0 +1,99 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" + +static const mp_rom_obj_tuple_t camera_data_tuple = { + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO11), + MP_ROM_PTR(&pin_GPIO9), + MP_ROM_PTR(&pin_GPIO8), + MP_ROM_PTR(&pin_GPIO10), + MP_ROM_PTR(&pin_GPIO47), + MP_ROM_PTR(&pin_GPIO18), + MP_ROM_PTR(&pin_GPIO17), + MP_ROM_PTR(&pin_GPIO16), + } +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_PER_EN), MP_ROM_PTR(&pin_GPIO46) }, + + // SD + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_ETH_RST), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_ETH_INT), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MOSI), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MISO), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CLK), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + + // LEDs + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + //I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, + + { MP_ROM_QSTR(MP_QSTR_CAMERA_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_HREF), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA9), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA8), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA7), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA6), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA2), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA5), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA3), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA4), MP_ROM_PTR(&pin_GPIO8) }, + // { MP_ROM_QSTR(MP_QSTR_CAMERA_RESET), MP_ROM_PTR(&pin_GPIO47) }, + // { MP_ROM_QSTR(MP_QSTR_CAMERA_PWDN), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOD), MP_ROM_PTR(&pin_GPIO4) }, // SDA + { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOC), MP_ROM_PTR(&pin_GPIO5) }, // SCL + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig new file mode 100644 index 0000000000000..ac1c535717672 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP +CONFIG_OV2640_SUPPORT=y +# end of Component config + +# end of Espressif IoT Development Framework Configuration From 5493a6a1bde5538a4bfedad502f3ca3834b79b65 Mon Sep 17 00:00:00 2001 From: allexok Date: Tue, 2 Sep 2025 17:38:23 +0200 Subject: [PATCH 076/208] prettier text after 'pre-commit run --all-files' --- ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c index b11b33877c34b..305bdb3e0b69a 100644 --- a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c @@ -68,7 +68,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, - //I2C + // I2C { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, From de2efe0c2cceefa1a5ae5d14e6145ec8716a66f4 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 2 Sep 2025 20:43:39 -0400 Subject: [PATCH 077/208] Fix cardputer boot loop, and do some cleanup. - For `cardputer_keyboard.c`, allocate `DemuxKeyMatrix` it creates and the objects it holds (all the way down) on the port heap, because it lives past VM's. - To do the above, add support for non-VM heap for `DemuxKeyMatrix` and the `keypad` allocations it needs by passing an arg `use_gc_allocator`, as is done in `lvfontio`. - Add `mp_obj_port_malloc()`, `mp_obj_port_malloc_var()`, `mp_obj_new_port_tuple()`, all of which allocate on the port heap, not the VM heap. - Add `port_malloc_zero()`, because `port_malloc()` did not zero out its allocation, unlike VM heap allocations. I got caught by this. - Move `port_gc_collect()` from `main.c` to `supervisor/port.c` for consistency. This function is not actually used by anyone, but I was considering using it. - Add an `MP_WEAK` `mp_board_init()`, for board-specific initializations needed when a VM starts. Also considered, but not used. Added anyway for possible future use. - Add an `MP_WEAK` `board_gc_collect()`, for board-specific gc. Not used. - Add an `MP_WEAK` `port_gc_collect()`, for port-specific gc. Not used. - Don't duplicate keyboard code between `boards/m5stack_cardputer` and `boards/m5stack_cardputer_ros`. Instead, add a `ports/espressif/module` directory for this code, in the style of a port-specific `module` directory, like the port-specific `bindings` directories. --- main.c | 8 +- .../boards/m5stack_cardputer/mpconfigboard.mk | 2 +- .../cardputer_keyboard.c | 238 ------------------ .../boards/m5stack_cardputer_ros/keymap.h | 214 ---------------- .../m5stack_cardputer_ros/mpconfigboard.mk | 2 +- .../cardputer_keyboard.c | 59 ++--- .../keymap.h => module/cardputer_keymap.h} | 0 py/objtuple.c | 3 + shared-bindings/keypad/EventQueue.h | 2 +- shared-bindings/keypad_demux/DemuxKeyMatrix.c | 3 +- shared-bindings/keypad_demux/DemuxKeyMatrix.h | 2 +- shared-module/keypad/EventQueue.c | 9 +- shared-module/keypad/KeyMatrix.c | 2 +- shared-module/keypad/Keys.c | 2 +- shared-module/keypad/ShiftRegisterKeys.c | 2 +- shared-module/keypad/__init__.c | 14 +- shared-module/keypad/__init__.h | 2 +- shared-module/keypad_demux/DemuxKeyMatrix.c | 25 +- supervisor/board.h | 7 + supervisor/port.h | 8 + supervisor/port_heap.h | 1 + supervisor/shared/board.c | 8 + supervisor/shared/port.c | 36 +++ 23 files changed, 140 insertions(+), 509 deletions(-) delete mode 100644 ports/espressif/boards/m5stack_cardputer_ros/cardputer_keyboard.c delete mode 100644 ports/espressif/boards/m5stack_cardputer_ros/keymap.h rename ports/espressif/{boards/m5stack_cardputer => module}/cardputer_keyboard.c (83%) rename ports/espressif/{boards/m5stack_cardputer/keymap.h => module/cardputer_keymap.h} (100%) diff --git a/main.c b/main.c index 1f387b7ca3ceb..cf9cf377d690b 100644 --- a/main.c +++ b/main.c @@ -207,6 +207,9 @@ static void start_mp(safe_mode_t safe_mode) { // Always return to root common_hal_os_chdir("/"); + + // Initialization for individual boards when a VM starts. + mp_board_init(); } static void stop_mp(void) { @@ -1149,6 +1152,7 @@ void gc_collect(void) { gc_collect_root((void **)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t)); port_gc_collect(); + board_gc_collect(); background_callback_gc_collect(); @@ -1179,10 +1183,6 @@ void gc_collect(void) { gc_collect_end(); } -// Ports may provide an implementation of this function if it is needed -MP_WEAK void port_gc_collect(void) { -} - size_t gc_get_max_new_split(void) { return port_heap_get_largest_free_size(); } diff --git a/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk b/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk index cd18ccf8a5a81..bc30ae3afd5e9 100644 --- a/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk @@ -13,4 +13,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 8MB CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_MAX3421E = 0 -SRC_C += boards/$(BOARD)/cardputer_keyboard.c +SRC_C += module/cardputer_keyboard.c diff --git a/ports/espressif/boards/m5stack_cardputer_ros/cardputer_keyboard.c b/ports/espressif/boards/m5stack_cardputer_ros/cardputer_keyboard.c deleted file mode 100644 index 73880f66e19d9..0000000000000 --- a/ports/espressif/boards/m5stack_cardputer_ros/cardputer_keyboard.c +++ /dev/null @@ -1,238 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft -// -// SPDX-License-Identifier: MIT - -#include "py/obj.h" -#include "py/objstr.h" -#include "py/runtime.h" - -#include "supervisor/shared/serial.h" -#include "shared-bindings/keypad/EventQueue.h" -#include "shared-bindings/keypad_demux/DemuxKeyMatrix.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-module/keypad/EventQueue.h" -#include "shared-module/keypad_demux/DemuxKeyMatrix.h" -#include "supervisor/shared/reload.h" - -#include "keymap.h" - -//| """M5Stack Cardputer keyboard integration. -//| """ -//| -//| """The KEYBOARD object is an instance of DemuxKeyMatrix, configured with correct pins. -//| The pins cannot be used for any other purposes (even though exposed in the board module). -//| By default all keyboard events are consumed and routed to the standard input - there is -//| not much use of the KEYBOARD object in this configuration - just read the input via sys.stdin. -//| -//| If you need to manually process individual key up / key down events via KEYBOARD.events, -//| call `detach_serial()`. -//| """" -//| KEYBOARD: keypad_demux.DemuxKeymatrix -//| -keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard_obj; -bool cardputer_keyboard_serial_attached = false; - -void cardputer_keyboard_init(void); -void keyboard_seq(const char *seq); -void update_keyboard(keypad_eventqueue_obj_t *queue); - -//| def detach_serial() -> None: -//| """Stops consuming keyboard events and routing them to sys.stdin.""" -//| ... -//| -static mp_obj_t detach_serial(void) { - cardputer_keyboard_serial_attached = false; - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, NULL); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial); - -//| def attach_serial() -> None: -//| """Starts consuming keyboard events and routing them to sys.stdin.""" -//| ... -//| -static mp_obj_t attach_serial(void) { - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, update_keyboard); - cardputer_keyboard_serial_attached = true; - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(attach_serial_obj, attach_serial); - -//| def key_to_char(key: int, shifted: bool) -> str | None: -//| """Converts a key index to the respective key (with or without shift modifier). -//| Returns None for functional & modifier keys or whenever not 0 <= key < 56. -//| """ -//| ... -//| -static mp_obj_t key_to_char(mp_obj_t key_obj, mp_obj_t shifted_obj) { - mp_int_t key = mp_obj_get_int(key_obj); - if (key < 0 || key > (mp_int_t)(sizeof keymap / sizeof *keymap) || keymap[key] == 0) { - return mp_const_none; - } else if (shifted_obj == mp_const_true) { - return mp_obj_new_str(&keymap_shifted[key], 1); - } else { - return mp_obj_new_str(&keymap[key], 1); - } -} -static MP_DEFINE_CONST_FUN_OBJ_2(key_to_char_obj, key_to_char); - -// Ring buffer of characters consumed from keyboard events (when serial attached) -ringbuf_t keyqueue; -char keybuf[32]; - -keypad_event_obj_t event; -char keystate[56]; - -// Keyboard pins -const mcu_pin_obj_t *row_addr_pins[] = { - &pin_GPIO8, - &pin_GPIO9, - &pin_GPIO11, -}; - -const mcu_pin_obj_t *column_pins[] = { - &pin_GPIO13, - &pin_GPIO15, - &pin_GPIO3, - &pin_GPIO4, - &pin_GPIO5, - &pin_GPIO6, - &pin_GPIO7 -}; - -void cardputer_keyboard_init(void) { - cardputer_keyboard_obj.base.type = &keypad_demux_demuxkeymatrix_type; - common_hal_keypad_demux_demuxkeymatrix_construct( - &cardputer_keyboard_obj, // self - 3, // num_row_addr_pins - row_addr_pins, // row_addr_pins - 7, // num_column_pins - column_pins, // column_pins - true, // columns_to_anodes - false, // transpose - 0.01f, // interval - 20, // max_events - 2 // debounce_threshold - ); - demuxkeymatrix_never_reset(&cardputer_keyboard_obj); - - ringbuf_init(&keyqueue, (uint8_t *)keybuf, sizeof(keybuf)); - attach_serial(); -} - -// Overrides the weakly linked function from supervisor/shared/serial.c -void board_serial_init(void) { - cardputer_keyboard_init(); -} - -// Overrides the weakly linked function from supervisor/shared/serial.c -bool board_serial_connected(void) { - return cardputer_keyboard_serial_attached; -} - -// Overrides the weakly linked function from supervisor/shared/serial.c -uint32_t board_serial_bytes_available(void) { - if (cardputer_keyboard_serial_attached) { - return ringbuf_num_filled(&keyqueue); - } else { - return 0; - } -} - -// Overrides the weakly linked function from supervisor/shared/serial.c -char board_serial_read(void) { - if (cardputer_keyboard_serial_attached) { - return ringbuf_get(&keyqueue); - } else { - return 0; - } -} - -void keyboard_seq(const char *seq) { - while (*seq) { - ringbuf_put(&keyqueue, *seq++); - } -} - -void update_keyboard(keypad_eventqueue_obj_t *queue) { - uint8_t ascii = 0; - - if (common_hal_keypad_eventqueue_get_length(queue) == 0) { - return; - } - - while (common_hal_keypad_eventqueue_get_into(queue, &event)) { - if (event.pressed) { - keystate[event.key_number] = 1; - - if (keystate[KEY_CTRL]) { - if (keystate[KEY_ALT] && keystate[KEY_BACKSPACE]) { - reload_initiate(RUN_REASON_REPL_RELOAD); - } - ascii = keymap[event.key_number]; - if (ascii >= 'a' && ascii <= 'z') { - ascii -= 'a' - 1; - } - - if (ascii == mp_interrupt_char) { - mp_sched_keyboard_interrupt(); - } - } else if (keystate[KEY_SHIFT]) { - ascii = keymap_shifted[event.key_number]; - } else if (keystate[KEY_FN] && event.key_number != KEY_FN) { - switch (event.key_number | FN_MOD) - { - case KEY_DOWN: - keyboard_seq("\e[B"); - break; - case KEY_UP: - keyboard_seq("\e[A"); - break; - case KEY_DELETE: - keyboard_seq("\e[3~"); - break; - case KEY_LEFT: - keyboard_seq("\e[D"); - break; - case KEY_RIGHT: - keyboard_seq("\e[C"); - break; - case KEY_ESC: - ringbuf_put(&keyqueue, '\e'); - break; - } - } else { - ascii = keymap[event.key_number]; - } - - if (ascii > 0) { - if (keystate[KEY_ALT]) { - ringbuf_put(&keyqueue, '\e'); - } else if (keystate[KEY_OPT]) { - ringbuf_put(&keyqueue, '\x10'); - } - ringbuf_put(&keyqueue, ascii); - } - } else { - keystate[event.key_number] = 0; - } - } -} - -static const mp_rom_map_elem_t cardputer_keyboard_module_globals_table[] = { - {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cardputer_keyboard)}, - {MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard_obj)}, - {MP_ROM_QSTR(MP_QSTR_attach_serial), MP_ROM_PTR(&attach_serial_obj)}, - {MP_ROM_QSTR(MP_QSTR_detach_serial), MP_ROM_PTR(&detach_serial_obj)}, - {MP_ROM_QSTR(MP_QSTR_key_to_char), MP_ROM_PTR(&key_to_char_obj)}, -}; -MP_DEFINE_CONST_DICT(cardputer_keyboard_module_globals, cardputer_keyboard_module_globals_table); - -const mp_obj_module_t cardputer_keyboard_module = { - .base = {&mp_type_module}, - .globals = (mp_obj_dict_t *)&cardputer_keyboard_module_globals, -}; - -MP_REGISTER_MODULE(MP_QSTR_cardputer_keyboard, cardputer_keyboard_module); diff --git a/ports/espressif/boards/m5stack_cardputer_ros/keymap.h b/ports/espressif/boards/m5stack_cardputer_ros/keymap.h deleted file mode 100644 index 0256fafaa0f57..0000000000000 --- a/ports/espressif/boards/m5stack_cardputer_ros/keymap.h +++ /dev/null @@ -1,214 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries -// -// SPDX-License-Identifier: MIT - -#pragma once - -#define SHIFT_MOD 0x40 -#define FN_MOD 0x80 - -#define KEY_OPT 0 -#define KEY_Z 1 -#define KEY_C 2 -#define KEY_B 3 -#define KEY_M 4 -#define KEY_DOT 5 -#define KEY_SPACE 6 -#define KEY_SHIFT 7 -#define KEY_S 8 -#define KEY_F 9 -#define KEY_H 10 -#define KEY_K 11 -#define KEY_SEMICOLON 12 -#define KEY_ENTER 13 -#define KEY_Q 14 -#define KEY_E 15 -#define KEY_T 16 -#define KEY_U 17 -#define KEY_O 18 -#define KEY_LEFT_BRACKET 19 -#define KEY_BACKSLASH 20 -#define KEY_1 21 -#define KEY_3 22 -#define KEY_5 23 -#define KEY_7 24 -#define KEY_9 25 -#define KEY_UNDERSCORE 26 -#define KEY_BACKSPACE 27 -#define KEY_CTRL 28 -#define KEY_ALT 29 -#define KEY_X 30 -#define KEY_V 31 -#define KEY_N 32 -#define KEY_COMMA 33 -#define KEY_SLASH 34 -#define KEY_FN 35 -#define KEY_A 36 -#define KEY_D 37 -#define KEY_G 38 -#define KEY_J 39 -#define KEY_L 40 -#define KEY_APOSTROPHE 41 -#define KEY_TAB 42 -#define KEY_W 43 -#define KEY_R 44 -#define KEY_Y 45 -#define KEY_I 46 -#define KEY_P 47 -#define KEY_RIGHT_BRACKET 48 -#define KEY_GRAVE 49 -#define KEY_2 50 -#define KEY_4 51 -#define KEY_6 52 -#define KEY_8 53 -#define KEY_0 54 -#define KEY_EQUALS 55 - -#define KEY_GREATER (5 | SHIFT_MOD) -#define KEY_COLON (12 | SHIFT_MOD) -#define KEY_LEFT_CURLY_BRACKET (19 | SHIFT_MOD) -#define KEY_PIPE (20 | SHIFT_MOD) -#define KEY_EXCLAMATION (21 | SHIFT_MOD) -#define KEY_HASH (22 | SHIFT_MOD) -#define KEY_PERCENT (23 | SHIFT_MOD) -#define KEY_AMPERSAND (24 | SHIFT_MOD) -#define KEY_OPEN_PARENTHESIS (25 | SHIFT_MOD) -#define KEY_MINUS (26 | SHIFT_MOD) -#define KEY_LESS (33 | SHIFT_MOD) -#define KEY_QUESTION (34 | SHIFT_MOD) -#define KEY_DOUBLE_QUOTE (41 | SHIFT_MOD) -#define KEY_RIGHT_CURLY_BRACKET (48 | SHIFT_MOD) -#define KEY_TILDE (49 | SHIFT_MOD) -#define KEY_AT (50 | SHIFT_MOD) -#define KEY_DOLLAR (51 | SHIFT_MOD) -#define KEY_CARET (52 | SHIFT_MOD) -#define KEY_ASTERISK (53 | SHIFT_MOD) -#define KEY_CLOSE_PARENTHESIS (54 | SHIFT_MOD) -#define KEY_PLUS (55 | SHIFT_MOD) - -#define KEY_DOWN (5 | FN_MOD) -#define KEY_UP (12 | FN_MOD) -#define KEY_DELETE (27 | FN_MOD) -#define KEY_LEFT (33 | FN_MOD) -#define KEY_RIGHT (34 | FN_MOD) -#define KEY_ESC (49 | FN_MOD) - -const char keymap[56] = { - 0, // KEY_OPT - 'z', // KEY_Z - 'c', // KEY_C - 'b', // KEY_B - 'm', // KEY_M - '.', // KEY_DOT - ' ', // KEY_SPACE - 0, // KEY_SHIFT - 's', // KEY_S - 'f', // KEY_F - 'h', // KEY_H - 'k', // KEY_K - ';', // KEY_SEMICOLON - '\r',// KEY_ENTER - 'q', // KEY_Q - 'e', // KEY_E - 't', // KEY_T - 'u', // KEY_U - 'o', // KEY_O - '[', // KEY_LEFT_BRACKET - '\\',// KEY_BACKSLASH - '1', // KEY_1 - '3', // KEY_3 - '5', // KEY_5 - '7', // KEY_7 - '9', // KEY_9 - '_', // KEY_UNDERSCORE - '\b',// KEY_BACKSPACE - 0, // KEY_CTRL - 0, // KEY_ALT - 'x', // KEY_X - 'v', // KEY_V - 'n', // KEY_N - ',', // KEY_COMMA - '/', // KEY_SLASH - 0, // KEY_FN - 'a', // KEY_A - 'd', // KEY_D - 'g', // KEY_G - 'j', // KEY_J - 'l', // KEY_L - '\'',// KEY_APOSTROPHE - '\t',// KEY_TAB - 'w', // KEY_W - 'r', // KEY_R - 'y', // KEY_Y - 'i', // KEY_I - 'p', // KEY_P - ']', // KEY_RIGHT_BRACKET - '`', // KEY_GRAVE - '2', // KEY_2 - '4', // KEY_4 - '6', // KEY_6 - '8', // KEY_8 - '0', // KEY_0 - '=' // KEY_EQUALS -}; - -const char keymap_shifted[56] = { - 0, // KEY_OPT - 'Z', // KEY_Z - 'C', // KEY_C - 'B', // KEY_B - 'M', // KEY_M - '>', // KEY_DOT -> '>' - ' ', // KEY_SPACE - 0, // KEY_SHIFT - 'S', // KEY_S - 'F', // KEY_F - 'H', // KEY_H - 'K', // KEY_K - ':', // KEY_SEMICOLON -> ':' - '\r',// KEY_ENTER - 'Q', // KEY_Q - 'E', // KEY_E - 'T', // KEY_T - 'U', // KEY_U - 'O', // KEY_O - '{', // KEY_LEFT_BRACKET -> '{' - '|', // KEY_BACKSLASH -> '|' - '!', // KEY_1 -> '!' - '#', // KEY_3 -> '#' - '%', // KEY_5 -> '%' - '&', // KEY_7 -> '&' - '(', // KEY_9 -> '(' - '-', // KEY_UNDERSCORE -> '-' - '\b',// KEY_BACKSPACE - 0, // KEY_CTRL - 0, // KEY_ALT - 'X', // KEY_X - 'V', // KEY_V - 'N', // KEY_N - '<', // KEY_COMMA -> '<' - '?', // KEY_SLASH -> '?' - 0, // KEY_FN - 'A', // KEY_A - 'D', // KEY_D - 'G', // KEY_G - 'J', // KEY_J - 'L', // KEY_L - '"', // KEY_APOSTROPHE -> '"' - '\t',// KEY_TAB - 'W', // KEY_W - 'R', // KEY_R - 'Y', // KEY_Y - 'I', // KEY_I - 'P', // KEY_P - '}', // KEY_RIGHT_BRACKET -> '}' - '~', // KEY_GRAVE -> '~' - '@', // KEY_2 -> '@' - '$', // KEY_4 -> '$' - '^', // KEY_6 -> '^' - '*', // KEY_8 -> '*' - ')', // KEY_0 -> ')' - '+' // KEY_EQUALS -> '+' -}; diff --git a/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk index 573f947f0a8f5..ede48c2f01523 100644 --- a/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk @@ -15,4 +15,4 @@ CIRCUITPY_RCLCPY = 1 CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_MAX3421E = 0 -SRC_C += boards/$(BOARD)/cardputer_keyboard.c +SRC_C += module/cardputer_keyboard.c diff --git a/ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c b/ports/espressif/module/cardputer_keyboard.c similarity index 83% rename from ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c rename to ports/espressif/module/cardputer_keyboard.c index 73880f66e19d9..548275001acc5 100644 --- a/ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c +++ b/ports/espressif/module/cardputer_keyboard.c @@ -16,7 +16,7 @@ #include "shared-module/keypad_demux/DemuxKeyMatrix.h" #include "supervisor/shared/reload.h" -#include "keymap.h" +#include "cardputer_keymap.h" //| """M5Stack Cardputer keyboard integration. //| """ @@ -31,12 +31,13 @@ //| """" //| KEYBOARD: keypad_demux.DemuxKeymatrix //| -keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard_obj; -bool cardputer_keyboard_serial_attached = false; -void cardputer_keyboard_init(void); -void keyboard_seq(const char *seq); -void update_keyboard(keypad_eventqueue_obj_t *queue); +keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard; +static bool cardputer_keyboard_serial_attached = false; + +// Forward declarations. +static void keyboard_seq(const char *seq); +static void update_keyboard(keypad_eventqueue_obj_t *queue); //| def detach_serial() -> None: //| """Stops consuming keyboard events and routing them to sys.stdin.""" @@ -44,7 +45,7 @@ void update_keyboard(keypad_eventqueue_obj_t *queue); //| static mp_obj_t detach_serial(void) { cardputer_keyboard_serial_attached = false; - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, NULL); + common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard.events, NULL); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial); @@ -54,7 +55,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial); //| ... //| static mp_obj_t attach_serial(void) { - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, update_keyboard); + common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard.events, update_keyboard); cardputer_keyboard_serial_attached = true; return mp_const_none; } @@ -79,20 +80,20 @@ static mp_obj_t key_to_char(mp_obj_t key_obj, mp_obj_t shifted_obj) { static MP_DEFINE_CONST_FUN_OBJ_2(key_to_char_obj, key_to_char); // Ring buffer of characters consumed from keyboard events (when serial attached) -ringbuf_t keyqueue; -char keybuf[32]; +static ringbuf_t keyqueue; +static char keybuf[32]; keypad_event_obj_t event; -char keystate[56]; +static char keystate[56] = {0}; // Keyboard pins -const mcu_pin_obj_t *row_addr_pins[] = { +static const mcu_pin_obj_t *row_addr_pins[] = { &pin_GPIO8, &pin_GPIO9, &pin_GPIO11, }; -const mcu_pin_obj_t *column_pins[] = { +static const mcu_pin_obj_t *column_pins[] = { &pin_GPIO13, &pin_GPIO15, &pin_GPIO3, @@ -102,22 +103,22 @@ const mcu_pin_obj_t *column_pins[] = { &pin_GPIO7 }; -void cardputer_keyboard_init(void) { - cardputer_keyboard_obj.base.type = &keypad_demux_demuxkeymatrix_type; +static void cardputer_keyboard_init(void) { common_hal_keypad_demux_demuxkeymatrix_construct( - &cardputer_keyboard_obj, // self - 3, // num_row_addr_pins - row_addr_pins, // row_addr_pins - 7, // num_column_pins - column_pins, // column_pins - true, // columns_to_anodes - false, // transpose - 0.01f, // interval - 20, // max_events - 2 // debounce_threshold + &cardputer_keyboard, // self + MP_ARRAY_SIZE(row_addr_pins), // num_row_addr_pins + row_addr_pins, // row_addr_pins + MP_ARRAY_SIZE(column_pins), // num_column_pins + column_pins, // column_pins + true, // columns_to_anodes + false, // transpose + 0.01f, // interval + 20, // max_events + 2, // debounce_threshold + false // use_gc_allocator ); - demuxkeymatrix_never_reset(&cardputer_keyboard_obj); + demuxkeymatrix_never_reset(&cardputer_keyboard); ringbuf_init(&keyqueue, (uint8_t *)keybuf, sizeof(keybuf)); attach_serial(); } @@ -150,13 +151,13 @@ char board_serial_read(void) { } } -void keyboard_seq(const char *seq) { +static void keyboard_seq(const char *seq) { while (*seq) { ringbuf_put(&keyqueue, *seq++); } } -void update_keyboard(keypad_eventqueue_obj_t *queue) { +static void update_keyboard(keypad_eventqueue_obj_t *queue) { uint8_t ascii = 0; if (common_hal_keypad_eventqueue_get_length(queue) == 0) { @@ -223,7 +224,7 @@ void update_keyboard(keypad_eventqueue_obj_t *queue) { static const mp_rom_map_elem_t cardputer_keyboard_module_globals_table[] = { {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cardputer_keyboard)}, - {MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard_obj)}, + {MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard)}, {MP_ROM_QSTR(MP_QSTR_attach_serial), MP_ROM_PTR(&attach_serial_obj)}, {MP_ROM_QSTR(MP_QSTR_detach_serial), MP_ROM_PTR(&detach_serial_obj)}, {MP_ROM_QSTR(MP_QSTR_key_to_char), MP_ROM_PTR(&key_to_char_obj)}, diff --git a/ports/espressif/boards/m5stack_cardputer/keymap.h b/ports/espressif/module/cardputer_keymap.h similarity index 100% rename from ports/espressif/boards/m5stack_cardputer/keymap.h rename to ports/espressif/module/cardputer_keymap.h diff --git a/py/objtuple.c b/py/objtuple.c index 42e8d56a806cc..e0b31edaf2376 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -250,6 +250,9 @@ MP_DEFINE_CONST_OBJ_TYPE( // the zero-length tuple const mp_obj_tuple_t mp_const_empty_tuple_obj = {{&mp_type_tuple}, 0}; +// CIRCUITPY-CHANGE: No change here, but implementation was copied for +// mp_obj_new_port_tuple in supervisor/shared/port.c, which allocates using port_malloc(). +// Change that to match if this changes. mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { if (n == 0) { return mp_const_empty_tuple; diff --git a/shared-bindings/keypad/EventQueue.h b/shared-bindings/keypad/EventQueue.h index 893165e3220f1..02c3414b0764c 100644 --- a/shared-bindings/keypad/EventQueue.h +++ b/shared-bindings/keypad/EventQueue.h @@ -11,7 +11,7 @@ extern const mp_obj_type_t keypad_eventqueue_type; -void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events); +void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events, bool use_gc_allocator); void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self); size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self); diff --git a/shared-bindings/keypad_demux/DemuxKeyMatrix.c b/shared-bindings/keypad_demux/DemuxKeyMatrix.c index d76a20aec9d01..f1b5ecae9ceb6 100644 --- a/shared-bindings/keypad_demux/DemuxKeyMatrix.c +++ b/shared-bindings/keypad_demux/DemuxKeyMatrix.c @@ -123,7 +123,8 @@ static mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type, column_pins_array[column] = pin; } - common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, args[ARG_transpose].u_bool, interval, max_events, debounce_threshold); + // Last arg is use_gc_allocator, true during VM use. + common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, args[ARG_transpose].u_bool, interval, max_events, debounce_threshold, true); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/keypad_demux/DemuxKeyMatrix.h b/shared-bindings/keypad_demux/DemuxKeyMatrix.h index 8bdaa597dc035..25d36283e90fc 100644 --- a/shared-bindings/keypad_demux/DemuxKeyMatrix.h +++ b/shared-bindings/keypad_demux/DemuxKeyMatrix.h @@ -11,7 +11,7 @@ extern const mp_obj_type_t keypad_demux_demuxkeymatrix_type; -void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold); +void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator); void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self); diff --git a/shared-module/keypad/EventQueue.c b/shared-module/keypad/EventQueue.c index e5b362a045ddf..3130d8b59a1d7 100644 --- a/shared-module/keypad/EventQueue.c +++ b/shared-module/keypad/EventQueue.c @@ -15,9 +15,14 @@ #define EVENT_SIZE_BYTES (sizeof(uint16_t) + sizeof(mp_obj_t)) -void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events) { +void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events, bool use_gc_allocator) { // Event queue is 16-bit values. - ringbuf_alloc(&self->encoded_events, max_events * EVENT_SIZE_BYTES); + const size_t size = max_events * EVENT_SIZE_BYTES; + if (use_gc_allocator) { + ringbuf_alloc(&self->encoded_events, size); + } else { + ringbuf_init(&self->encoded_events, port_malloc(size, false), size); + } self->overflowed = false; self->event_handler = NULL; } diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index 67a5546853552..28830f591b129 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -56,7 +56,7 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint self->columns_to_anodes = columns_to_anodes; self->funcs = &keymatrix_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) { diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index 39d50f95e3238..80dcf36e163ad 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -41,7 +41,7 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin self->value_when_pressed = value_when_pressed; self->funcs = &keys_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index 97917434ff81b..aa0c14dd36b50 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -71,7 +71,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ self->value_when_pressed = value_when_pressed; self->funcs = &shiftregisterkeys_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self) { diff --git a/shared-module/keypad/__init__.c b/shared-module/keypad/__init__.c index 3ffa0433174cf..f1d5d395df789 100644 --- a/shared-module/keypad/__init__.c +++ b/shared-module/keypad/__init__.c @@ -85,14 +85,20 @@ void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) { supervisor_release_lock(&keypad_scanners_linked_list_lock); } -void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) { +void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator) { size_t key_count = common_hal_keypad_generic_get_key_count(self); - self->debounce_counter = (int8_t *)m_malloc_without_collect(sizeof(int8_t) * key_count); + self->debounce_counter = + use_gc_allocator + ? (int8_t *)m_malloc_without_collect(sizeof(int8_t) * key_count) + : (int8_t *)port_malloc_zero(sizeof(int8_t) * key_count, false); self->interval_ticks = (mp_uint_t)(interval * 1024); // interval * 1000 * (1024/1000) - keypad_eventqueue_obj_t *events = mp_obj_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type); - common_hal_keypad_eventqueue_construct(events, max_events); + keypad_eventqueue_obj_t *events = + use_gc_allocator + ? mp_obj_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type) + : mp_obj_port_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type); + common_hal_keypad_eventqueue_construct(events, max_events, use_gc_allocator); self->events = events; self->debounce_threshold = debounce_threshold; diff --git a/shared-module/keypad/__init__.h b/shared-module/keypad/__init__.h index a7d21753f6625..66fea4878543b 100644 --- a/shared-module/keypad/__init__.h +++ b/shared-module/keypad/__init__.h @@ -39,7 +39,7 @@ void keypad_reset(void); void keypad_register_scanner(keypad_scanner_obj_t *scanner); void keypad_deregister_scanner(keypad_scanner_obj_t *scanner); -void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events, uint8_t debounce_cycles); +void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events, uint8_t debounce_cycles, bool use_gc_allocator); bool keypad_debounce(keypad_scanner_obj_t *self, mp_uint_t key_number, bool current); void keypad_never_reset(keypad_scanner_obj_t *self); diff --git a/shared-module/keypad_demux/DemuxKeyMatrix.c b/shared-module/keypad_demux/DemuxKeyMatrix.c index b90669d772fcd..329f7679d3f76 100644 --- a/shared-module/keypad_demux/DemuxKeyMatrix.c +++ b/shared-module/keypad_demux/DemuxKeyMatrix.c @@ -31,38 +31,45 @@ static mp_uint_t row_column_to_key_number(keypad_demux_demuxkeymatrix_obj_t *sel return row * common_hal_keypad_demux_demuxkeymatrix_get_column_count(self) + column; } -void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) { - +void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator) { // the multiplexed pins are outputs so we can set the address for the target row // the sense of the address pins themselves doesn't change with columns_to_anodes // but the value output on the selected row line will be !columns_to_anodes mp_obj_t row_addr_dios[num_row_addr_pins]; for (size_t row = 0; row < num_row_addr_pins; row++) { digitalio_digitalinout_obj_t *dio = - mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); + use_gc_allocator + ? mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type) + : mp_obj_port_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, row_addr_pins[row]); common_hal_digitalio_digitalinout_switch_to_output(dio, false, DRIVE_MODE_PUSH_PULL); row_addr_dios[row] = dio; } - self->row_addr_digitalinouts = mp_obj_new_tuple(num_row_addr_pins, row_addr_dios); + self->row_addr_digitalinouts = + use_gc_allocator + ? mp_obj_new_tuple(num_row_addr_pins, row_addr_dios) + : mp_obj_new_port_tuple(num_row_addr_pins, row_addr_dios); // the column pins are always inputs, with default state based on columns_to_anodes mp_obj_t column_dios[num_column_pins]; for (size_t column = 0; column < num_column_pins; column++) { digitalio_digitalinout_obj_t *dio = - mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); - dio->base.type = &digitalio_digitalinout_type; + use_gc_allocator + ? mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type) + : mp_obj_port_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, column_pins[column]); common_hal_digitalio_digitalinout_switch_to_input(dio, columns_to_anodes ? PULL_UP : PULL_DOWN); column_dios[column] = dio; } - self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios); - + self->column_digitalinouts = + use_gc_allocator + ? mp_obj_new_tuple(num_column_pins, column_dios) + : mp_obj_new_port_tuple(num_column_pins, column_dios); self->columns_to_anodes = columns_to_anodes; self->transpose = transpose; self->funcs = &keymatrix_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, use_gc_allocator); } void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self) { diff --git a/supervisor/board.h b/supervisor/board.h index 0920bf4e5777b..1200eccc9b68c 100644 --- a/supervisor/board.h +++ b/supervisor/board.h @@ -25,3 +25,10 @@ void reset_board(void); // state. It should not prevent the user access method from working (such as // disabling USB, BLE or flash) because CircuitPython may continue to run. void board_deinit(void); + +// Initialization for individual boards when a VM starts. +void mp_board_init(void); + +// Some boards may want to mark additional pointers as gc roots. +// A default weak implementation is provided that does nothing. +void board_gc_collect(void); diff --git a/supervisor/port.h b/supervisor/port.h index cc49538218fac..0bf8fd8d01350 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -9,6 +9,7 @@ #include #include +#include "py/obj.h" #include "supervisor/shared/safe_mode.h" // Provided by the linker; @@ -107,3 +108,10 @@ void port_gc_collect(void); // this function to sense the button. Ports that need to can override this // function to provide their own implementation. bool port_boot_button_pressed(void); + +// Allocating objects on the port heap, not the VM heap. +#define mp_obj_port_malloc(struct_type, obj_type) ((struct_type *)mp_obj_port_malloc_helper(sizeof(struct_type), obj_type)) +#define mp_obj_port_malloc_var(struct_type, var_field, var_type, var_num, obj_type) ((struct_type *)mp_obj_port_malloc_helper(offsetof(struct_type, var_field) + sizeof(var_type) * (var_num), obj_type)) + +void *mp_obj_port_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); +mp_obj_t mp_obj_new_port_tuple(size_t n, const mp_obj_t *items); diff --git a/supervisor/port_heap.h b/supervisor/port_heap.h index 07a3c884e241e..40abd21438741 100644 --- a/supervisor/port_heap.h +++ b/supervisor/port_heap.h @@ -21,6 +21,7 @@ void port_heap_init(void); void *port_malloc(size_t size, bool dma_capable); +void *port_malloc_zero(size_t size, bool dma_capable); void port_free(void *ptr); diff --git a/supervisor/shared/board.c b/supervisor/shared/board.c index 192bf7a65c806..40bc1e45a1049 100644 --- a/supervisor/shared/board.c +++ b/supervisor/shared/board.c @@ -44,3 +44,11 @@ MP_WEAK void board_deinit(void) { // Do-nothing so not all boards need to provide this function. MP_WEAK void reset_board(void) { } + +// Do-nothing so not all boards need to provide this function. +MP_WEAK void mp_board_init(void) { +} + +// Do-nothing so not all boards need to provide this function. +MP_WEAK void board_gc_collect(void) { +} diff --git a/supervisor/shared/port.c b/supervisor/shared/port.c index 3b9f0c8718161..aabf003fb302d 100644 --- a/supervisor/shared/port.c +++ b/supervisor/shared/port.c @@ -43,6 +43,15 @@ MP_WEAK void *port_malloc(size_t size, bool dma_capable) { return block; } +// Ensure allocated memory is zero. +MP_WEAK void *port_malloc_zero(size_t size, bool dma_capable) { + void *ptr = port_malloc(size, dma_capable); + if (ptr) { + memset(ptr, 0, size); + } + return ptr; +} + MP_WEAK void port_free(void *ptr) { tlsf_free(heap, ptr); } @@ -80,3 +89,30 @@ MP_WEAK bool port_boot_button_pressed(void) { return false; #endif } + +// Ports may provide an implementation of this function if it is needed +MP_WEAK void port_gc_collect(void) { +} + +// Allocates an object in the port heap, not the VM heap, and also sets type, for mp_obj_malloc{,_var} macros. +MP_NOINLINE void *mp_obj_port_malloc_helper(size_t num_bytes, const mp_obj_type_t *type) { + mp_obj_base_t *base = (mp_obj_base_t *)port_malloc_zero(num_bytes, false); + base->type = type; + return base; +} + +// Creates a tuple on the port heap, not the VM heap. +// Implementation copied from py/objtuple.c. +mp_obj_t mp_obj_new_port_tuple(size_t n, const mp_obj_t *items) { + if (n == 0) { + return mp_const_empty_tuple; + } + mp_obj_tuple_t *o = mp_obj_port_malloc_var(mp_obj_tuple_t, items, mp_obj_t, n, &mp_type_tuple); + o->len = n; + if (items) { + for (size_t i = 0; i < n; i++) { + o->items[i] = items[i]; + } + } + return MP_OBJ_FROM_PTR(o); +} From 1d8352845684fefb22fd888bcf255ef23dc28791 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 9 May 2025 14:34:09 +1000 Subject: [PATCH 078/208] lib/littlefs: Fix string initializer in lfs1.c. Avoids the new Wunterminated-string-literal when compiled with gcc 15.1. It would be preferable to just disable this warning, but Clang -Wunknown-warning-option kicks in even when disabling warnings so this becomes fiddly to apply. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- lib/littlefs/lfs1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/littlefs/lfs1.c b/lib/littlefs/lfs1.c index 6a3fd670012cc..ec18dc470258c 100644 --- a/lib/littlefs/lfs1.c +++ b/lib/littlefs/lfs1.c @@ -2141,7 +2141,7 @@ int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *cfg) { .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, .d.nlen = sizeof(superblock.d.magic), .d.version = LFS1_DISK_VERSION, - .d.magic = {"littlefs"}, + .d.magic = {'l', 'i', 't', 't', 'l', 'e', 'f', 's'}, .d.block_size = lfs1->cfg->block_size, .d.block_count = lfs1->cfg->block_count, .d.root = {lfs1->root[0], lfs1->root[1]}, From 1630f215b709da2c98a4aa521833b1ccbf7e0c3d Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 9 May 2025 13:36:05 +1000 Subject: [PATCH 079/208] py/emitinlinethumb: Refactor string literal as array initializer. Avoids the new Wunterminated-string-literal when compiled with gcc 15.1. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- py/emitinlinethumb.c | 108 +++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 7818bb4f46da8..d6596337ae5a6 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -150,27 +150,27 @@ typedef struct _reg_name_t { byte reg; byte name[3]; } reg_name_t; static const reg_name_t reg_name_table[] = { - {0, "r0\0"}, - {1, "r1\0"}, - {2, "r2\0"}, - {3, "r3\0"}, - {4, "r4\0"}, - {5, "r5\0"}, - {6, "r6\0"}, - {7, "r7\0"}, - {8, "r8\0"}, - {9, "r9\0"}, - {10, "r10"}, - {11, "r11"}, - {12, "r12"}, - {13, "r13"}, - {14, "r14"}, - {15, "r15"}, - {10, "sl\0"}, - {11, "fp\0"}, - {13, "sp\0"}, - {14, "lr\0"}, - {15, "pc\0"}, + {0, {'r', '0' }}, + {1, {'r', '1' }}, + {2, {'r', '2' }}, + {3, {'r', '3' }}, + {4, {'r', '4' }}, + {5, {'r', '5' }}, + {6, {'r', '6' }}, + {7, {'r', '7' }}, + {8, {'r', '8' }}, + {9, {'r', '9' }}, + {10, {'r', '1', '0' }}, + {11, {'r', '1', '1' }}, + {12, {'r', '1', '2' }}, + {13, {'r', '1', '3' }}, + {14, {'r', '1', '4' }}, + {15, {'r', '1', '5' }}, + {10, {'s', 'l' }}, + {11, {'f', 'p' }}, + {13, {'s', 'p' }}, + {14, {'l', 'r' }}, + {15, {'p', 'c' }}, }; #define MAX_SPECIAL_REGISTER_NAME_LENGTH 7 @@ -368,20 +368,20 @@ typedef struct _cc_name_t { byte cc; byte name[2]; } cc_name_t; static const cc_name_t cc_name_table[] = { - { ASM_THUMB_CC_EQ, "eq" }, - { ASM_THUMB_CC_NE, "ne" }, - { ASM_THUMB_CC_CS, "cs" }, - { ASM_THUMB_CC_CC, "cc" }, - { ASM_THUMB_CC_MI, "mi" }, - { ASM_THUMB_CC_PL, "pl" }, - { ASM_THUMB_CC_VS, "vs" }, - { ASM_THUMB_CC_VC, "vc" }, - { ASM_THUMB_CC_HI, "hi" }, - { ASM_THUMB_CC_LS, "ls" }, - { ASM_THUMB_CC_GE, "ge" }, - { ASM_THUMB_CC_LT, "lt" }, - { ASM_THUMB_CC_GT, "gt" }, - { ASM_THUMB_CC_LE, "le" }, + { ASM_THUMB_CC_EQ, { 'e', 'q' }}, + { ASM_THUMB_CC_NE, { 'n', 'e' }}, + { ASM_THUMB_CC_CS, { 'c', 's' }}, + { ASM_THUMB_CC_CC, { 'c', 'c' }}, + { ASM_THUMB_CC_MI, { 'm', 'i' }}, + { ASM_THUMB_CC_PL, { 'p', 'l' }}, + { ASM_THUMB_CC_VS, { 'v', 's' }}, + { ASM_THUMB_CC_VC, { 'v', 'c' }}, + { ASM_THUMB_CC_HI, { 'h', 'i' }}, + { ASM_THUMB_CC_LS, { 'l', 's' }}, + { ASM_THUMB_CC_GE, { 'g', 'e' }}, + { ASM_THUMB_CC_LT, { 'l', 't' }}, + { ASM_THUMB_CC_GT, { 'g', 't' }}, + { ASM_THUMB_CC_LE, { 'l', 'e' }}, }; typedef struct _format_4_op_t { byte op; @@ -389,21 +389,21 @@ typedef struct _format_4_op_t { byte op; } format_4_op_t; #define X(x) (((x) >> 4) & 0xff) // only need 1 byte to distinguish these ops static const format_4_op_t format_4_op_table[] = { - { X(ASM_THUMB_FORMAT_4_EOR), "eor" }, - { X(ASM_THUMB_FORMAT_4_LSL), "lsl" }, - { X(ASM_THUMB_FORMAT_4_LSR), "lsr" }, - { X(ASM_THUMB_FORMAT_4_ASR), "asr" }, - { X(ASM_THUMB_FORMAT_4_ADC), "adc" }, - { X(ASM_THUMB_FORMAT_4_SBC), "sbc" }, - { X(ASM_THUMB_FORMAT_4_ROR), "ror" }, - { X(ASM_THUMB_FORMAT_4_TST), "tst" }, - { X(ASM_THUMB_FORMAT_4_NEG), "neg" }, - { X(ASM_THUMB_FORMAT_4_CMP), "cmp" }, - { X(ASM_THUMB_FORMAT_4_CMN), "cmn" }, - { X(ASM_THUMB_FORMAT_4_ORR), "orr" }, - { X(ASM_THUMB_FORMAT_4_MUL), "mul" }, - { X(ASM_THUMB_FORMAT_4_BIC), "bic" }, - { X(ASM_THUMB_FORMAT_4_MVN), "mvn" }, + { X(ASM_THUMB_FORMAT_4_EOR), {'e', 'o', 'r' }}, + { X(ASM_THUMB_FORMAT_4_LSL), {'l', 's', 'l' }}, + { X(ASM_THUMB_FORMAT_4_LSR), {'l', 's', 'r' }}, + { X(ASM_THUMB_FORMAT_4_ASR), {'a', 's', 'r' }}, + { X(ASM_THUMB_FORMAT_4_ADC), {'a', 'd', 'c' }}, + { X(ASM_THUMB_FORMAT_4_SBC), {'s', 'b', 'c' }}, + { X(ASM_THUMB_FORMAT_4_ROR), {'r', 'o', 'r' }}, + { X(ASM_THUMB_FORMAT_4_TST), {'t', 's', 't' }}, + { X(ASM_THUMB_FORMAT_4_NEG), {'n', 'e', 'g' }}, + { X(ASM_THUMB_FORMAT_4_CMP), {'c', 'm', 'p' }}, + { X(ASM_THUMB_FORMAT_4_CMN), {'c', 'm', 'n' }}, + { X(ASM_THUMB_FORMAT_4_ORR), {'o', 'r', 'r' }}, + { X(ASM_THUMB_FORMAT_4_MUL), {'m', 'u', 'l' }}, + { X(ASM_THUMB_FORMAT_4_BIC), {'b', 'i', 'c' }}, + { X(ASM_THUMB_FORMAT_4_MVN), {'m', 'v', 'n' }}, }; #undef X @@ -428,10 +428,10 @@ typedef struct _format_vfp_op_t { char name[3]; } format_vfp_op_t; static const format_vfp_op_t format_vfp_op_table[] = { - { 0x30, "add" }, - { 0x34, "sub" }, - { 0x20, "mul" }, - { 0x80, "div" }, + { 0x30, {'a', 'd', 'd' }}, + { 0x34, {'s', 'u', 'b' }}, + { 0x20, {'m', 'u', 'l' }}, + { 0x80, {'d', 'i', 'v' }}, }; // shorthand alias for whether we allow ARMv7-M instructions From 8e6cf02761e39801e9f9bca9fb7f86e724716b53 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 3 Sep 2025 12:37:56 -0400 Subject: [PATCH 080/208] Remove unused pins; group aliased pins --- .../boards/prokyber_ai_on_the_edge_cam/pins.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c index 305bdb3e0b69a..68dc40781a480 100644 --- a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c @@ -34,24 +34,32 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { // SD { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, // Ethernet { MP_ROM_QSTR(MP_QSTR_ETH_RST), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_ETH_INT), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MOSI), MP_ROM_PTR(&pin_GPIO1) }, { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MISO), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CLK), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CS), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, @@ -65,6 +73,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { // UART { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, @@ -86,8 +95,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA5), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA3), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA4), MP_ROM_PTR(&pin_GPIO8) }, - // { MP_ROM_QSTR(MP_QSTR_CAMERA_RESET), MP_ROM_PTR(&pin_GPIO47) }, - // { MP_ROM_QSTR(MP_QSTR_CAMERA_PWDN), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOD), MP_ROM_PTR(&pin_GPIO4) }, // SDA { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOC), MP_ROM_PTR(&pin_GPIO5) }, // SCL From a16137f9619e70e26bef27e3c676796f2c2ba5d9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 3 Sep 2025 14:42:49 -0400 Subject: [PATCH 081/208] sdkconfig.defaults: use standard defaults --- ports/espressif/esp-idf-config/sdkconfig.defaults | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ports/espressif/esp-idf-config/sdkconfig.defaults b/ports/espressif/esp-idf-config/sdkconfig.defaults index b54f599b2a5b7..dd766675136d9 100644 --- a/ports/espressif/esp-idf-config/sdkconfig.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig.defaults @@ -71,16 +71,6 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=0 CONFIG_LWIP_IPV6_DHCP6=y # -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=4 -CONFIG_LWIP_MAX_LISTENING_TCP=4 -CONFIG_LWIP_TCP_SYNMAXRTX=6 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=2880 -CONFIG_LWIP_TCP_WND_DEFAULT=2880 -CONFIG_LWIP_TCP_RTO_TIME=3000 -# end of TCP - # end of LWIP # From 8993356f0532c345b70f07c72e218fceea27bce9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 3 Sep 2025 19:54:33 -0400 Subject: [PATCH 082/208] remove unused mp_board_init() and board_gc_collect() per review comments --- main.c | 4 ---- supervisor/board.h | 7 ------- supervisor/shared/board.c | 8 -------- 3 files changed, 19 deletions(-) diff --git a/main.c b/main.c index cf9cf377d690b..6c8e9c8804906 100644 --- a/main.c +++ b/main.c @@ -207,9 +207,6 @@ static void start_mp(safe_mode_t safe_mode) { // Always return to root common_hal_os_chdir("/"); - - // Initialization for individual boards when a VM starts. - mp_board_init(); } static void stop_mp(void) { @@ -1152,7 +1149,6 @@ void gc_collect(void) { gc_collect_root((void **)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t)); port_gc_collect(); - board_gc_collect(); background_callback_gc_collect(); diff --git a/supervisor/board.h b/supervisor/board.h index 1200eccc9b68c..0920bf4e5777b 100644 --- a/supervisor/board.h +++ b/supervisor/board.h @@ -25,10 +25,3 @@ void reset_board(void); // state. It should not prevent the user access method from working (such as // disabling USB, BLE or flash) because CircuitPython may continue to run. void board_deinit(void); - -// Initialization for individual boards when a VM starts. -void mp_board_init(void); - -// Some boards may want to mark additional pointers as gc roots. -// A default weak implementation is provided that does nothing. -void board_gc_collect(void); diff --git a/supervisor/shared/board.c b/supervisor/shared/board.c index 40bc1e45a1049..192bf7a65c806 100644 --- a/supervisor/shared/board.c +++ b/supervisor/shared/board.c @@ -44,11 +44,3 @@ MP_WEAK void board_deinit(void) { // Do-nothing so not all boards need to provide this function. MP_WEAK void reset_board(void) { } - -// Do-nothing so not all boards need to provide this function. -MP_WEAK void mp_board_init(void) { -} - -// Do-nothing so not all boards need to provide this function. -MP_WEAK void board_gc_collect(void) { -} From eaca0bb751e2dd07deb4e1e1233f1677502580d3 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 5 Sep 2025 15:05:50 -0400 Subject: [PATCH 083/208] ports/raspberrypi/lwip_src/lwip_mem.c: put storage ops in a critical section --- ports/raspberrypi/lwip_src/lwip_mem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ports/raspberrypi/lwip_src/lwip_mem.c b/ports/raspberrypi/lwip_src/lwip_mem.c index 244f51e289bc9..d7d5468a42011 100644 --- a/ports/raspberrypi/lwip_src/lwip_mem.c +++ b/ports/raspberrypi/lwip_src/lwip_mem.c @@ -8,14 +8,20 @@ #include #include "lib/tlsf/tlsf.h" #include "lwip_mem.h" +#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/port_heap.h" void *lwip_heap_malloc(size_t size) { - return port_malloc(size, true); + common_hal_mcu_disable_interrupts(); + void *ptr = port_malloc(size, true); + common_hal_mcu_enable_interrupts(); + return ptr; } void lwip_heap_free(void *ptr) { + common_hal_mcu_disable_interrupts(); port_free(ptr); + common_hal_mcu_enable_interrupts(); } void *lwip_heap_calloc(size_t num, size_t size) { From 05db6eefb2f08e579d5c03d462e507a1ba5c8a57 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Tue, 2 Sep 2025 22:16:35 +0000 Subject: [PATCH 084/208] fix bad xfer_result_t enum values shared-module/usb/core/Device.c was using its own 0xff value for the xfer_result_t enum defined by tinyusb/src/common/tusb_types.h. The 0xff value served the same purpose as the already exisiting XFER_RESULT_INVALID enum value (a placeholder to mark in-progress transactions). This commit standardizes on XFER_RESULT_INVALID in usb.core.Device consistent with the usage in tinyusb. Making this change allows implementing `switch(result){...}` style result code checks without compiler errors about 0xff not being a valid value for the enum. --- shared-module/usb/core/Device.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index c9df0cf73805f..f6cd03ebcd40a 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -45,7 +45,7 @@ bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t d } self->device_address = device_address; self->first_langid = 0; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; return true; } @@ -91,13 +91,13 @@ static void _transfer_done_cb(tuh_xfer_t *xfer) { static bool _wait_for_callback(void) { while (!mp_hal_is_interrupted() && - _xfer_result == 0xff) { + _xfer_result == XFER_RESULT_INVALID) { // The background tasks include TinyUSB which will call the function // we provided above. In other words, the callback isn't in an interrupt. RUN_BACKGROUND_TASKS; } xfer_result_t result = _xfer_result; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; return result == XFER_RESULT_SUCCESS; } @@ -225,7 +225,7 @@ void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, m } static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; xfer->complete_cb = _transfer_done_cb; if (!tuh_edpt_xfer(xfer)) { mp_raise_usb_core_USBError(NULL); @@ -234,7 +234,7 @@ static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { uint32_t start_time = supervisor_ticks_ms32(); while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && !mp_hal_is_interrupted() && - _xfer_result == 0xff) { + _xfer_result == XFER_RESULT_INVALID) { // The background tasks include TinyUSB which will call the function // we provided above. In other words, the callback isn't in an interrupt. RUN_BACKGROUND_TASKS; @@ -244,11 +244,11 @@ static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { return 0; } xfer_result_t result = _xfer_result; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; if (result == XFER_RESULT_STALLED) { mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); } - if (result == 0xff) { + if (result == XFER_RESULT_INVALID) { tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); mp_raise_usb_core_USBTimeoutError(); } @@ -355,7 +355,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .complete_cb = _transfer_done_cb, }; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; if (!tuh_control_xfer(&xfer)) { mp_raise_usb_core_USBError(NULL); @@ -364,7 +364,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, uint32_t start_time = supervisor_ticks_ms32(); while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && !mp_hal_is_interrupted() && - _xfer_result == 0xff) { + _xfer_result == XFER_RESULT_INVALID) { // The background tasks include TinyUSB which will call the function // we provided above. In other words, the callback isn't in an interrupt. RUN_BACKGROUND_TASKS; @@ -374,11 +374,11 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, return 0; } xfer_result_t result = _xfer_result; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; if (result == XFER_RESULT_STALLED) { mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); } - if (result == 0xff) { + if (result == XFER_RESULT_INVALID) { tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); mp_raise_usb_core_USBTimeoutError(); } From b0760773077aaab556394061fde17168cbf52df3 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Tue, 2 Sep 2025 22:40:46 +0000 Subject: [PATCH 085/208] use switch for ctrl_transfer result check This directly translates the Device.ctrl_transfer() result check logic from its old if-statements to an equivalent switch-statement. The point is to make it clear how each possible result code is handled. Note that XFER_RESULT_FAILED and XFER_RESULT_TIMEOUT both return 0 without generating any exception. (but also, tinyusb may not actually use XFER_RESULT_TIMOUT if its comments are still accurate) --- shared-module/usb/core/Device.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index f6cd03ebcd40a..87d1141bfde39 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -375,17 +375,21 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, } xfer_result_t result = _xfer_result; _xfer_result = XFER_RESULT_INVALID; - if (result == XFER_RESULT_STALLED) { - mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); - } - if (result == XFER_RESULT_INVALID) { - tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); - mp_raise_usb_core_USBTimeoutError(); - } - if (result == XFER_RESULT_SUCCESS) { - return len; + switch (result) { + case XFER_RESULT_SUCCESS: + return len; + case XFER_RESULT_FAILED: + break; + case XFER_RESULT_STALLED: + mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); + break; + case XFER_RESULT_TIMEOUT: + break; + case XFER_RESULT_INVALID: + tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); + mp_raise_usb_core_USBTimeoutError(); + break; } - return 0; } From e9da6bce6dd037f4befe9c5966cd81b4960f9a7d Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Tue, 2 Sep 2025 23:02:39 +0000 Subject: [PATCH 086/208] return actual length from ctrl_transfer Previously this returned the requested transfer length argument, ignoring the actual length of transferred bytes. This changes to returning the actual length. --- shared-module/usb/core/Device.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 87d1141bfde39..517eb5f357a07 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -355,7 +355,11 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .complete_cb = _transfer_done_cb, }; + // Prepare for transfer. Unless there is a timeout, these static globals will + // get modified by the _transfer_done_cb() callback when tinyusb finishes the + // transfer or encounters an error condition. _xfer_result = XFER_RESULT_INVALID; + _actual_len = 0; if (!tuh_control_xfer(&xfer)) { mp_raise_usb_core_USBError(NULL); @@ -377,7 +381,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, _xfer_result = XFER_RESULT_INVALID; switch (result) { case XFER_RESULT_SUCCESS: - return len; + return _actual_len; case XFER_RESULT_FAILED: break; case XFER_RESULT_STALLED: From f3560f98b5527e469977b5d450b3dd813df06d1e Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Wed, 3 Sep 2025 00:41:44 +0000 Subject: [PATCH 087/208] handle XFER_RESULT_FAILED with exception Previously, usb.core.Device.ctrl_transfer() did not raise an exception when TinyUSB returned an XFER_RESULT_FAILED result code. This change raises an exception which prevents a failed transfer from returning an all zero result buffer. --- shared-module/usb/core/Device.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 517eb5f357a07..79b6775dd0c1a 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -374,22 +374,30 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, RUN_BACKGROUND_TASKS; } if (mp_hal_is_interrupted()) { + // Handle case of VM being interrupted by Ctrl-C or autoreload tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); return 0; } + // Handle control transfer result code from TinyUSB xfer_result_t result = _xfer_result; _xfer_result = XFER_RESULT_INVALID; switch (result) { case XFER_RESULT_SUCCESS: return _actual_len; case XFER_RESULT_FAILED: + mp_raise_usb_core_USBError(NULL); break; case XFER_RESULT_STALLED: mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); break; case XFER_RESULT_TIMEOUT: + // This timeout comes from TinyUSB, so assume that it has stopped the + // transfer (note: timeout logic may be unimplemented on TinyUSB side) + mp_raise_usb_core_USBTimeoutError(); break; case XFER_RESULT_INVALID: + // This timeout comes from CircuitPython, not TinyUSB, so tell TinyUSB + // to stop the transfer tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); mp_raise_usb_core_USBTimeoutError(); break; From 7d26fe986600718ac687f7bc2230c679ef3d6f2a Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Wed, 3 Sep 2025 01:50:48 +0000 Subject: [PATCH 088/208] factor out timed transfer setup & err handling The code for endpoint transfers and control transfers previously had a bunch of duplicated logic for setup, timeout checking, and result code error handling. This change factors that stuff out into functions, using my new transfer result error handling code from the last commit. Now the endpoint and control transfers can share the setup, timeout, and error check logic. For me, this refactor reduced the firmware image size by 176 bytes. --- shared-module/usb/core/Device.c | 128 ++++++++++++++------------------ 1 file changed, 57 insertions(+), 71 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 79b6775dd0c1a..f71ac8844bb73 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -101,6 +101,59 @@ static bool _wait_for_callback(void) { return result == XFER_RESULT_SUCCESS; } +static void _prepare_for_transfer(void) { + // Prepare for transfer. Unless there is a timeout, these static globals will + // get modified by the _transfer_done_cb() callback when tinyusb finishes the + // transfer or encounters an error condition. + _xfer_result = XFER_RESULT_INVALID; + _actual_len = 0; +} + +static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout) { + if (xfer == NULL) { + mp_raise_usb_core_USBError(NULL); + return 0; + } + uint32_t start_time = supervisor_ticks_ms32(); + while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && + !mp_hal_is_interrupted() && + _xfer_result == XFER_RESULT_INVALID) { + // The background tasks include TinyUSB which will call the function + // we provided above. In other words, the callback isn't in an interrupt. + RUN_BACKGROUND_TASKS; + } + if (mp_hal_is_interrupted()) { + // Handle case of VM being interrupted by Ctrl-C or autoreload + tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + return 0; + } + // Handle control transfer result code from TinyUSB + xfer_result_t result = _xfer_result; + _xfer_result = XFER_RESULT_INVALID; + switch (result) { + case XFER_RESULT_SUCCESS: + return _actual_len; + case XFER_RESULT_FAILED: + mp_raise_usb_core_USBError(NULL); + break; + case XFER_RESULT_STALLED: + mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); + break; + case XFER_RESULT_TIMEOUT: + // This timeout comes from TinyUSB, so assume that it has stopped the + // transfer (note: timeout logic may be unimplemented on TinyUSB side) + mp_raise_usb_core_USBTimeoutError(); + break; + case XFER_RESULT_INVALID: + // This timeout comes from CircuitPython, not TinyUSB, so tell TinyUSB + // to stop the transfer + tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + mp_raise_usb_core_USBTimeoutError(); + break; + } + return 0; +} + static mp_obj_t _get_string(const uint16_t *temp_buf) { size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); if (utf16_len == 0) { @@ -225,38 +278,13 @@ void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, m } static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { - _xfer_result = XFER_RESULT_INVALID; + _prepare_for_transfer(); xfer->complete_cb = _transfer_done_cb; if (!tuh_edpt_xfer(xfer)) { mp_raise_usb_core_USBError(NULL); return 0; } - uint32_t start_time = supervisor_ticks_ms32(); - while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && - !mp_hal_is_interrupted() && - _xfer_result == XFER_RESULT_INVALID) { - // The background tasks include TinyUSB which will call the function - // we provided above. In other words, the callback isn't in an interrupt. - RUN_BACKGROUND_TASKS; - } - if (mp_hal_is_interrupted()) { - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); - return 0; - } - xfer_result_t result = _xfer_result; - _xfer_result = XFER_RESULT_INVALID; - if (result == XFER_RESULT_STALLED) { - mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); - } - if (result == XFER_RESULT_INVALID) { - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); - mp_raise_usb_core_USBTimeoutError(); - } - if (result == XFER_RESULT_SUCCESS) { - return _actual_len; - } - - return 0; + return _handle_timed_transfer_callback(xfer, timeout); } static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { @@ -355,54 +383,12 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .complete_cb = _transfer_done_cb, }; - // Prepare for transfer. Unless there is a timeout, these static globals will - // get modified by the _transfer_done_cb() callback when tinyusb finishes the - // transfer or encounters an error condition. - _xfer_result = XFER_RESULT_INVALID; - _actual_len = 0; - + _prepare_for_transfer(); if (!tuh_control_xfer(&xfer)) { mp_raise_usb_core_USBError(NULL); return 0; } - uint32_t start_time = supervisor_ticks_ms32(); - while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && - !mp_hal_is_interrupted() && - _xfer_result == XFER_RESULT_INVALID) { - // The background tasks include TinyUSB which will call the function - // we provided above. In other words, the callback isn't in an interrupt. - RUN_BACKGROUND_TASKS; - } - if (mp_hal_is_interrupted()) { - // Handle case of VM being interrupted by Ctrl-C or autoreload - tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); - return 0; - } - // Handle control transfer result code from TinyUSB - xfer_result_t result = _xfer_result; - _xfer_result = XFER_RESULT_INVALID; - switch (result) { - case XFER_RESULT_SUCCESS: - return _actual_len; - case XFER_RESULT_FAILED: - mp_raise_usb_core_USBError(NULL); - break; - case XFER_RESULT_STALLED: - mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); - break; - case XFER_RESULT_TIMEOUT: - // This timeout comes from TinyUSB, so assume that it has stopped the - // transfer (note: timeout logic may be unimplemented on TinyUSB side) - mp_raise_usb_core_USBTimeoutError(); - break; - case XFER_RESULT_INVALID: - // This timeout comes from CircuitPython, not TinyUSB, so tell TinyUSB - // to stop the transfer - tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); - mp_raise_usb_core_USBTimeoutError(); - break; - } - return 0; + return (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout); } bool common_hal_usb_core_device_is_kernel_driver_active(usb_core_device_obj_t *self, mp_int_t interface) { From e8a6d38ec4396a4ed0987829e01db9deabbfc84f Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Sat, 6 Sep 2025 00:52:51 +0000 Subject: [PATCH 089/208] fix idVendor and idProduct error check Previously these weren't checking to see if TinyUSB reported a failure. Now they check. --- shared-module/usb/core/Device.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index f71ac8844bb73..df108776fd446 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -1,6 +1,7 @@ // This file is part of the CircuitPython project: https://circuitpython.org // // SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Sam Blenny // // SPDX-License-Identifier: MIT @@ -70,14 +71,18 @@ void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self) { uint16_t common_hal_usb_core_device_get_idVendor(usb_core_device_obj_t *self) { uint16_t vid; uint16_t pid; - tuh_vid_pid_get(self->device_address, &vid, &pid); + if (!tuh_vid_pid_get(self->device_address, &vid, &pid)) { + mp_raise_usb_core_USBError(NULL); + } return vid; } uint16_t common_hal_usb_core_device_get_idProduct(usb_core_device_obj_t *self) { uint16_t vid; uint16_t pid; - tuh_vid_pid_get(self->device_address, &vid, &pid); + if (!tuh_vid_pid_get(self->device_address, &vid, &pid)) { + mp_raise_usb_core_USBError(NULL); + } return pid; } From 99f244e033d08c7ae862a52e8eccc831661608ed Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Sat, 6 Sep 2025 07:46:34 +0000 Subject: [PATCH 090/208] fix comment --- shared-module/usb/core/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index df108776fd446..604e945f1db96 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -132,7 +132,7 @@ static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); return 0; } - // Handle control transfer result code from TinyUSB + // Handle transfer result code from TinyUSB xfer_result_t result = _xfer_result; _xfer_result = XFER_RESULT_INVALID; switch (result) { From ad745c2c33a9e91fcbda22b9b58a08a56eb25fc4 Mon Sep 17 00:00:00 2001 From: sam blenny <68084116+samblenny@users.noreply.github.com> Date: Sun, 7 Sep 2025 01:00:31 +0000 Subject: [PATCH 091/208] error checks for usb device string properties Improve the error handling for usb.core.Device string properties: .serial_number, .product, .manufacturer Previously, the property getters didn't check the device descriptor to see if the device actually had the requested string. Instead, they relied on TinyUSB to return a failure result if the string was not available. That made it impossible to distinguish missing strings from other more serious USB errors (e.g. unplugged device). These changes make it possible to return None for a missing string or raise a USBError exception in case of a more serious problem. --- shared-module/usb/core/Device.c | 87 ++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 604e945f1db96..c07ffda1149c9 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -101,9 +101,28 @@ static bool _wait_for_callback(void) { // we provided above. In other words, the callback isn't in an interrupt. RUN_BACKGROUND_TASKS; } + if (mp_hal_is_interrupted()) { + // Handle case of VM being interrupted by Ctrl-C or autoreload + return false; + } + // Handle callback result code from TinyUSB xfer_result_t result = _xfer_result; _xfer_result = XFER_RESULT_INVALID; - return result == XFER_RESULT_SUCCESS; + switch (result) { + case XFER_RESULT_SUCCESS: + return true; + case XFER_RESULT_FAILED: + mp_raise_usb_core_USBError(NULL); + break; + case XFER_RESULT_STALLED: + mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); + break; + case XFER_RESULT_TIMEOUT: + case XFER_RESULT_INVALID: + mp_raise_usb_core_USBTimeoutError(); + break; + } + return false; } static void _prepare_for_transfer(void) { @@ -173,41 +192,75 @@ static void _get_langid(usb_core_device_obj_t *self) { } // Two control bytes and one uint16_t language code. uint16_t temp_buf[2]; - if (!tuh_descriptor_get_string(self->device_address, 0, 0, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { - return; + _prepare_for_transfer(); + if (!tuh_descriptor_get_string(self->device_address, 0, 0, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + self->first_langid = temp_buf[1]; } - self->first_langid = temp_buf[1]; } mp_obj_t common_hal_usb_core_device_get_serial_number(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; - _get_langid(self); - if (!tuh_descriptor_get_serial_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { + return mp_const_none; + } + if (descriptor.iSerialNumber == 0) { return mp_const_none; } - return _get_string(temp_buf); + // Device does provide this string, so continue + _get_langid(self); + _prepare_for_transfer(); + if (!tuh_descriptor_get_serial_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; } mp_obj_t common_hal_usb_core_device_get_product(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; - _get_langid(self); - if (!tuh_descriptor_get_product_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { return mp_const_none; } - return _get_string(temp_buf); + if (descriptor.iProduct == 0) { + return mp_const_none; + } + // Device does provide this string, so continue + _get_langid(self); + _prepare_for_transfer(); + if (!tuh_descriptor_get_product_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; } mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; - _get_langid(self); - if (!tuh_descriptor_get_manufacturer_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { return mp_const_none; } - return _get_string(temp_buf); + if (descriptor.iManufacturer == 0) { + return mp_const_none; + } + // Device does provide this string, so continue + _get_langid(self); + _prepare_for_transfer(); + if (!tuh_descriptor_get_manufacturer_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; } From 5d1bbca8ec1ea2a72b250a081b4233293f1a17fe Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 9 Sep 2025 13:42:09 -0400 Subject: [PATCH 092/208] Better error when mistakenly importing MicroPython .mpy file --- locale/circuitpython.pot | 4 ++++ py/persistentcode.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 262b5de769c89..7cb03d45088cc 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -1394,6 +1394,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/py/persistentcode.c b/py/persistentcode.c index 1976729f4d879..93f4c33deb4e2 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -471,6 +471,9 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) { read_bytes(reader, header, sizeof(header)); byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); // CIRCUITPY-CHANGE: 'C', not 'M' + if (header[0] == 'M') { + mp_raise_ValueError(MP_ERROR_TEXT("MicroPython .mpy file; use CircuitPython mpy-cross")); + } if (header[0] != 'C' || header[1] != MPY_VERSION || (arch != MP_NATIVE_ARCH_NONE && MPY_FEATURE_DECODE_SUB_VERSION(header[2]) != MPY_SUB_VERSION) From 8d6bd4b746017eedf31ac1d40ef32928d78b2949 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 9 Sep 2025 21:20:33 +0200 Subject: [PATCH 093/208] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/cs.po | 4 ++++ locale/el.po | 4 ++++ locale/hi.po | 4 ++++ locale/ko.po | 4 ++++ locale/ru.po | 4 ++++ locale/tr.po | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/locale/cs.po b/locale/cs.po index 58785e0a5d75a..67ece22664d76 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -1414,6 +1414,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/locale/el.po b/locale/el.po index 082ae20351e3b..9e31051bcc03b 100644 --- a/locale/el.po +++ b/locale/el.po @@ -1420,6 +1420,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/locale/hi.po b/locale/hi.po index 8e4aa0990aee7..7ab47ff0953b5 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -1396,6 +1396,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/locale/ko.po b/locale/ko.po index 8bde494eeec78..30205cad930e0 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -1447,6 +1447,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "매핑은 투플이어야 합니다" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/locale/ru.po b/locale/ru.po index d3d9415230455..49fb1eccdedef 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -1435,6 +1435,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "Сопоставление должно быть кортежом" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" diff --git a/locale/tr.po b/locale/tr.po index 10a288553a698..1bb304eaba6ca 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -1415,6 +1415,10 @@ msgstr "" msgid "Mapping must be a tuple" msgstr "Map tuple olmalıdır" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" + #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" From 77b613769d9432562caea23e375fefc3bc9cc45d Mon Sep 17 00:00:00 2001 From: gychang Date: Tue, 9 Sep 2025 15:44:01 -0700 Subject: [PATCH 094/208] Initial support for ESP32-C3-Lyra-V2 dev board See https://docs.espressif.com/projects/esp-adf/en/latest/design-guide/dev-boards/user-guide-esp32-c3-lyra.html This commit adds support for the status LED. It's not 100% clear to me why the default neopixel_write implementation doesn't work, but it seems that deleting the RMT channel triggers some sort of glitch signal that clears the WS2812C LED. Tested on this board: - console/REPL over USB/UART (connection works but is not stable) - web interface and editor over wifi - audiomp3 playback (sounds terrible) - neopixel library --- .../boards/espressif_esp32c3_lyra_v2/board.c | 9 ++++ .../espressif_esp32c3_lyra_v2/mpconfigboard.h | 23 +++++++++++ .../mpconfigboard.mk | 14 +++++++ .../boards/espressif_esp32c3_lyra_v2/pins.c | 41 +++++++++++++++++++ .../espressif_esp32c3_lyra_v2/sdkconfig | 0 .../common-hal/neopixel_write/__init__.c | 10 +++++ 6 files changed, 97 insertions(+) create mode 100644 ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c create mode 100644 ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h create mode 100644 ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk create mode 100644 ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c create mode 100644 ports/espressif/boards/espressif_esp32c3_lyra_v2/sdkconfig diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c b/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c new file mode 100644 index 0000000000000..b3b20cfe2d3f0 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h new file mode 100644 index 0000000000000..d38d4f4d09fdf --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Board setup +#define MICROPY_HW_BOARD_NAME "ESP32-C3-Lyra-V2" +#define MICROPY_HW_MCU_NAME "ESP32-C3N4" + +// Status LED +#define MICROPY_HW_NEOPIXEL (&pin_GPIO10) +#define MICROPY_HW_NEOPIXEL_COUNT (1) + +// Default bus pins +#define DEFAULT_UART_BUS_RX (&pin_GPIO20) +#define DEFAULT_UART_BUS_TX (&pin_GPIO21) + +// Serial over UART +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk new file mode 100644 index 0000000000000..a233eb526fdbd --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk @@ -0,0 +1,14 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x00C3A000 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 + +ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD = 1 + +CFLAGS += -DESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD=$(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c b/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c new file mode 100644 index 0000000000000..5f7c3d084dd3f --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/sdkconfig b/ports/espressif/boards/espressif_esp32c3_lyra_v2/sdkconfig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ports/espressif/common-hal/neopixel_write/__init__.c b/ports/espressif/common-hal/neopixel_write/__init__.c index d0d46a3179787..945b309372ac7 100644 --- a/ports/espressif/common-hal/neopixel_write/__init__.c +++ b/ports/espressif/common-hal/neopixel_write/__init__.c @@ -126,6 +126,11 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, // Update the next start to +2 ticks. It ensures that we've gone 300+ us. next_start_raw_ticks = port_get_raw_ticks(NULL) + 2; + #if defined(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) + // Hold the pin, deleting the channel seems to glitch pixels into turning off. + gpio_hold_en(digitalinout->pin->number); + #endif + // Free channel again rmt_del_encoder(encoder); rmt_disable(channel); @@ -133,4 +138,9 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, CHECK_ESP_RESULT(result); // Swap pin back to GPIO mode gpio_set_direction(digitalinout->pin->number, GPIO_MODE_OUTPUT); + + #if defined(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) + // Release hold + gpio_hold_dis(digitalinout->pin->number); + #endif } From 06f7192cba388a3da683387a959c8bc1a73f2e82 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 9 Sep 2025 21:24:03 -0400 Subject: [PATCH 095/208] Rev 3 board changes; lots of flash so turn on most features --- .../mpconfigboard.h | 4 ++-- .../mpconfigboard.mk | 19 ------------------- .../pins.c | 16 ++++++++-------- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h index 31559f318ada7..6e67197e757f1 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h @@ -5,8 +5,8 @@ #define MICROPY_HW_MCU_NAME "same51j20" #define CIRCUITPY_MCU_FAMILY samd51 -#define MICROPY_HW_LED_STATUS (&pin_PB23) -#define MICROPY_HW_NEOPIXEL (&pin_PB22) +#define MICROPY_HW_LED_STATUS (&pin_PB23) +#define MICROPY_HW_NEOPIXEL (&pin_PB22) #define BOARD_HAS_CRYSTAL 1 diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index 408c4eca9fd60..34c9d7bcaab28 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -9,24 +9,5 @@ CHIP_FAMILY = same51 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "SST26VF016B,SST26VF032B,SST26VF064B" LONGINT_IMPL = MPZ -CIRCUITPY_ULAB = 0 CIRCUITPY__EVE = 1 -CIRCUITPY_BITMAPFILTER = 0 -CIRCUITPY_CANIO = 1 -CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_SYNTHIO = 0 -CIRCUITPY_GIFIO = 0 -CIRCUITPY_JPEGIO = 0 - -CIRCUITPY_LTO_PARTITION = one - -# We don't have room for the fonts for terminalio for certain languages, -# so turn off terminalio, and if it's off and displayio is on, -# force a clean build. -# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an -# ifeq, because it's not set yet. -ifneq (,$(filter $(TRANSLATION),ja ko ru)) -CIRCUITPY_TERMINALIO = 0 -RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) -endif diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c index b4184e3cecd30..f3069930c6b0b 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c @@ -22,13 +22,11 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, @@ -60,23 +58,25 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA19) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB00) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_0), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB00) }, { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_1), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_2), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB03) }, - { MP_ROM_QSTR(MP_QSTR_SPARE_3), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB03) }, { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, From 146c199f34624add97a6287875a7287022accd3c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 10 Sep 2025 09:57:30 -0400 Subject: [PATCH 096/208] ports/raspberrypi/rp2pio/StateMachine.c: fix wait pin validation --- ports/raspberrypi/common-hal/rp2pio/StateMachine.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index 74b9a7f0c31b0..8d7f7f2ed6f7e 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -523,9 +523,10 @@ static void consider_instruction(introspect_t *state, uint16_t full_instruction, } } if (instruction == pio_instr_bits_wait) { - uint16_t wait_source = (full_instruction & 0x0060) >> 5; - uint16_t wait_index = (full_instruction & 0x001f) + state->inputs.pio_gpio_offset; - if (wait_source == 0 && !PIO_PINMASK_IS_SET(state->inputs.pins_we_use, wait_index)) { // GPIO + const uint16_t wait_source = (full_instruction & 0x0060) >> 5; + const uint16_t wait_index = full_instruction & 0x001f; + const uint16_t wait_pin = wait_index + state->inputs.pio_gpio_offset; + if (wait_source == 0 && !PIO_PINMASK_IS_SET(state->inputs.pins_we_use, wait_pin)) { // GPIO mp_raise_ValueError_varg(MP_ERROR_TEXT("%q[%u] uses extra pin"), what_program, i); } else if (wait_source == 1) { // Input pin if (!state->inputs.has_in_pin) { From 0013b48091424e0beaac2d704fe7a1be4a951f82 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 11 Sep 2025 16:22:09 -0400 Subject: [PATCH 097/208] py/builtinimport.c: always name module in error msg when an import fails --- py/builtinimport.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/py/builtinimport.c b/py/builtinimport.c index 17b3f11c4a001..e4e06d8e2cc8b 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -451,7 +451,9 @@ static mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, if (stat == MP_IMPORT_STAT_NO_EXIST) { // Not found -- fail. - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + // CIRCUITPY-CHANGE: always the use more verbose error message that names missing module. + // Otherwise `import a` where `a` imports `b`, but `b` is missing will give a confusing error. + #if 0 && (MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE) mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), full_mod_name); From 64b9c05779dd3db85fda5227ea31130e733bf4df Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 13 Sep 2025 15:44:51 -0400 Subject: [PATCH 098/208] Use critical sections for port_* storage operations, not just in LWIP --- .../common-hal/socketpool/Socket.c | 25 ++++++++++++++----- ports/raspberrypi/lwip_src/lwip_mem.c | 4 --- ports/raspberrypi/supervisor/port.c | 13 +++++++++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index 018365def8c75..aeab1498510a0 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -89,7 +89,7 @@ static mp_obj_t socketpool_ip_addr_and_port_to_tuple(const ip_addr_t *addr, int // socket API. // Extension to lwIP error codes -// Matches lwIP 2.0.3 +// Matches lwIP 2.2.1 #undef _ERR_BADF #define _ERR_BADF -17 static const int error_lookup_table[] = { @@ -473,7 +473,12 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, MICROPY_PY_LWIP_ENTER - u16_t available = tcp_sndbuf(socket->pcb.tcp); + // If the socket is still connecting then don't let data be written to it. + // Otherwise, get the number of available bytes in the output buffer. + u16_t available = 0; + if (socket->state != STATE_CONNECTING) { + available = tcp_sndbuf(socket->pcb.tcp); + } if (available == 0) { // Non-blocking socket @@ -490,7 +495,8 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, // If peer fully closed socket, we would have socket->state set to ERR_RST (connection // reset) by error callback. // Avoid sending too small packets, so wait until at least 16 bytes available - while (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16) { + while (socket->state == STATE_CONNECTING + || (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16)) { MICROPY_PY_LWIP_EXIT if (socket->timeout != (unsigned)-1 && mp_hal_ticks_ms() - start > socket->timeout) { *_errno = MP_ETIMEDOUT; @@ -531,9 +537,10 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, MICROPY_PY_LWIP_REENTER } - // If the output buffer is getting full then send the data to the lower layers - if (err == ERR_OK && tcp_sndbuf(socket->pcb.tcp) < TCP_SND_BUF / 4) { - err = tcp_output(socket->pcb.tcp); + // Use nagle algorithm to determine when to send segment buffer (can be + // disabled with TCP_NODELAY socket option) + if (err == ERR_OK) { + err = tcp_output_nagle(socket->pcb.tcp); } MICROPY_PY_LWIP_EXIT @@ -551,6 +558,12 @@ static mp_uint_t lwip_tcp_receive(socketpool_socket_obj_t *socket, byte *buf, mp // Check for any pending errors STREAM_ERROR_CHECK(socket); + if (socket->state == STATE_LISTENING) { + // original socket in listening state, not the accepted connection. + *_errno = MP_ENOTCONN; + return -1; + } + if (socket->incoming.pbuf == NULL) { // Non-blocking socket diff --git a/ports/raspberrypi/lwip_src/lwip_mem.c b/ports/raspberrypi/lwip_src/lwip_mem.c index d7d5468a42011..23b185354b072 100644 --- a/ports/raspberrypi/lwip_src/lwip_mem.c +++ b/ports/raspberrypi/lwip_src/lwip_mem.c @@ -12,16 +12,12 @@ #include "supervisor/port_heap.h" void *lwip_heap_malloc(size_t size) { - common_hal_mcu_disable_interrupts(); void *ptr = port_malloc(size, true); - common_hal_mcu_enable_interrupts(); return ptr; } void lwip_heap_free(void *ptr) { - common_hal_mcu_disable_interrupts(); port_free(ptr); - common_hal_mcu_enable_interrupts(); } void *lwip_heap_calloc(size_t num, size_t size) { diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 4be42380491cb..25b0bb6650f0c 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -264,31 +264,42 @@ void port_heap_init(void) { void *port_malloc(size_t size, bool dma_capable) { if (!dma_capable && _psram_size > 0) { + common_hal_mcu_disable_interrupts(); void *block = tlsf_malloc(_psram_heap, size); + common_hal_mcu_enable_interrupts(); if (block) { return block; } } + common_hal_mcu_disable_interrupts(); void *block = tlsf_malloc(_heap, size); + common_hal_mcu_enable_interrupts(); return block; } void port_free(void *ptr) { + common_hal_mcu_disable_interrupts(); if (((size_t)ptr) < SRAM_BASE) { tlsf_free(_psram_heap, ptr); } else { tlsf_free(_heap, ptr); } + common_hal_mcu_enable_interrupts(); } void *port_realloc(void *ptr, size_t size, bool dma_capable) { if (_psram_size > 0 && ((ptr != NULL && ((size_t)ptr) < SRAM_BASE) || (ptr == NULL && !dma_capable))) { + common_hal_mcu_disable_interrupts(); void *block = tlsf_realloc(_psram_heap, ptr, size); + common_hal_mcu_enable_interrupts(); if (block) { return block; } } - return tlsf_realloc(_heap, ptr, size); + common_hal_mcu_disable_interrupts(); + void *new_ptr = tlsf_realloc(_heap, ptr, size); + common_hal_mcu_enable_interrupts(); + return new_ptr; } static bool max_size_walker(void *ptr, size_t size, int used, void *user) { From 4008e1499735bb789d8cc95af2628d7327eb29aa Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 13 Sep 2025 15:46:00 -0400 Subject: [PATCH 099/208] espressif/common-hal/socketpool/Socket.c: return correct errno connect failure --- ports/espressif/common-hal/socketpool/Socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index 0a36eff95b454..5128e93c8589e 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -483,7 +483,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, socklen_t socklen = sizeof(error_code); result = getsockopt(self->num, SOL_SOCKET, SO_ERROR, &error_code, &socklen); if (result < 0 || error_code != 0) { - mp_raise_OSError(errno); + mp_raise_OSError(error_code); } self->connected = true; return; From a2c4dfa1ea5442b6416bc3be0c4a17c2ce89ec52 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 15 Sep 2025 12:20:20 -0700 Subject: [PATCH 100/208] Ensure USB host buffers are allocated in internal RAM --- locale/circuitpython.pot | 4 + ports/raspberrypi/mpconfigport.mk | 3 + ports/raspberrypi/supervisor/port.c | 8 ++ py/circuitpy_mpconfig.mk | 5 ++ shared-module/usb/core/Device.c | 116 ++++++++++++++++++++++++++-- shared-module/usb/core/Device.h | 4 + supervisor/port_heap.h | 6 ++ 7 files changed, 141 insertions(+), 5 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 7cb03d45088cc..98fc54741eb39 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -844,6 +844,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 1404b2b06777c..bbce13d13811f 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -59,6 +59,9 @@ CIRCUITPY_CYW43_INIT_DELAY ?= 1000 endif ifeq ($(CHIP_VARIANT),RP2350) +# RP2350 has PSRAM that is not DMA-capable +CIRCUITPY_ALL_MEMORY_DMA_CAPABLE = 0 + # This needs to be implemented. CIRCUITPY_ALARM = 0 # Default PICODVI on because it doesn't require much code in RAM to talk to HSTX. diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 25b0bb6650f0c..66e63248c4810 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -302,6 +302,14 @@ void *port_realloc(void *ptr, size_t size, bool dma_capable) { return new_ptr; } +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +bool port_buffer_is_dma_capable(const void *ptr) { + // For RP2350, DMA can only access SRAM, not PSRAM + // PSRAM addresses are below SRAM_BASE + return ptr != NULL && ((size_t)ptr) >= SRAM_BASE; +} +#endif + static bool max_size_walker(void *ptr, size_t size, int used, void *user) { size_t *max_size = (size_t *)user; if (!used && *max_size < size) { diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 2009c4e177da6..8c838a41218a3 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -98,6 +98,11 @@ CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) CIRCUITPY_ALARM_TOUCH ?= $(CIRCUITPY_ALARM) CFLAGS += -DCIRCUITPY_ALARM_TOUCH=$(CIRCUITPY_ALARM_TOUCH) +# Enable DMA buffer management for platforms where not all memory is DMA-capable +# Platforms with PSRAM or other non-DMA memory should set this to 0 +CIRCUITPY_ALL_MEMORY_DMA_CAPABLE ?= 1 +CFLAGS += -DCIRCUITPY_ALL_MEMORY_DMA_CAPABLE=$(CIRCUITPY_ALL_MEMORY_DMA_CAPABLE) + CIRCUITPY_ANALOGBUFIO ?= 0 CFLAGS += -DCIRCUITPY_ANALOGBUFIO=$(CIRCUITPY_ANALOGBUFIO) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index c07ffda1149c9..c4342e10d1d65 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -8,6 +8,8 @@ #include "shared-bindings/usb/core/Device.h" #include "tusb_config.h" +#include "supervisor/port.h" +#include "supervisor/port_heap.h" #include "lib/tinyusb/src/host/hcd.h" #include "lib/tinyusb/src/host/usbh.h" @@ -33,6 +35,39 @@ void tuh_umount_cb(uint8_t dev_addr) { static xfer_result_t _xfer_result; static size_t _actual_len; + +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +// Helper to ensure buffer is DMA-capable for transfer operations +static uint8_t *_ensure_dma_buffer(usb_core_device_obj_t *self, const uint8_t *buffer, size_t len, bool for_write) { + if (port_buffer_is_dma_capable(buffer)) { + return (uint8_t *)buffer; // Already DMA-capable, use directly + } + + // Need to allocate/reallocate temporary buffer in DMA-capable memory + if (self->temp_buffer_size < len) { + self->temp_buffer = port_realloc(self->temp_buffer, len, true); // true = DMA capable + if (self->temp_buffer == NULL) { + self->temp_buffer_size = 0; + return NULL; // Allocation failed + } + self->temp_buffer_size = len; + } + + // Copy data to DMA buffer if writing + if (for_write && buffer != NULL) { + memcpy(self->temp_buffer, buffer, len); + } + + return self->temp_buffer; +} + +// Copy data back from DMA buffer to original buffer after read +static void _copy_from_dma_buffer(usb_core_device_obj_t *self, uint8_t *original_buffer, size_t len) { + if (!port_buffer_is_dma_capable(original_buffer) && self->temp_buffer != NULL) { + memcpy(original_buffer, self->temp_buffer, len); + } +} +#endif bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t device_address) { if (!tuh_inited()) { mp_raise_RuntimeError(MP_ERROR_TEXT("No usb host port initialized")); @@ -46,6 +81,10 @@ bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t d } self->device_address = device_address; self->first_langid = 0; + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + self->temp_buffer = NULL; + self->temp_buffer_size = 0; + #endif _xfer_result = XFER_RESULT_INVALID; return true; } @@ -65,6 +104,14 @@ void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self) { self->open_endpoints[i] = 0; } } + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Clean up temporary buffer + if (self->temp_buffer != NULL) { + port_free(self->temp_buffer); + self->temp_buffer = NULL; + self->temp_buffer_size = 0; + } + #endif self->device_address = 0; } @@ -399,10 +446,22 @@ mp_int_t common_hal_usb_core_device_write(usb_core_device_obj_t *self, mp_int_t mp_raise_usb_core_USBError(NULL); return 0; } + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = _ensure_dma_buffer(self, buffer, len, true); // true = for write + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; + } + #else + uint8_t *dma_buffer = (uint8_t *)buffer; // All memory is DMA-capable + #endif + tuh_xfer_t xfer; xfer.daddr = self->device_address; xfer.ep_addr = endpoint; - xfer.buffer = (uint8_t *)buffer; + xfer.buffer = dma_buffer; xfer.buflen = len; return _xfer(&xfer, timeout); } @@ -412,12 +471,33 @@ mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t e mp_raise_usb_core_USBError(NULL); return 0; } + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = _ensure_dma_buffer(self, buffer, len, false); // false = for read + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; + } + #else + uint8_t *dma_buffer = buffer; // All memory is DMA-capable + #endif + tuh_xfer_t xfer; xfer.daddr = self->device_address; xfer.ep_addr = endpoint; - xfer.buffer = buffer; + xfer.buffer = dma_buffer; xfer.buflen = len; - return _xfer(&xfer, timeout); + mp_int_t result = _xfer(&xfer, timeout); + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Copy data back to original buffer if needed + if (result > 0) { + _copy_from_dma_buffer(self, buffer, result); + } + #endif + + return result; } mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, @@ -426,6 +506,23 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, uint8_t *buffer, mp_int_t len, mp_int_t timeout) { // Timeout is in ms. + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Determine if this is a write (host-to-device) or read (device-to-host) transfer + bool is_write = (bmRequestType & 0x80) == 0; // Bit 7: 0=host-to-device, 1=device-to-host + + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = NULL; + if (len > 0 && buffer != NULL) { + dma_buffer = _ensure_dma_buffer(self, buffer, len, is_write); + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; + } + } + #else + uint8_t *dma_buffer = buffer; // All memory is DMA-capable + #endif + tusb_control_request_t request = { .bmRequestType = bmRequestType, .bRequest = bRequest, @@ -437,7 +534,7 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .daddr = self->device_address, .ep_addr = 0, .setup = &request, - .buffer = buffer, + .buffer = dma_buffer, .complete_cb = _transfer_done_cb, }; @@ -446,7 +543,16 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, mp_raise_usb_core_USBError(NULL); return 0; } - return (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout); + mp_int_t result = (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout); + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Copy data back to original buffer if this was a read transfer and we got data + if ((bmRequestType & 0x80) != 0 && result > 0 && buffer != NULL) { // Read transfer (device-to-host) + _copy_from_dma_buffer(self, buffer, result); + } + #endif + + return result; } bool common_hal_usb_core_device_is_kernel_driver_active(usb_core_device_obj_t *self, mp_int_t interface) { diff --git a/shared-module/usb/core/Device.h b/shared-module/usb/core/Device.h index c7392a04ba7bc..8737eeaf86bf7 100644 --- a/shared-module/usb/core/Device.h +++ b/shared-module/usb/core/Device.h @@ -15,4 +15,8 @@ typedef struct { uint8_t *configuration_descriptor; // Contains the length of the all descriptors. uint8_t open_endpoints[8]; uint16_t first_langid; + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + uint8_t *temp_buffer; // Temporary buffer for PSRAM data + size_t temp_buffer_size; // Size of temporary buffer + #endif } usb_core_device_obj_t; diff --git a/supervisor/port_heap.h b/supervisor/port_heap.h index 40abd21438741..3e6b5a660fa79 100644 --- a/supervisor/port_heap.h +++ b/supervisor/port_heap.h @@ -27,4 +27,10 @@ void port_free(void *ptr); void *port_realloc(void *ptr, size_t size, bool dma_capable); +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +// Check if a buffer pointer is in DMA-capable memory. DMA-capable memory is also accessible during +// flash operations. +bool port_buffer_is_dma_capable(const void *ptr); +#endif + size_t port_heap_get_largest_free_size(void); From 989a857a335643fa280f6e72a39da3ad6b31e2fb Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 15 Sep 2025 23:10:38 -0400 Subject: [PATCH 101/208] rotaryio.IncrementalEncoder deinit fix and improvements --- .../common-hal/rotaryio/IncrementalEncoder.c | 13 ++++++++++--- .../common-hal/rotaryio/IncrementalEncoder.c | 8 ++++++++ .../common-hal/rotaryio/IncrementalEncoder.c | 10 ++++++++-- .../nordic/common-hal/rotaryio/IncrementalEncoder.c | 9 ++++++++- ports/raspberrypi/bindings/rp2pio/StateMachine.h | 1 + .../common-hal/rotaryio/IncrementalEncoder.c | 9 +++++++++ ports/raspberrypi/common-hal/rp2pio/StateMachine.c | 9 ++++++++- shared-bindings/rotaryio/IncrementalEncoder.h | 4 ++++ 8 files changed, 56 insertions(+), 7 deletions(-) diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c index c6cd4605784ab..a8c87d82ed268 100644 --- a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c @@ -17,6 +17,10 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + if (!pin_a->has_extint) { raise_ValueError_invalid_pin_name(MP_QSTR_pin_a); } @@ -83,10 +87,13 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o turn_off_eic_channel(self->eic_channel_b); reset_pin_number(self->pin_a); - self->pin_a = NO_PIN; - reset_pin_number(self->pin_b); - self->pin_b = NO_PIN; + + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { + self->pin_a = NO_PIN; } void incrementalencoder_interrupt_handler(uint8_t channel) { diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c index ba8b70221b729..f65c7fdd9f110 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c @@ -21,6 +21,10 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode // // These routines also implicitly configure the weak internal pull-ups, as expected // in CircuitPython. + + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + pcnt_unit_config_t unit_config = { // Set counter limit .low_limit = INT16_MIN, @@ -87,6 +91,10 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o pcnt_del_channel(self->channel_a); pcnt_del_channel(self->channel_b); pcnt_del_unit(self->unit); + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->unit = NULL; } diff --git a/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c index c71f8b212e183..211b5c186f3fa 100644 --- a/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c @@ -26,6 +26,9 @@ static void encoder_change(void *self_in) { void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + self->pin_a = pin_a; self->pin_b = pin_b; @@ -49,7 +52,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode } bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { - return !self->pin_a; + return self->pin_a == NULL; } void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self) { @@ -62,6 +65,9 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o common_hal_reset_pin(self->pin_a); common_hal_reset_pin(self->pin_b); + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->pin_a = NULL; - self->pin_b = NULL; } diff --git a/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c b/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c index b0617fae7e566..2e8b308ff64d9 100644 --- a/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c @@ -32,6 +32,9 @@ static void _intr_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + self->pin_a = pin_a->number; self->pin_b = pin_b->number; @@ -78,6 +81,10 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o nrfx_gpiote_in_uninit(self->pin_b); reset_pin_number(self->pin_a); reset_pin_number(self->pin_b); + + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->pin_a = NO_PIN; - self->pin_b = NO_PIN; } diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.h b/ports/raspberrypi/bindings/rp2pio/StateMachine.h index afdffd1eccd3b..16f884bcfca32 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.h +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.h @@ -42,6 +42,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self); bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self); +void common_hal_rp2pio_statemachine_mark_deinit(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self); diff --git a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c index 113bd1900dd88..d71ff60b2ebc3 100644 --- a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c @@ -43,6 +43,9 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { const mcu_pin_obj_t *pins[] = { pin_a, pin_b }; + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + // Start out with swapped to match behavior with other ports. self->swapped = true; if (!common_hal_rp2pio_pins_are_sequential(2, pins)) { @@ -89,6 +92,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode } bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { + // Use the deinit state of the PIO state machine. return common_hal_rp2pio_statemachine_deinited(&self->state_machine); } @@ -100,6 +104,11 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o common_hal_rp2pio_statemachine_deinit(&self->state_machine); } +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { + // Use the deinit state of the PIO state machine. + common_hal_rp2pio_statemachine_mark_deinit(&self->state_machine); +} + static void incrementalencoder_interrupt_handler(void *self_in) { rotaryio_incrementalencoder_obj_t *self = self_in; diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index 8d7f7f2ed6f7e..71050677f225f 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -628,6 +628,9 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, int mov_status_type, int mov_status_n) { + // Ensure object starts in its deinit state. + common_hal_rp2pio_statemachine_mark_deinit(self); + // First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false. pio_pinmask_t pins_we_use = wait_gpio_mask; PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(first_out_pin, out_pin_count, exclusive_pin_use)); @@ -744,7 +747,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, mov_status_type, mov_status_n); if (!ok) { // indicate state machine never inited - self->state_machine = NUM_PIO_STATE_MACHINES; + common_hal_rp2pio_statemachine_mark_deinit(self); mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); } } @@ -827,6 +830,10 @@ void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self) { rp2pio_statemachine_deinit(self, false); } +void common_hal_rp2pio_statemachine_mark_deinit(rp2pio_statemachine_obj_t *self) { + self->state_machine = NUM_PIO_STATE_MACHINES; +} + void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self) { rp2pio_statemachine_never_reset(self->pio, self->state_machine); // TODO: never reset all the pins diff --git a/shared-bindings/rotaryio/IncrementalEncoder.h b/shared-bindings/rotaryio/IncrementalEncoder.h index 1c60dd69a1937..b3ceb3eeb1513 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.h +++ b/shared-bindings/rotaryio/IncrementalEncoder.h @@ -13,11 +13,15 @@ extern const mp_obj_type_t rotaryio_incrementalencoder_type; extern void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b); + extern void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self); extern bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self); +extern void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self); + extern mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t *self); extern void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t *self, mp_int_t new_position); + extern mp_int_t common_hal_rotaryio_incrementalencoder_get_divisor(rotaryio_incrementalencoder_obj_t *self); extern void common_hal_rotaryio_incrementalencoder_set_divisor(rotaryio_incrementalencoder_obj_t *self, mp_int_t new_divisor); From 908e1341c152c383316fb96aebe11700d222057a Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Tue, 16 Sep 2025 08:33:17 -0500 Subject: [PATCH 102/208] Return self object from `play` methods to allow for chaining --- shared-bindings/audiodelays/Chorus.c | 4 ++-- shared-bindings/audiodelays/Echo.c | 4 ++-- shared-bindings/audiodelays/MultiTapDelay.c | 4 ++-- shared-bindings/audiodelays/PitchShift.c | 4 ++-- shared-bindings/audiofilters/Distortion.c | 4 ++-- shared-bindings/audiofilters/Filter.c | 4 ++-- shared-bindings/audiofilters/Phaser.c | 4 ++-- shared-bindings/audiofreeverb/Freeverb.c | 4 ++-- shared-bindings/audiomixer/Mixer.c | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/shared-bindings/audiodelays/Chorus.c b/shared-bindings/audiodelays/Chorus.c index c6bfa2ffa7eb1..67b9bc32745c4 100644 --- a/shared-bindings/audiodelays/Chorus.c +++ b/shared-bindings/audiodelays/Chorus.c @@ -206,7 +206,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_playing_obj, audiodelays_chorus MP_PROPERTY_GETTER(audiodelays_chorus_playing_obj, (mp_obj_t)&audiodelays_chorus_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Chorus: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -228,7 +228,7 @@ static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_a mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_chorus_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_chorus_play_obj, 1, audiodelays_chorus_obj_play); diff --git a/shared-bindings/audiodelays/Echo.c b/shared-bindings/audiodelays/Echo.c index 5ae849b19aa41..68216d2355b70 100644 --- a/shared-bindings/audiodelays/Echo.c +++ b/shared-bindings/audiodelays/Echo.c @@ -230,7 +230,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_playing_obj, audiodelays_echo_obj MP_PROPERTY_GETTER(audiodelays_echo_playing_obj, (mp_obj_t)&audiodelays_echo_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Echo: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -252,7 +252,7 @@ static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_arg mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_echo_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_echo_play_obj, 1, audiodelays_echo_obj_play); diff --git a/shared-bindings/audiodelays/MultiTapDelay.c b/shared-bindings/audiodelays/MultiTapDelay.c index 5b057eaf80d1b..ce11b2f1d3c61 100644 --- a/shared-bindings/audiodelays/MultiTapDelay.c +++ b/shared-bindings/audiodelays/MultiTapDelay.c @@ -233,7 +233,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_playing_obj, audiodela MP_PROPERTY_GETTER(audiodelays_multi_tap_delay_playing_obj, (mp_obj_t)&audiodelays_multi_tap_delay_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> MultiTapDelay: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -255,7 +255,7 @@ static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_multi_tap_delay_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_multi_tap_delay_play_obj, 1, audiodelays_multi_tap_delay_obj_play); diff --git a/shared-bindings/audiodelays/PitchShift.c b/shared-bindings/audiodelays/PitchShift.c index df2189945aa5d..e595beec6b8de 100644 --- a/shared-bindings/audiodelays/PitchShift.c +++ b/shared-bindings/audiodelays/PitchShift.c @@ -190,7 +190,7 @@ MP_PROPERTY_GETTER(audiodelays_pitch_shift_playing_obj, (mp_obj_t)&audiodelays_pitch_shift_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> PitchShift: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -211,7 +211,7 @@ static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t * mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_pitch_shift_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_pitch_shift_play_obj, 1, audiodelays_pitch_shift_obj_play); diff --git a/shared-bindings/audiofilters/Distortion.c b/shared-bindings/audiofilters/Distortion.c index cb888d0c71b7b..3120111ca9a80 100644 --- a/shared-bindings/audiofilters/Distortion.c +++ b/shared-bindings/audiofilters/Distortion.c @@ -309,7 +309,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_playing_obj, audiofilters_ MP_PROPERTY_GETTER(audiofilters_distortion_playing_obj, (mp_obj_t)&audiofilters_distortion_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Distortion: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -331,7 +331,7 @@ static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t * mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_distortion_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_distortion_play_obj, 1, audiofilters_distortion_obj_play); diff --git a/shared-bindings/audiofilters/Filter.c b/shared-bindings/audiofilters/Filter.c index 2a4887a4d42a2..2d8829d8a815d 100644 --- a/shared-bindings/audiofilters/Filter.c +++ b/shared-bindings/audiofilters/Filter.c @@ -179,7 +179,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_get_playing_obj, audiofilters_filt MP_PROPERTY_GETTER(audiofilters_filter_playing_obj, (mp_obj_t)&audiofilters_filter_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Filter: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -201,7 +201,7 @@ static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_ mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_filter_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_filter_play_obj, 1, audiofilters_filter_obj_play); diff --git a/shared-bindings/audiofilters/Phaser.c b/shared-bindings/audiofilters/Phaser.c index e7ddd986176b3..daff50e983492 100644 --- a/shared-bindings/audiofilters/Phaser.c +++ b/shared-bindings/audiofilters/Phaser.c @@ -214,7 +214,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_playing_obj, audiofilters_phas MP_PROPERTY_GETTER(audiofilters_phaser_playing_obj, (mp_obj_t)&audiofilters_phaser_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Phaser: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -236,7 +236,7 @@ static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_ mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_phaser_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_phaser_play_obj, 1, audiofilters_phaser_obj_play); diff --git a/shared-bindings/audiofreeverb/Freeverb.c b/shared-bindings/audiofreeverb/Freeverb.c index 62c9237a0d271..5e4c9644d2e8d 100644 --- a/shared-bindings/audiofreeverb/Freeverb.c +++ b/shared-bindings/audiofreeverb/Freeverb.c @@ -196,7 +196,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_playing_obj, audiofreeverb_ MP_PROPERTY_GETTER(audiofreeverb_freeverb_playing_obj, (mp_obj_t)&audiofreeverb_freeverb_get_playing_obj); -//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Freeverb: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -218,7 +218,7 @@ static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *p mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofreeverb_freeverb_play(self, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiofreeverb_freeverb_play_obj, 1, audiofreeverb_freeverb_obj_play); diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index dda6d06bd500c..0944f58ddbe45 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -160,7 +160,7 @@ MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj, //| def play( //| self, sample: circuitpython_typing.AudioSample, *, voice: int = 0, loop: bool = False -//| ) -> None: +//| ) -> Mixer: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| @@ -189,7 +189,7 @@ static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_arg mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool); - return mp_const_none; + return pos_args[0]; } MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); From 2e6dbaf5a00be4429592a8240c2f95c0e1add8ac Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Tue, 16 Sep 2025 10:09:22 -0500 Subject: [PATCH 103/208] Improve clarity of self reference --- shared-bindings/audiodelays/Chorus.c | 2 +- shared-bindings/audiodelays/Echo.c | 2 +- shared-bindings/audiodelays/MultiTapDelay.c | 2 +- shared-bindings/audiodelays/PitchShift.c | 2 +- shared-bindings/audiofilters/Distortion.c | 2 +- shared-bindings/audiofilters/Filter.c | 2 +- shared-bindings/audiofilters/Phaser.c | 2 +- shared-bindings/audiofreeverb/Freeverb.c | 2 +- shared-bindings/audiomixer/Mixer.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/shared-bindings/audiodelays/Chorus.c b/shared-bindings/audiodelays/Chorus.c index 67b9bc32745c4..94360ee558d5a 100644 --- a/shared-bindings/audiodelays/Chorus.c +++ b/shared-bindings/audiodelays/Chorus.c @@ -228,7 +228,7 @@ static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_a mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_chorus_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_chorus_play_obj, 1, audiodelays_chorus_obj_play); diff --git a/shared-bindings/audiodelays/Echo.c b/shared-bindings/audiodelays/Echo.c index 68216d2355b70..273d0e8e18dcb 100644 --- a/shared-bindings/audiodelays/Echo.c +++ b/shared-bindings/audiodelays/Echo.c @@ -252,7 +252,7 @@ static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_arg mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_echo_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_echo_play_obj, 1, audiodelays_echo_obj_play); diff --git a/shared-bindings/audiodelays/MultiTapDelay.c b/shared-bindings/audiodelays/MultiTapDelay.c index ce11b2f1d3c61..75b029600a2c0 100644 --- a/shared-bindings/audiodelays/MultiTapDelay.c +++ b/shared-bindings/audiodelays/MultiTapDelay.c @@ -255,7 +255,7 @@ static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_multi_tap_delay_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_multi_tap_delay_play_obj, 1, audiodelays_multi_tap_delay_obj_play); diff --git a/shared-bindings/audiodelays/PitchShift.c b/shared-bindings/audiodelays/PitchShift.c index e595beec6b8de..c8b4ea4b81c79 100644 --- a/shared-bindings/audiodelays/PitchShift.c +++ b/shared-bindings/audiodelays/PitchShift.c @@ -211,7 +211,7 @@ static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t * mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiodelays_pitch_shift_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_pitch_shift_play_obj, 1, audiodelays_pitch_shift_obj_play); diff --git a/shared-bindings/audiofilters/Distortion.c b/shared-bindings/audiofilters/Distortion.c index 3120111ca9a80..956a14e97e345 100644 --- a/shared-bindings/audiofilters/Distortion.c +++ b/shared-bindings/audiofilters/Distortion.c @@ -331,7 +331,7 @@ static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t * mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_distortion_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_distortion_play_obj, 1, audiofilters_distortion_obj_play); diff --git a/shared-bindings/audiofilters/Filter.c b/shared-bindings/audiofilters/Filter.c index 2d8829d8a815d..d82208d11ed81 100644 --- a/shared-bindings/audiofilters/Filter.c +++ b/shared-bindings/audiofilters/Filter.c @@ -201,7 +201,7 @@ static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_ mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_filter_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_filter_play_obj, 1, audiofilters_filter_obj_play); diff --git a/shared-bindings/audiofilters/Phaser.c b/shared-bindings/audiofilters/Phaser.c index daff50e983492..8472b01505cec 100644 --- a/shared-bindings/audiofilters/Phaser.c +++ b/shared-bindings/audiofilters/Phaser.c @@ -236,7 +236,7 @@ static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_ mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofilters_phaser_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_phaser_play_obj, 1, audiofilters_phaser_obj_play); diff --git a/shared-bindings/audiofreeverb/Freeverb.c b/shared-bindings/audiofreeverb/Freeverb.c index 5e4c9644d2e8d..de061734997a0 100644 --- a/shared-bindings/audiofreeverb/Freeverb.c +++ b/shared-bindings/audiofreeverb/Freeverb.c @@ -218,7 +218,7 @@ static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *p mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiofreeverb_freeverb_play(self, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiofreeverb_freeverb_play_obj, 1, audiofreeverb_freeverb_obj_play); diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 0944f58ddbe45..5e5bfdc1f3df9 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -189,7 +189,7 @@ static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_arg mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool); - return pos_args[0]; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); From 734209078660bc06103cb48eee460b1625323546 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Tue, 16 Sep 2025 10:15:47 -0500 Subject: [PATCH 104/208] Add return type documentation --- shared-bindings/audiodelays/Chorus.c | 6 +++++- shared-bindings/audiodelays/Echo.c | 6 +++++- shared-bindings/audiodelays/MultiTapDelay.c | 6 +++++- shared-bindings/audiodelays/PitchShift.c | 6 +++++- shared-bindings/audiofilters/Distortion.c | 6 +++++- shared-bindings/audiofilters/Filter.c | 6 +++++- shared-bindings/audiofilters/Phaser.c | 6 +++++- shared-bindings/audiofreeverb/Freeverb.c | 6 +++++- shared-bindings/audiomixer/Mixer.c | 6 +++++- 9 files changed, 45 insertions(+), 9 deletions(-) diff --git a/shared-bindings/audiodelays/Chorus.c b/shared-bindings/audiodelays/Chorus.c index 94360ee558d5a..87922ff110b1b 100644 --- a/shared-bindings/audiodelays/Chorus.c +++ b/shared-bindings/audiodelays/Chorus.c @@ -210,7 +210,11 @@ MP_PROPERTY_GETTER(audiodelays_chorus_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Chorus""" //| ... //| static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiodelays/Echo.c b/shared-bindings/audiodelays/Echo.c index 273d0e8e18dcb..dbb496c61b975 100644 --- a/shared-bindings/audiodelays/Echo.c +++ b/shared-bindings/audiodelays/Echo.c @@ -234,7 +234,11 @@ MP_PROPERTY_GETTER(audiodelays_echo_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Echo""" //| ... //| static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiodelays/MultiTapDelay.c b/shared-bindings/audiodelays/MultiTapDelay.c index 75b029600a2c0..2126dbf990435 100644 --- a/shared-bindings/audiodelays/MultiTapDelay.c +++ b/shared-bindings/audiodelays/MultiTapDelay.c @@ -237,7 +237,11 @@ MP_PROPERTY_GETTER(audiodelays_multi_tap_delay_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: MultiTapDelay""" //| ... //| static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiodelays/PitchShift.c b/shared-bindings/audiodelays/PitchShift.c index c8b4ea4b81c79..b94df7d9edd08 100644 --- a/shared-bindings/audiodelays/PitchShift.c +++ b/shared-bindings/audiodelays/PitchShift.c @@ -194,7 +194,11 @@ MP_PROPERTY_GETTER(audiodelays_pitch_shift_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: PitchShift""" //| ... //| static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiofilters/Distortion.c b/shared-bindings/audiofilters/Distortion.c index 956a14e97e345..8de4c1d1ea331 100644 --- a/shared-bindings/audiofilters/Distortion.c +++ b/shared-bindings/audiofilters/Distortion.c @@ -313,7 +313,11 @@ MP_PROPERTY_GETTER(audiofilters_distortion_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Distortion""" //| ... //| static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiofilters/Filter.c b/shared-bindings/audiofilters/Filter.c index d82208d11ed81..426fff226168f 100644 --- a/shared-bindings/audiofilters/Filter.c +++ b/shared-bindings/audiofilters/Filter.c @@ -183,7 +183,11 @@ MP_PROPERTY_GETTER(audiofilters_filter_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Filter""" //| ... //| static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiofilters/Phaser.c b/shared-bindings/audiofilters/Phaser.c index 8472b01505cec..9f713afce5f72 100644 --- a/shared-bindings/audiofilters/Phaser.c +++ b/shared-bindings/audiofilters/Phaser.c @@ -218,7 +218,11 @@ MP_PROPERTY_GETTER(audiofilters_phaser_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Phaser""" //| ... //| static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiofreeverb/Freeverb.c b/shared-bindings/audiofreeverb/Freeverb.c index de061734997a0..12eb7ef70ab79 100644 --- a/shared-bindings/audiofreeverb/Freeverb.c +++ b/shared-bindings/audiofreeverb/Freeverb.c @@ -200,7 +200,11 @@ MP_PROPERTY_GETTER(audiofreeverb_freeverb_playing_obj, //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| The sample must match the encoding settings given in the constructor.""" +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Freeverb""" //| ... //| static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 5e5bfdc1f3df9..516d079cd2a09 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -166,7 +166,11 @@ MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj, //| //| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`. //| -//| The sample must match the Mixer's encoding settings given in the constructor.""" +//| The sample must match the Mixer's encoding settings given in the constructor. +//| +//| :return: The mixer object itself. Can be used for chaining, ie: +//| ``audio.play(mixer.play(sample))``. +//| :rtype: Chorus""" //| ... //| static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { From 9f771b37ba6ca319828c98f4793618cebece32dc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 19 Sep 2025 11:08:04 -0700 Subject: [PATCH 105/208] Free dma capable temporary buffer immediately This reduces memory use and prevents long term fragmentation. --- shared-module/usb/core/Device.c | 98 +++++++++++++++++++-------------- shared-module/usb/core/Device.h | 4 -- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index c4342e10d1d65..83def37de914e 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -43,30 +43,19 @@ static uint8_t *_ensure_dma_buffer(usb_core_device_obj_t *self, const uint8_t *b return (uint8_t *)buffer; // Already DMA-capable, use directly } - // Need to allocate/reallocate temporary buffer in DMA-capable memory - if (self->temp_buffer_size < len) { - self->temp_buffer = port_realloc(self->temp_buffer, len, true); // true = DMA capable - if (self->temp_buffer == NULL) { - self->temp_buffer_size = 0; - return NULL; // Allocation failed - } - self->temp_buffer_size = len; + uint8_t *dma_buffer = port_malloc(len, true); // true = DMA capable + if (dma_buffer == NULL) { + return NULL; // Allocation failed } // Copy data to DMA buffer if writing if (for_write && buffer != NULL) { - memcpy(self->temp_buffer, buffer, len); + memcpy(dma_buffer, buffer, len); } - return self->temp_buffer; + return dma_buffer; } -// Copy data back from DMA buffer to original buffer after read -static void _copy_from_dma_buffer(usb_core_device_obj_t *self, uint8_t *original_buffer, size_t len) { - if (!port_buffer_is_dma_capable(original_buffer) && self->temp_buffer != NULL) { - memcpy(original_buffer, self->temp_buffer, len); - } -} #endif bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t device_address) { if (!tuh_inited()) { @@ -81,10 +70,6 @@ bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t d } self->device_address = device_address; self->first_langid = 0; - #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE - self->temp_buffer = NULL; - self->temp_buffer_size = 0; - #endif _xfer_result = XFER_RESULT_INVALID; return true; } @@ -104,14 +89,6 @@ void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self) { self->open_endpoints[i] = 0; } } - #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE - // Clean up temporary buffer - if (self->temp_buffer != NULL) { - port_free(self->temp_buffer); - self->temp_buffer = NULL; - self->temp_buffer_size = 0; - } - #endif self->device_address = 0; } @@ -180,7 +157,24 @@ static void _prepare_for_transfer(void) { _actual_len = 0; } -static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout) { +static void _abort_transfer(tuh_xfer_t *xfer) { + bool aborted = tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + if (aborted) { + // If the transfer was aborted, then we can continue. + return; + } + uint32_t start_time = supervisor_ticks_ms32(); + // If not, we need to wait for it to finish, otherwise we may free memory out from under it. + // Limit the wait time to 10 milliseconds to avoid blocking indefinitely. + while (_xfer_result == XFER_RESULT_INVALID && (supervisor_ticks_ms32() - start_time < 10)) { + // The background tasks include TinyUSB which will call the function + // we provided above. In other words, the callback isn't in an interrupt. + RUN_BACKGROUND_TASKS; + } +} + +// Only frees the transfer buffer on error. +static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout, bool our_buffer) { if (xfer == NULL) { mp_raise_usb_core_USBError(NULL); return 0; @@ -195,12 +189,15 @@ static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout } if (mp_hal_is_interrupted()) { // Handle case of VM being interrupted by Ctrl-C or autoreload - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + _abort_transfer(xfer); return 0; } // Handle transfer result code from TinyUSB xfer_result_t result = _xfer_result; _xfer_result = XFER_RESULT_INVALID; + if (our_buffer && result != XFER_RESULT_SUCCESS && result != XFER_RESULT_INVALID) { + port_free(xfer->buffer); + } switch (result) { case XFER_RESULT_SUCCESS: return _actual_len; @@ -217,8 +214,11 @@ static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout break; case XFER_RESULT_INVALID: // This timeout comes from CircuitPython, not TinyUSB, so tell TinyUSB - // to stop the transfer - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + // to stop the transfer and then wait to free the buffer. + _abort_transfer(xfer); + if (our_buffer) { + port_free(xfer->buffer); + } mp_raise_usb_core_USBTimeoutError(); break; } @@ -382,14 +382,18 @@ void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, m _wait_for_callback(); } -static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { +// Raises an exception on failure. Returns the number of bytes transferred (maybe zero) on success. +static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout, bool our_buffer) { _prepare_for_transfer(); xfer->complete_cb = _transfer_done_cb; if (!tuh_edpt_xfer(xfer)) { + if (our_buffer) { + port_free(xfer->buffer); + } mp_raise_usb_core_USBError(NULL); return 0; } - return _handle_timed_transfer_callback(xfer, timeout); + return _handle_timed_transfer_callback(xfer, timeout, our_buffer); } static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { @@ -463,7 +467,13 @@ mp_int_t common_hal_usb_core_device_write(usb_core_device_obj_t *self, mp_int_t xfer.ep_addr = endpoint; xfer.buffer = dma_buffer; xfer.buflen = len; - return _xfer(&xfer, timeout); + size_t result = _xfer(&xfer, timeout, dma_buffer != buffer); + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + if (dma_buffer != buffer) { + port_free(dma_buffer); + } + #endif + return result; } mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t endpoint, uint8_t *buffer, mp_int_t len, mp_int_t timeout) { @@ -488,12 +498,13 @@ mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t e xfer.ep_addr = endpoint; xfer.buffer = dma_buffer; xfer.buflen = len; - mp_int_t result = _xfer(&xfer, timeout); + mp_int_t result = _xfer(&xfer, timeout, dma_buffer != buffer); #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE // Copy data back to original buffer if needed - if (result > 0) { - _copy_from_dma_buffer(self, buffer, result); + if (dma_buffer != buffer) { + memcpy(buffer, dma_buffer, result); + port_free(dma_buffer); } #endif @@ -543,12 +554,15 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, mp_raise_usb_core_USBError(NULL); return 0; } - mp_int_t result = (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout); + mp_int_t result = (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout, dma_buffer != buffer); #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE - // Copy data back to original buffer if this was a read transfer and we got data - if ((bmRequestType & 0x80) != 0 && result > 0 && buffer != NULL) { // Read transfer (device-to-host) - _copy_from_dma_buffer(self, buffer, result); + if (dma_buffer != buffer) { + // Copy data back to original buffer if this was a read transfer + if (buffer != NULL && !is_write) { + memcpy(buffer, dma_buffer, result); + } + port_free(dma_buffer); } #endif diff --git a/shared-module/usb/core/Device.h b/shared-module/usb/core/Device.h index 8737eeaf86bf7..c7392a04ba7bc 100644 --- a/shared-module/usb/core/Device.h +++ b/shared-module/usb/core/Device.h @@ -15,8 +15,4 @@ typedef struct { uint8_t *configuration_descriptor; // Contains the length of the all descriptors. uint8_t open_endpoints[8]; uint16_t first_langid; - #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE - uint8_t *temp_buffer; // Temporary buffer for PSRAM data - size_t temp_buffer_size; // Size of temporary buffer - #endif } usb_core_device_obj_t; From dd0e10d6f45398683627f268eb6ad060044887d6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 21 Sep 2025 11:49:58 -0400 Subject: [PATCH 106/208] turn on canio --- .../microchip_curiosity_circuitpython_nano/mpconfigboard.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk index 34c9d7bcaab28..4bb7b68550922 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "SST26VF016B,SST26VF032B,SST26VF064B" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 1 From 9d006d42604eaffc2782389f34287eeea5f9ef13 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 22 Sep 2025 19:40:55 +0200 Subject: [PATCH 107/208] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/cs.po | 4 ++++ locale/el.po | 4 ++++ locale/hi.po | 4 ++++ locale/ko.po | 4 ++++ locale/ru.po | 4 ++++ locale/tr.po | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/locale/cs.po b/locale/cs.po index 67ece22664d76..eab928c2aaaf6 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -861,6 +861,10 @@ msgstr "Pole souřadnic mají různé délky" msgid "Coordinate arrays types have different sizes" msgstr "" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/locale/el.po b/locale/el.po index 9e31051bcc03b..871ce82f6725c 100644 --- a/locale/el.po +++ b/locale/el.po @@ -867,6 +867,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/locale/hi.po b/locale/hi.po index 7ab47ff0953b5..f8408f6c119a5 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -846,6 +846,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 30205cad930e0..4a74ec9003488 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -890,6 +890,10 @@ msgstr "좌표 배열의 길이가 다릅니다" msgid "Coordinate arrays types have different sizes" msgstr "좌표 배열 유형은 크기가 다릅니다" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/locale/ru.po b/locale/ru.po index 49fb1eccdedef..24b880972cb42 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -870,6 +870,10 @@ msgstr "Координатные массивы имеют разные длин msgid "Coordinate arrays types have different sizes" msgstr "Типы массивов координат имеют разные размеры" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" diff --git a/locale/tr.po b/locale/tr.po index 1bb304eaba6ca..f51ad3e8c12ee 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -860,6 +860,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" + #: ports/espressif/common-hal/rclcpy/Publisher.c msgid "Could not publish to ROS topic" msgstr "" From 493f078739d1e5ce93dfc5ef9d0a52a29c63b4ba Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Thu, 26 Dec 2024 13:25:26 -0800 Subject: [PATCH 108/208] Setup files for busio --- ports/analog/common-hal/busio/I2C.c | 210 ++++++++++++++++++ ports/analog/common-hal/busio/I2C.h | 24 ++ ports/analog/common-hal/busio/SPI.c | 254 ++++++++++++++++++++++ ports/analog/common-hal/busio/SPI.h | 35 +++ ports/analog/common-hal/busio/UART.c | 76 +++++++ ports/analog/common-hal/busio/UART.h | 31 +++ ports/analog/common-hal/busio/__init__.c | 5 + ports/analog/peripherals/max32690/gpios.h | 2 + 8 files changed, 637 insertions(+) create mode 100644 ports/analog/common-hal/busio/I2C.c create mode 100644 ports/analog/common-hal/busio/I2C.h create mode 100644 ports/analog/common-hal/busio/SPI.c create mode 100644 ports/analog/common-hal/busio/SPI.h create mode 100644 ports/analog/common-hal/busio/UART.c create mode 100644 ports/analog/common-hal/busio/UART.h create mode 100644 ports/analog/common-hal/busio/__init__.c diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c new file mode 100644 index 0000000000000..ae18f561c502f --- /dev/null +++ b/ports/analog/common-hal/busio/I2C.c @@ -0,0 +1,210 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +static I2CSPM_Init_TypeDef i2cspm_init; +static bool in_used = false; + +// Construct I2C protocol, this function init i2c peripheral +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t *scl, + const mcu_pin_obj_t *sda, + uint32_t frequency, uint32_t timeout) { + + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + + if ((scl != NULL) && (sda != NULL)) { + if (scl->function_list[ DEFAULT_I2C_PERIPHERAL == I2C1? + FN_I2C1_SCL : FN_I2C0_SCL] == 1 && + scl->function_list[DEFAULT_I2C_PERIPHERAL == I2C1? + FN_I2C1_SDA : FN_I2C0_SDA] == 1) { + self->scl = scl; + self->sda = sda; + self->has_lock = false; + i2cspm_init.sclPort = self->scl->port; + i2cspm_init.sclPin = self->scl->number; + i2cspm_init.sdaPort = self->sda->port; + i2cspm_init.sdaPin = self->sda->number; + i2cspm_init.port = DEFAULT_I2C_PERIPHERAL; + i2cspm_init.i2cRefFreq = 0; + i2cspm_init.i2cMaxFreq = I2C_FREQ_STANDARD_MAX; + i2cspm_init.i2cClhr = i2cClockHLRStandard; + + self->i2cspm = i2cspm_init.port; + I2CSPM_Init(&i2cspm_init); + common_hal_mcu_pin_claim(scl); + common_hal_mcu_pin_claim(sda); + in_used = true; + } else { + mp_raise_ValueError(MP_ERROR_TEXT("Hardware in use, try alternative pins")); + } + } else { + raise_ValueError_invalid_pins(); + } +} + +// Never reset I2C obj when reload +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + common_hal_never_reset_pin(self->sda); + common_hal_never_reset_pin(self->scl); +} + +// Check I2C status, deinited or not +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda == NULL; +} + +// Deinit i2c obj, reset I2C pin +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + I2C_Reset(self->i2cspm); + common_hal_reset_pin(self->sda); + common_hal_reset_pin(self->scl); + self->i2cspm = NULL; + in_used = false; + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda = NULL; +} + +// Probe device in I2C bus +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + uint8_t data = 0; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_READ; + + seq.buf[0].data = &data; + seq.buf[0].len = 1; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return false; + } + return true; +} + +// Lock I2C bus +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return false; + } + bool grabbed_lock = false; + + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + return grabbed_lock; +} + +// Check I2C lock status +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +// Unlock I2C bus +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +// Write data to the device selected by address +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_WRITE; + + seq.buf[0].data = (uint8_t *)data; + seq.buf[0].len = len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} + +// Read into buffer from the device selected by address +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, + uint16_t addr, + uint8_t *data, size_t len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_READ; + + seq.buf[0].data = data; + seq.buf[0].len = len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} + +// Write the bytes from out_data to the device selected by address, +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, + uint8_t *in_data, size_t in_len) { + + I2C_TransferSeq_TypeDef seq; + I2C_TransferReturn_TypeDef ret; + + seq.addr = addr << 1; + seq.flags = I2C_FLAG_WRITE_READ; + // Select command to issue + seq.buf[0].data = out_data; + seq.buf[0].len = out_len; + // Select location/length of data to be read + seq.buf[1].data = in_data; + seq.buf[1].len = in_len; + + ret = I2CSPM_Transfer(self->i2cspm, &seq); + if (ret != i2cTransferDone) { + return MP_EIO; + } + return 0; +} diff --git a/ports/analog/common-hal/busio/I2C.h b/ports/analog/common-hal/busio/I2C.h new file mode 100644 index 0000000000000..c92283d6c53b6 --- /dev/null +++ b/ports/analog/common-hal/busio/I2C.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +// FIXME: Silabs includes "peripherals/periph.h. Figure out what's in this file. " +#include "py/obj.h" + +// HAL-specific +#include "i2c.h" +#include "gpio.h" + +// Define a struct for what BUSIO.I2C should carry +typedef struct { + mp_obj_base_t base; + mxc_i2c_regs_t* i2c_regs; + bool has_lock; + const mcu_pin_obj_t *scl; + const mcu_pin_obj_t *sda; +} busio_i2c_obj_t; diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c new file mode 100644 index 0000000000000..74cfc69bfb2a0 --- /dev/null +++ b/ports/analog/common-hal/busio/SPI.c @@ -0,0 +1,254 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/board.h" +#include "shared-bindings/microcontroller/Pin.h" + +// Note that any bugs introduced in this file can cause crashes +// at startupfor chips using external SPI flash. + +static SPIDRV_HandleData_t spidrv_eusart_handle; +static SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; +static bool in_used = false; +static bool never_reset = false; + +// Reset SPI when reload +void spi_reset(void) { + if (!never_reset && in_used) { + SPIDRV_DeInit(&spidrv_eusart_handle); + in_used = false; + } + return; +} + +// Construct SPI protocol, this function init SPI peripheral +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t *sck, + const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, + bool half_duplex) { + Ecode_t sc = ECODE_OK; + + if (half_duplex) { + mp_raise_NotImplementedError( + MP_ERROR_TEXT("Half duplex SPI is not implemented")); + } + + if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { + if (sck->function_list[FN_EUSART1_SCLK] == 1 + && miso->function_list[FN_EUSART1_RX] == 1 + && mosi->function_list[FN_EUSART1_TX] == 1) { + + self->sck = sck; + self->mosi = mosi; + self->miso = miso; + self->handle = &spidrv_eusart_handle; + self->polarity = 0; + self->phase = 0; + self->bits = 8; + + spidrv_eusart_init.portTx = mosi->port; + spidrv_eusart_init.portRx = miso->port; + spidrv_eusart_init.portClk = sck->port; + spidrv_eusart_init.pinTx = mosi->number; + spidrv_eusart_init.pinRx = miso->number; + spidrv_eusart_init.pinClk = sck->number; + spidrv_eusart_init.bitRate = 1000000; + spidrv_eusart_init.frameLength = 8; + spidrv_eusart_init.dummyTxValue = 0; + spidrv_eusart_init.type = spidrvMaster; + spidrv_eusart_init.bitOrder = spidrvBitOrderMsbFirst; + spidrv_eusart_init.clockMode = spidrvClockMode0; + spidrv_eusart_init.csControl = spidrvCsControlApplication; + spidrv_eusart_init.slaveStartMode = spidrvSlaveStartImmediate; + + sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_ValueError(MP_ERROR_TEXT("SPI init error")); + } + } else { + mp_raise_ValueError(MP_ERROR_TEXT("Hardware in use, try alternative pins")); + } + } else { + raise_ValueError_invalid_pins(); + } + + in_used = true; + common_hal_mcu_pin_claim(sck); + common_hal_mcu_pin_claim(mosi); + common_hal_mcu_pin_claim(miso); +} + +// Never reset SPI when reload +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + never_reset = true; + common_hal_never_reset_pin(self->mosi); + common_hal_never_reset_pin(self->miso); + common_hal_never_reset_pin(self->sck); +} + +// Check SPI status, deinited or not +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->sck == NULL; +} + +// Deinit SPI obj +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + + if (common_hal_busio_spi_deinited(self)) { + return; + } + + Ecode_t sc = SPIDRV_DeInit(self->handle); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); + } + + in_used = false; + self->sck = NULL; + self->mosi = NULL; + self->miso = NULL; + self->handle = NULL; + common_hal_reset_pin(self->mosi); + common_hal_reset_pin(self->miso); + common_hal_reset_pin(self->sck); +} + +// Configures the SPI bus. The SPI object must be locked. +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, + uint8_t polarity, + uint8_t phase, + uint8_t bits) { + Ecode_t sc; + // This resets the SPI, so check before updating it redundantly + if (baudrate == self->baudrate && polarity == self->polarity + && phase == self->phase && bits == self->bits) { + return true; + } + + sc = SPIDRV_DeInit(self->handle); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); + } + in_used = false; + self->baudrate = baudrate; + self->phase = phase; + self->bits = bits; + self->polarity = polarity; + + spidrv_eusart_init.bitRate = baudrate; + spidrv_eusart_init.frameLength = 8; + if (polarity == 0 && phase == 0) { + spidrv_eusart_init.clockMode = spidrvClockMode0; + } else if (polarity == 0 && phase == 1) { + spidrv_eusart_init.clockMode = spidrvClockMode1; + } else if (polarity == 1 && phase == 0) { + spidrv_eusart_init.clockMode = spidrvClockMode2; + } else if (polarity == 1 && phase == 1) { + spidrv_eusart_init.clockMode = spidrvClockMode3; + } + + sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); + if (sc != ECODE_EMDRV_SPIDRV_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); + } + in_used = true; + return true; +} + +// Lock SPI bus +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + bool grabbed_lock = false; + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + + return grabbed_lock; +} + +// Check SPI lock status +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +// Unlock SPI bus +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +// Write the data contained in buffer +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, + size_t len) { + + Ecode_t result = SPIDRV_MTransmitB(self->handle, data, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Read data into buffer +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, + uint8_t write_value) { + + self->handle->initData.dummyTxValue = write_value; + Ecode_t result = SPIDRV_MReceiveB(self->handle, data, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Write out the data in data_out +// while simultaneously reading data into data_in +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, + const uint8_t *data_out, + uint8_t *data_in, + size_t len) { + + Ecode_t result = SPIDRV_MTransferB(self->handle, data_out, data_in, len); + return result == ECODE_EMDRV_SPIDRV_OK; +} + +// Get SPI baudrate +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { + return self->baudrate; +} + +// Get SPI phase +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t *self) { + return self->phase; +} + +// Get SPI polarity +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { + return self->polarity; +} diff --git a/ports/analog/common-hal/busio/SPI.h b/ports/analog/common-hal/busio/SPI.h new file mode 100644 index 0000000000000..8c48147ff6c77 --- /dev/null +++ b/ports/analog/common-hal/busio/SPI.h @@ -0,0 +1,35 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" +// FIXME: Silabs includes "peripherals/periph.h. Figure out what's in this file. " +#include "py/obj.h" + +// HAL-specific +#include "spi.h" + +// Define a struct for what BUSIO.SPI should carry +typedef struct { + mp_obj_base_t base; + mxc_spi_regs_t* spi_regs; + bool has_lock; + const mcu_pin_obj_t *sck; + const mcu_pin_obj_t *mosi; + const mcu_pin_obj_t *miso; + const mcu_pin_obj_t *nss; + uint32_t baudrate; + uint16_t prescaler; + uint8_t polarity; + uint8_t phase; + uint8_t bits; +} busio_spi_obj_t; + +void spi_reset(void); + +#endif // MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c new file mode 100644 index 0000000000000..6d1507b78c696 --- /dev/null +++ b/ports/analog/common-hal/busio/UART.c @@ -0,0 +1,76 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/UART.h" + +#include "mpconfigport.h" +#include "shared/readline/readline.h" +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "uart.h" +#include "UART.h" + +typedef enum { + BUSIO_UART_PARITY_NONE, + BUSIO_UART_PARITY_EVEN, + BUSIO_UART_PARITY_ODD +} busio_uart_parity_t; + +// Construct an underlying UART object. +extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, + const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, + const mcu_pin_obj_t *rs485_dir, bool rs485_invert, + uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, + bool sigint_enabled); + +extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); + +// Read characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_read(busio_uart_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self); +extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate); +extern mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self); +extern void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout); + +extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self); +extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self); + +extern void common_hal_busio_uart_never_reset(busio_uart_obj_t *self); diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h new file mode 100644 index 0000000000000..a8d294de222d3 --- /dev/null +++ b/ports/analog/common-hal/busio/UART.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" +#include "peripherals/periph.h" +#include "py/obj.h" +#include "py/ringbuf.h" + +#include "uart.h" + +// Define a struct for what BUSIO.UART should contain +typedef struct { + mp_obj_base_t base; + mxc_uart_regs_t* uart_regs; + const mcu_pin_obj_t *rx; + const mcu_pin_obj_t *tx; + uint32_t baudrate; + bool parity; + uint8_t stop_bits; + uint8_t bits; +} busio_uart_obj_t; + +void uart_reset(void); + +#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H diff --git a/ports/analog/common-hal/busio/__init__.c b/ports/analog/common-hal/busio/__init__.c new file mode 100644 index 0000000000000..ff05be051bb25 --- /dev/null +++ b/ports/analog/common-hal/busio/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT diff --git a/ports/analog/peripherals/max32690/gpios.h b/ports/analog/peripherals/max32690/gpios.h index 4677bf8f33dbe..fe91227728291 100644 --- a/ports/analog/peripherals/max32690/gpios.h +++ b/ports/analog/peripherals/max32690/gpios.h @@ -4,6 +4,8 @@ // // SPDX-License-Identifier: MIT +#pragma once + #include "py/obj.h" #include "py/mphal.h" From f4c21716f5385b62a4400312c8de53abc195ab00 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 14 Jan 2025 15:19:04 -0800 Subject: [PATCH 109/208] Add default build for analog ports for apard32690 board. --- Makefile | 3 +++ ports/analog/Makefile | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f2fc070a6331d..c2aebc61f1c0b 100644 --- a/Makefile +++ b/Makefile @@ -299,6 +299,9 @@ update-frozen-libraries: one-of-each: samd21 litex mimxrt10xx nordic stm +analog: + $(MAKE) -C ports/analog/ BOARD=apard32690 + samd21: $(MAKE) -C ports/atmel-samd BOARD=trinket_m0 diff --git a/ports/analog/Makefile b/ports/analog/Makefile index ce9082c5e255a..96f9037aae924 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -6,12 +6,13 @@ # # SPDX-License-Identifier: MIT +BOARD ?= apard32690 +CROSS_COMPILE = arm-none-eabi- + # Includes mpconfigboard.mk & mpconfigport.mk, # along with numerous other shared environment makefiles. include ../../py/circuitpy_mkenv.mk -CROSS_COMPILE = arm-none-eabi- - # MCU_SERIES e.g. "max32" # MCU_VARIANT e.g. "max32690" # defined in mpconfigboard.mk @@ -20,6 +21,7 @@ MCU_SERIES_UPPER := $(shell echo $(MCU_SERIES) | tr '[:lower:]' '[:upper:]') MCU_VARIANT_LOWER := $(shell echo $(MCU_VARIANT) | tr '[:upper:]' '[:lower:]') MCU_VARIANT_UPPER := $(shell echo $(MCU_VARIANT) | tr '[:lower:]' '[:upper:]') + # ******************************************************************************* #### MSDK INCLUDES #### # Necessary for msdk makefiles @@ -59,6 +61,7 @@ DIE_TYPE=me18 endif PERIPH_SRC = $(ADI_PERIPH)/Source +PERIPH_INC = $(ADI_PERIPH)/Include/$(MCU_VARIANT_UPPER) INC += -I. INC += -I../.. @@ -75,7 +78,7 @@ INC += \ -I$(TOP)/lib/cmsis/inc \ -I$(CMSIS_ROOT)/Include \ -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Include \ - -I$(ADI_PERIPH)/Include/$(MCU_VARIANT_UPPER) \ + -I$(PERIPH_INC) \ -I$(PERIPH_SRC)/SYS \ -I$(PERIPH_SRC)/CTB \ -I$(PERIPH_SRC)/DMA \ @@ -126,7 +129,8 @@ SRC_C += $(SRC_MAX32) \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ peripherals/$(MCU_VARIANT_LOWER)/pins.c \ - peripherals/$(MCU_VARIANT_LOWER)/gpios.c + peripherals/$(MCU_VARIANT_LOWER)/gpios.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_uart.c # ******************************************************************************* ### Compiler & Linker Flags ### From 1380af79aae33182845c869e0a7c40829bf0d315 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 14 Jan 2025 15:22:10 -0800 Subject: [PATCH 110/208] Add preliminary busio.UART support - Enabled BUSIO in mpconfigport.mk - Stubs added for busio.I2C & busio.SPI - Implemented busio.UART to basic working functionality - Added MCU-specific UART data in peripherals//max32_uart.c & max32_uart.h - Still have a couple issues where UART generates garbage characters or does not respond to timeouts / generate asynchronous IRQs --- ports/analog/common-hal/busio/I2C.c | 116 +---- ports/analog/common-hal/busio/SPI.c | 147 +------ ports/analog/common-hal/busio/UART.c | 406 +++++++++++++++++- ports/analog/common-hal/busio/UART.h | 33 +- ports/analog/max32_port.h | 52 +-- ports/analog/mpconfigport.mk | 3 +- .../analog/peripherals/max32690/max32_uart.c | 47 ++ .../analog/peripherals/max32690/max32_uart.h | 16 + 8 files changed, 527 insertions(+), 293 deletions(-) create mode 100644 ports/analog/peripherals/max32690/max32_uart.c create mode 100644 ports/analog/peripherals/max32690/max32_uart.h diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index ae18f561c502f..a8080fa5bc10d 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -30,7 +30,6 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -static I2CSPM_Init_TypeDef i2cspm_init; static bool in_used = false; // Construct I2C protocol, this function init i2c peripheral @@ -39,37 +38,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { - // Ensure the object starts in its deinit state. - common_hal_busio_i2c_mark_deinit(self); - - if ((scl != NULL) && (sda != NULL)) { - if (scl->function_list[ DEFAULT_I2C_PERIPHERAL == I2C1? - FN_I2C1_SCL : FN_I2C0_SCL] == 1 && - scl->function_list[DEFAULT_I2C_PERIPHERAL == I2C1? - FN_I2C1_SDA : FN_I2C0_SDA] == 1) { - self->scl = scl; - self->sda = sda; - self->has_lock = false; - i2cspm_init.sclPort = self->scl->port; - i2cspm_init.sclPin = self->scl->number; - i2cspm_init.sdaPort = self->sda->port; - i2cspm_init.sdaPin = self->sda->number; - i2cspm_init.port = DEFAULT_I2C_PERIPHERAL; - i2cspm_init.i2cRefFreq = 0; - i2cspm_init.i2cMaxFreq = I2C_FREQ_STANDARD_MAX; - i2cspm_init.i2cClhr = i2cClockHLRStandard; - - self->i2cspm = i2cspm_init.port; - I2CSPM_Init(&i2cspm_init); - common_hal_mcu_pin_claim(scl); - common_hal_mcu_pin_claim(sda); - in_used = true; - } else { - mp_raise_ValueError(MP_ERROR_TEXT("Hardware in use, try alternative pins")); - } - } else { - raise_ValueError_invalid_pins(); - } + } // Never reset I2C obj when reload @@ -85,53 +54,26 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { // Deinit i2c obj, reset I2C pin void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { - if (common_hal_busio_i2c_deinited(self)) { - return; - } - I2C_Reset(self->i2cspm); - common_hal_reset_pin(self->sda); - common_hal_reset_pin(self->scl); - self->i2cspm = NULL; - in_used = false; - common_hal_busio_i2c_mark_deinit(self); + // FIXME: Implement } void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { - self->sda = NULL; + // FIXME: Implement } // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - I2C_TransferSeq_TypeDef seq; - I2C_TransferReturn_TypeDef ret; - uint8_t data = 0; - - seq.addr = addr << 1; - seq.flags = I2C_FLAG_READ; - - seq.buf[0].data = &data; - seq.buf[0].len = 1; + // FIXME: Implement - ret = I2CSPM_Transfer(self->i2cspm, &seq); - if (ret != i2cTransferDone) { - return false; - } return true; } // Lock I2C bus bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { - if (common_hal_busio_i2c_deinited(self)) { - return false; - } - bool grabbed_lock = false; - if (!self->has_lock) { - grabbed_lock = true; - self->has_lock = true; - } + // FIXME: Implement - return grabbed_lock; + return false; } // Check I2C lock status @@ -148,19 +90,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { - I2C_TransferSeq_TypeDef seq; - I2C_TransferReturn_TypeDef ret; - - seq.addr = addr << 1; - seq.flags = I2C_FLAG_WRITE; - - seq.buf[0].data = (uint8_t *)data; - seq.buf[0].len = len; - - ret = I2CSPM_Transfer(self->i2cspm, &seq); - if (ret != i2cTransferDone) { - return MP_EIO; - } + // FIXME: Implement return 0; } @@ -169,19 +99,7 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - I2C_TransferSeq_TypeDef seq; - I2C_TransferReturn_TypeDef ret; - - seq.addr = addr << 1; - seq.flags = I2C_FLAG_READ; - - seq.buf[0].data = data; - seq.buf[0].len = len; - - ret = I2CSPM_Transfer(self->i2cspm, &seq); - if (ret != i2cTransferDone) { - return MP_EIO; - } + // FIXME: Implement return 0; } @@ -190,21 +108,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - I2C_TransferSeq_TypeDef seq; - I2C_TransferReturn_TypeDef ret; - - seq.addr = addr << 1; - seq.flags = I2C_FLAG_WRITE_READ; - // Select command to issue - seq.buf[0].data = out_data; - seq.buf[0].len = out_len; - // Select location/length of data to be read - seq.buf[1].data = in_data; - seq.buf[1].len = in_len; - - ret = I2CSPM_Transfer(self->i2cspm, &seq); - if (ret != i2cTransferDone) { - return MP_EIO; - } + // FIXME: Implement + return 0; } diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 74cfc69bfb2a0..083403b12bbe3 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -34,17 +34,9 @@ // Note that any bugs introduced in this file can cause crashes // at startupfor chips using external SPI flash. -static SPIDRV_HandleData_t spidrv_eusart_handle; -static SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; -static bool in_used = false; -static bool never_reset = false; - // Reset SPI when reload void spi_reset(void) { - if (!never_reset && in_used) { - SPIDRV_DeInit(&spidrv_eusart_handle); - in_used = false; - } + // FIXME: Implement return; } @@ -54,64 +46,14 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { - Ecode_t sc = ECODE_OK; - - if (half_duplex) { - mp_raise_NotImplementedError( - MP_ERROR_TEXT("Half duplex SPI is not implemented")); - } - - if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { - if (sck->function_list[FN_EUSART1_SCLK] == 1 - && miso->function_list[FN_EUSART1_RX] == 1 - && mosi->function_list[FN_EUSART1_TX] == 1) { - - self->sck = sck; - self->mosi = mosi; - self->miso = miso; - self->handle = &spidrv_eusart_handle; - self->polarity = 0; - self->phase = 0; - self->bits = 8; - - spidrv_eusart_init.portTx = mosi->port; - spidrv_eusart_init.portRx = miso->port; - spidrv_eusart_init.portClk = sck->port; - spidrv_eusart_init.pinTx = mosi->number; - spidrv_eusart_init.pinRx = miso->number; - spidrv_eusart_init.pinClk = sck->number; - spidrv_eusart_init.bitRate = 1000000; - spidrv_eusart_init.frameLength = 8; - spidrv_eusart_init.dummyTxValue = 0; - spidrv_eusart_init.type = spidrvMaster; - spidrv_eusart_init.bitOrder = spidrvBitOrderMsbFirst; - spidrv_eusart_init.clockMode = spidrvClockMode0; - spidrv_eusart_init.csControl = spidrvCsControlApplication; - spidrv_eusart_init.slaveStartMode = spidrvSlaveStartImmediate; - - sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); - if (sc != ECODE_EMDRV_SPIDRV_OK) { - mp_raise_ValueError(MP_ERROR_TEXT("SPI init error")); - } - } else { - mp_raise_ValueError(MP_ERROR_TEXT("Hardware in use, try alternative pins")); - } - } else { - raise_ValueError_invalid_pins(); - } - - in_used = true; - common_hal_mcu_pin_claim(sck); - common_hal_mcu_pin_claim(mosi); - common_hal_mcu_pin_claim(miso); + + + // FIXME: Implement } // Never reset SPI when reload void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset = true; - common_hal_never_reset_pin(self->mosi); - common_hal_never_reset_pin(self->miso); - common_hal_never_reset_pin(self->sck); + // FIXME: Implement } // Check SPI status, deinited or not @@ -122,23 +64,7 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { // Deinit SPI obj void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { - if (common_hal_busio_spi_deinited(self)) { - return; - } - - Ecode_t sc = SPIDRV_DeInit(self->handle); - if (sc != ECODE_EMDRV_SPIDRV_OK) { - mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); - } - - in_used = false; - self->sck = NULL; - self->mosi = NULL; - self->miso = NULL; - self->handle = NULL; - common_hal_reset_pin(self->mosi); - common_hal_reset_pin(self->miso); - common_hal_reset_pin(self->sck); + // FIXME: Implement } // Configures the SPI bus. The SPI object must be locked. @@ -147,55 +73,15 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint8_t polarity, uint8_t phase, uint8_t bits) { - Ecode_t sc; - // This resets the SPI, so check before updating it redundantly - if (baudrate == self->baudrate && polarity == self->polarity - && phase == self->phase && bits == self->bits) { - return true; - } - - sc = SPIDRV_DeInit(self->handle); - if (sc != ECODE_EMDRV_SPIDRV_OK) { - mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); - } - in_used = false; - self->baudrate = baudrate; - self->phase = phase; - self->bits = bits; - self->polarity = polarity; - - spidrv_eusart_init.bitRate = baudrate; - spidrv_eusart_init.frameLength = 8; - if (polarity == 0 && phase == 0) { - spidrv_eusart_init.clockMode = spidrvClockMode0; - } else if (polarity == 0 && phase == 1) { - spidrv_eusart_init.clockMode = spidrvClockMode1; - } else if (polarity == 1 && phase == 0) { - spidrv_eusart_init.clockMode = spidrvClockMode2; - } else if (polarity == 1 && phase == 1) { - spidrv_eusart_init.clockMode = spidrvClockMode3; - } - - sc = SPIDRV_Init(self->handle, &spidrv_eusart_init); - if (sc != ECODE_EMDRV_SPIDRV_OK) { - mp_raise_RuntimeError(MP_ERROR_TEXT("SPI re-init")); - } - in_used = true; + + // FIXME: Implement return true; } // Lock SPI bus bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { - if (common_hal_busio_spi_deinited(self)) { - return false; - } - bool grabbed_lock = false; - if (!self->has_lock) { - grabbed_lock = true; - self->has_lock = true; - } - - return grabbed_lock; + // FIXME: Implement + return false; } // Check SPI lock status @@ -213,8 +99,8 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) { - Ecode_t result = SPIDRV_MTransmitB(self->handle, data, len); - return result == ECODE_EMDRV_SPIDRV_OK; + // FIXME: Implement + return false; } // Read data into buffer @@ -222,9 +108,8 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { - self->handle->initData.dummyTxValue = write_value; - Ecode_t result = SPIDRV_MReceiveB(self->handle, data, len); - return result == ECODE_EMDRV_SPIDRV_OK; + // FIXME: Implement + return false; } // Write out the data in data_out @@ -234,8 +119,8 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_in, size_t len) { - Ecode_t result = SPIDRV_MTransferB(self->handle, data_out, data_in, len); - return result == ECODE_EMDRV_SPIDRV_OK; + // FIXME: Implement + return false; } // Get SPI baudrate diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 6d1507b78c696..ddffc8f55b9c3 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -26,8 +26,11 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +#include "supervisor/shared/tick.h" #include "shared-bindings/busio/UART.h" +#include "shared-bindings/microcontroller/Pin.h" + #include "mpconfigport.h" #include "shared/readline/readline.h" #include "shared/runtime/interrupt_char.h" @@ -35,42 +38,403 @@ #include "py/mperrno.h" #include "py/runtime.h" -#include "uart.h" +#include "max32_port.h" #include "UART.h" +#include "nvic_table.h" + +// UART IRQ Priority +#define UART_PRIORITY 1 + +/** + * +// Define a struct for what BUSIO.UART should contain +typedef struct { + mp_obj_base_t base; + int uart_id; + mxc_uart_regs_t* uart_regs; + + const mcu_pin_obj_t *rx_pin; + const mcu_pin_obj_t *tx_pin; + const mcu_pin_obj_t *rts_pin; + const mcu_pin_obj_t *cts_pin; + + uint8_t bits; + uint32_t baudrate; + bool parity; + uint8_t stop_bits; + + uint32_t timeout_ms; + bool error; +} busio_uart_obj_t; + */ + +typedef enum { + UART_9600 = 9600, + UART_14400 = 14400, + UART_19200 = 19200, + UART_38400 = 38400, + UART_57600 = 57600, + UART_115200 = 115200, + UART_230400 = 230400, + UART_460800 = 460800, + UART_921600 = 921600, +} uart_valid_baudrates; + typedef enum { - BUSIO_UART_PARITY_NONE, - BUSIO_UART_PARITY_EVEN, - BUSIO_UART_PARITY_ODD -} busio_uart_parity_t; + UART_FREE = 0, + UART_BUSY, + UART_NEVER_RESET, +} uart_status_t; + +static uint32_t timeout_ms=0; + +// Set each bit to indicate an active UART +// will be checked by ISR Handler for which ones to call +static uint8_t uarts_active = 0; +static uart_status_t uart_status[NUM_UARTS]; +// static uint8_t uart_never_reset_mask = 0; + +static int isValidBaudrate(uint32_t baudrate) { + switch(baudrate) { + case UART_9600: + return 1; + break; + case UART_14400: + return 1; + break; + case UART_19200: + return 1; + break; + case UART_38400: + return 1; + break; + case UART_57600: + return 1; + break; + case UART_115200: + return 1; + break; + case UART_230400: + return 1; + break; + case UART_460800: + return 1; + break; + case UART_921600: + return 1; + break; + default: + return 0; + break; + } +} + +static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) +{ + switch(busio_parity) { + case BUSIO_UART_PARITY_NONE: + return MXC_UART_PARITY_DISABLE; + case BUSIO_UART_PARITY_EVEN: + return MXC_UART_PARITY_EVEN_0; + case BUSIO_UART_PARITY_ODD: + return MXC_UART_PARITY_ODD_0; + default: + mp_raise_ValueError(MP_ERROR_TEXT("Parity must be ODD, EVEN, or NONE\n")); + } +} + +// FIXME: Find a better way of doing t his without a for loop +void UartISR(void) { + for (int i=0; i< NUM_UARTS; i++) { + if (uarts_active & (1 << i) ) { + MXC_UART_AsyncHandler(MXC_UART_GET_UART(i)); + uart_status[i] = UART_FREE; + } + } +} + +void uartCallback(mxc_uart_req_t *req, int error) { + +} // Construct an underlying UART object. -extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, +void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, const mcu_pin_obj_t *rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, - bool sigint_enabled); + bool sigint_enabled) +{ + int err, temp; + + // Check for NULL Pointers && valid UART settings + assert( self ); + + // Assign UART ID based on pins + temp = pinsToUart(tx, rx); + if (temp == -1) { + // Error will be indicated by pinsToUart(tx, rx) function + return; + } + else { + self->uart_id = temp; + self->uart_regs = MXC_UART_GET_UART(temp); + } + + assert( (self->uart_id >= 0) && (self->uart_id < NUM_UARTS) ); + + // Indicate RS485 not implemented + if ( (rs485_dir != NULL) || (rs485_invert) ) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("RS485")); + } + + if ((rx != NULL) && (tx != NULL)) { + err = MXC_UART_Init(self->uart_regs, baudrate, MXC_UART_IBRO_CLK); + if (err != E_NO_ERROR) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to initialize UART.\n")); + } + + // attach & configure pins + self->tx_pin = tx; + self->rx_pin = rx; + common_hal_mcu_pin_claim(self->tx_pin); + common_hal_mcu_pin_claim(self->rx_pin); + } + else if (tx != NULL) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); + } + else if (rx != NULL) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); + } + else { + // Should not get here, as shared-bindings API should not call this way + } + + if ((cts) && (rts)) { + MXC_UART_SetFlowCtrl(self->uart_regs, MXC_UART_FLOW_EN, 8); + self->cts_pin = cts; + self->rts_pin = rts; + common_hal_mcu_pin_claim(self->cts_pin); + common_hal_mcu_pin_claim(self->rts_pin); + } + else if (cts || rts) { + mp_raise_ValueError(MP_ERROR_TEXT("Flow Ctrl needs both CTS & RTS")); + } + + // Set stop bits & data size + assert( (stop == 1) || (stop == 2) ); + mp_arg_validate_int(bits, 8, MP_QSTR_bits); + MXC_UART_SetDataSize(self->uart_regs, bits); + MXC_UART_SetStopBits(self->uart_regs, stop); + + // Set parity + MXC_UART_SetParity(self->uart_regs, convertParity(parity)); + + // attach UART parameters + self->stop_bits = stop; // must be 1 or 2 + self->bits = bits; + self->parity = parity; + self->baudrate = baudrate; + self->error = E_NO_ERROR; -extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); -extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); + // Initialize ringbuffer for receiving data + if (self->rx_pin) { + // if given a ringbuff, use that + if (receiver_buffer) { + ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); + } + // else create one and attach it + else { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { + m_malloc_fail(receiver_buffer_size); + } + } + } + // Indicate to this module that the UART is active + uarts_active |= (1 << self->uart_id); + + MXC_UART_ClearFlags(self->uart_regs, self->uart_regs->int_fl); + + /* Enable UART interrupt */ + NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); + NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)UartISR); + + // FIXME: UART ISRs are NOT WORKING! + // MXC_UART_EnableInt(self->uart_regs, ???) + // NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + + return; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) +{ + assert(self); + + if (!common_hal_busio_uart_deinited(self)) { + // First disable the ISR to avoid pre-emption + NVIC_DisableIRQ(UART0_IRQn); + + MXC_UART_Shutdown(self->uart_regs); + self->error = E_UNINITIALIZED; + + assert(self->rx_pin && self->tx_pin); + reset_pin_number(self->rx_pin->port, self->rx_pin->mask); + reset_pin_number(self->tx_pin->port, self->tx_pin->mask); + + if (self->cts_pin && self->rts_pin) { + reset_pin_number(self->cts_pin->port, self->cts_pin->mask); + reset_pin_number(self->rts_pin->port, self->rts_pin->mask); + } + + self->tx_pin = NULL; + self->rx_pin = NULL; + self->cts_pin = NULL; + self->rts_pin = NULL; + + // Indicate to this module that the UART is not active + uarts_active &= ~(1 << self->uart_id); + } +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) +{ + if (uarts_active & (1 << self->uart_id)) { + return false; + } + else { + return true; + }; +} + +// todo: test // Read characters. len is in characters NOT bytes! -extern size_t common_hal_busio_uart_read(busio_uart_obj_t *self, - uint8_t *data, size_t len, int *errcode); +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, + uint8_t *data, size_t len, int *errcode) +{ + int err; + static size_t bytes_remaining; + + bytes_remaining = len * 4; + while(bytes_remaining > 0) { + mxc_uart_req_t uart_wr_req; + uart_wr_req.rxCnt = 0; + uart_wr_req.txCnt = 0; + uart_wr_req.rxData = data; + uart_wr_req.txData = NULL; + uart_wr_req.rxLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); + uart_wr_req.txLen = 0; + uart_wr_req.uart = self->uart_regs; + + err = MXC_UART_Transaction(&uart_wr_req); + if (err != E_NO_ERROR) { + *errcode = err; + return ((len * 4) - bytes_remaining); + } + bytes_remaining -= uart_wr_req.rxLen; + } + return len; +} + +//todo: test // Write characters. len is in characters NOT bytes! -extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self, - const uint8_t *data, size_t len, int *errcode); + size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode) +{ + int err; + uint32_t start_time=0; + static size_t bytes_remaining; + + bytes_remaining = len * 4; + + while(bytes_remaining > 0) { + mxc_uart_req_t uart_wr_req; + uart_wr_req.rxCnt = 0; + uart_wr_req.txCnt = 0; + uart_wr_req.rxData = NULL; + uart_wr_req.txData = data; + uart_wr_req.txLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); + uart_wr_req.rxLen = 0; + uart_wr_req.uart = self->uart_regs; + + uart_status[self->uart_id] = UART_BUSY; + start_time = supervisor_ticks_ms64(); + err = MXC_UART_Transaction(&uart_wr_req); + if (err != E_NO_ERROR) { + *errcode = err; + return ((len * 4) - bytes_remaining); + } + + // FIXME: NOT ENTERING ISR, NOT HANDLING TIMEOUT + // Wait for transaction completion + // FIXME: Test timeout & status flags + while ( (supervisor_ticks_ms64() - start_time < 500) + && (uart_status[self->uart_id] != UART_FREE) + ) {}; + + bytes_remaining -= uart_wr_req.txLen; + } + return len; +} + + uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) +{ + return self->baudrate; +} + +// Validate baudrate +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) +{ + if ( isValidBaudrate(baudrate) ) { + self->baudrate = baudrate; + } + else { + mp_raise_ValueError(MP_ERROR_TEXT("Baudrate invalid. Must be a standard UART baudrate.\n")); + } +} + +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) +{ + return self->timeout; +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) +{ + if (timeout > 100.0) { + mp_raise_ValueError(MP_ERROR_TEXT("Timeout must be < 100 seconds")); + } + + timeout_ms = 1000 * (uint32_t)timeout; + self->timeout = (uint32_t)timeout; + + return; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) +{ + return MXC_UART_GetRXFIFOAvailable(self->uart_regs); +} -extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self); -extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate); -extern mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self); -extern void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout); +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) +{ + MXC_UART_ClearRXFIFO(self->uart_regs); +} -extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self); -extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self); -extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self); +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) +{ + return !(MXC_UART_GetStatus(self->uart_regs) & (MXC_F_UART_STATUS_TX_BUSY)); +} -extern void common_hal_busio_uart_never_reset(busio_uart_obj_t *self); +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) +{ + common_hal_never_reset_pin(self->tx_pin); + common_hal_never_reset_pin(self->rx_pin); + common_hal_never_reset_pin(self->cts_pin); + common_hal_never_reset_pin(self->rts_pin); + // uart_never_reset_mask |= ( 1 << (self->uart_id) ); +} diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h index a8d294de222d3..3c76efc720e78 100644 --- a/ports/analog/common-hal/busio/UART.h +++ b/ports/analog/common-hal/busio/UART.h @@ -4,28 +4,43 @@ // // SPDX-License-Identifier: MIT -#ifndef MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H -#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H +#ifndef MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H #include "common-hal/microcontroller/Pin.h" -#include "peripherals/periph.h" #include "py/obj.h" #include "py/ringbuf.h" -#include "uart.h" +// #include "uart.h" +// #include "uart_regs.h" +// #include "mxc_sys.h" + +#include "max32_port.h" // Define a struct for what BUSIO.UART should contain typedef struct { mp_obj_base_t base; + + int uart_id; + int uart_map; mxc_uart_regs_t* uart_regs; - const mcu_pin_obj_t *rx; - const mcu_pin_obj_t *tx; - uint32_t baudrate; + bool parity; - uint8_t stop_bits; uint8_t bits; + uint8_t stop_bits; + uint32_t baudrate; + + int error; + float timeout; + + ringbuf_t ringbuf; + + const mcu_pin_obj_t *rx_pin; + const mcu_pin_obj_t *tx_pin; + const mcu_pin_obj_t *rts_pin; + const mcu_pin_obj_t *cts_pin; } busio_uart_obj_t; void uart_reset(void); -#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_UART_H +#endif // MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H diff --git a/ports/analog/max32_port.h b/ports/analog/max32_port.h index 5d92fcfe6d3ee..5c3811b651554 100644 --- a/ports/analog/max32_port.h +++ b/ports/analog/max32_port.h @@ -22,31 +22,35 @@ #include "system_max32690.h" #include "max32690.h" +// UART Ports & pins +#include "peripherals/max32690/max32_uart.h" +#define NUM_UARTS 4 + /** START: GPIO4 Handling specific to MAX32690 */ -#define GPIO4_PIN_MASK 0x00000003 -#define GPIO4_RESET_MASK 0xFFFFFF77 -#define GPIO4_OUTEN_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_OE_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_OE_POS - 1))) -#define GPIO4_PULLDIS_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_PE_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_PE_POS - 1))) -#define GPIO4_DATAOUT_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) -#define GPIO4_DATAOUT_GET_MASK(mask) \ - ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_DO) >> MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ - ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_DO) >> \ - (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) & \ - mask) -#define GPIO4_DATAIN_MASK(mask) \ - ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_IN) >> MXC_F_MCR_GPIO4_CTRL_P40_IN_POS) | \ - ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_IN) >> \ - (MXC_F_MCR_GPIO4_CTRL_P41_IN_POS - 1))) & \ - mask) -#define GPIO4_AFEN_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_OUTEN_PDOWN_OUT_EN_POS) | \ - ((mask & (1 << 1)) >> (MXC_F_MCR_OUTEN_SQWOUT_EN_POS + 1))) + #define GPIO4_PIN_MASK 0x00000003 + #define GPIO4_RESET_MASK 0xFFFFFF77 + #define GPIO4_OUTEN_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_OE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_OE_POS - 1))) + #define GPIO4_PULLDIS_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_PE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_PE_POS - 1))) + #define GPIO4_DATAOUT_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) + #define GPIO4_DATAOUT_GET_MASK(mask) \ + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_DO) >> MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_DO) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) & \ + mask) + #define GPIO4_DATAIN_MASK(mask) \ + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_IN) >> MXC_F_MCR_GPIO4_CTRL_P40_IN_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_IN) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_IN_POS - 1))) & \ + mask) + #define GPIO4_AFEN_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_OUTEN_PDOWN_OUT_EN_POS) | \ + ((mask & (1 << 1)) >> (MXC_F_MCR_OUTEN_SQWOUT_EN_POS + 1))) /** END: GPIO4 Handling specific to MAX32690 */ #endif diff --git a/ports/analog/mpconfigport.mk b/ports/analog/mpconfigport.mk index 97ead8efdfb0f..f1cd0bb2901e9 100644 --- a/ports/analog/mpconfigport.mk +++ b/ports/analog/mpconfigport.mk @@ -22,8 +22,7 @@ INTERNAL_FLASH_FILESYSTEM = 1 #################################################################################### # These modules are implemented in ports//common-hal: -# Plan to implement -CIRCUITPY_BUSIO ?= 0 +CIRCUITPY_BUSIO ?= 1 CIRCUITPY_RTC ?= 1 # Other modules (may or may not implement): diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c new file mode 100644 index 0000000000000..f8c53dc63218e --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/UART.h" +#include "max32_uart.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + +// FIXME: Remove upon test! +// mxc_uart_regs_t max32_uarts[NUM_UARTS] = { +// MXC_UART0, +// MXC_UART1, +// MXC_UART2, +// MXC_UART3, +// }; + +const mxc_gpio_cfg_t uart_maps[NUM_UARTS] = { + { MXC_GPIO2, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO2, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_16), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, + MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_WEAK_PULL_UP, + MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } +}; + +int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { + for (int i = 0; i < NUM_UARTS; i++) { + if ( (uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) + && (uart_maps[i].mask == (( tx->mask) | (rx->mask))) ) { + return i; + } + } + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find a uart matching pins...\nTX: port %d mask %d\nRX: port %d mask %d\n"), + tx->port, tx->mask, rx->port, rx->mask); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_uart.h b/ports/analog/peripherals/max32690/max32_uart.h new file mode 100644 index 0000000000000..f03b500a3c507 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_uart.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "uart_regs.h" +#include "mxc_sys.h" +#include "uart.h" +#include "peripherals/pins.h" + +#define NUM_UARTS 4 + +int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx); From 451e152d5b3d785b7e81a2fb575f4d22c33217c3 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 14 Jan 2025 15:26:49 -0800 Subject: [PATCH 111/208] Add tools files for debugging - Add debug-dap.sh to spawn OpenOCD process & gdb-multiarch process for debugging. Requires MaximSDK install & path settings inside this script. Also depends on gdb-multiarch and connected CMSIS-DAP probe over USB. - debug-dap.gdb simply holds the gdb commands for this script + small style fix on common-hal/microcontroller/Pin.c --- ports/analog/common-hal/microcontroller/Pin.c | 2 +- ports/analog/tools/debug-dap.gdb | 3 +++ ports/analog/tools/debug-dap.sh | 23 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ports/analog/tools/debug-dap.gdb create mode 100644 ports/analog/tools/debug-dap.sh diff --git a/ports/analog/common-hal/microcontroller/Pin.c b/ports/analog/common-hal/microcontroller/Pin.c index 4545aa039c2fa..6816054153e72 100644 --- a/ports/analog/common-hal/microcontroller/Pin.c +++ b/ports/analog/common-hal/microcontroller/Pin.c @@ -37,7 +37,7 @@ void reset_all_pins(void) { } void reset_pin_number(uint8_t pin_port, uint8_t pin_pad) { - if (pin_port == INVALID_PIN || pin_port > NUM_GPIO_PORTS) { + if ( (pin_port == INVALID_PIN) || (pin_port > NUM_GPIO_PORTS) ) { return; } diff --git a/ports/analog/tools/debug-dap.gdb b/ports/analog/tools/debug-dap.gdb new file mode 100644 index 0000000000000..d0aa7e2b13fa0 --- /dev/null +++ b/ports/analog/tools/debug-dap.gdb @@ -0,0 +1,3 @@ +target remote :3333 +break main +continue diff --git a/ports/analog/tools/debug-dap.sh b/ports/analog/tools/debug-dap.sh new file mode 100644 index 0000000000000..df2964fcb122a --- /dev/null +++ b/ports/analog/tools/debug-dap.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Primer on taking cmd line args in Linux shell scripts +# $0 is the script itself +# $1 $2 $3 are arg1, arg2, arg3, etc + +# Export OCD Path +### USER ACTION: Replace with your path to OpenOCD ### +OCD_PATH="~/MaximSDK/Tools/OpenOCD" + +# Call openocd to setup the debug server, storing the PID for OpenOCD +sh -c "openocd -s $OCD_PATH/scripts -f interface/cmsis-dap.cfg -f target/$1.cfg -c \"init; reset halt\" " & + +# Allow enough time for OCD server to set up +# + wait for the sleep to finish +sleep 3 & +wait $! + +# spawn the gdb process and store the gdb_pid +gdb-multiarch build-apard32690/firmware.elf -x "tools/debug-dap.gdb" + +# when gdb exits, kill all openocd processes +killall openocd From 13fb8f3d8f6d2d523f760c036a0d7cadcac2b312 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Fri, 24 Jan 2025 13:42:42 -0800 Subject: [PATCH 112/208] Fixed most UART write issues. - Graceful recovery from timeouts added - Remaining issue still exists where a timeout occurs after a while --- ports/analog/common-hal/busio/UART.c | 86 +++++++++++++++++----------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index ddffc8f55b9c3..4b0c8bfba6a81 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#if CIRCUITPY_BUSIO_UART + #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/tick.h" @@ -144,18 +146,21 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) } } -// FIXME: Find a better way of doing t his without a for loop -void UartISR(void) { - for (int i=0; i< NUM_UARTS; i++) { +// FIXME: Find a better way of doing this without a for loop +// FIXME: Fixed @ UART0 for TESTING BUGFIXES!!! +void UART0_IRQHandler(void) { + // MXC_UART_AsyncHandler(MXC_UART_GET_UART(0)); + for (int i=0; i < NUM_UARTS; i++) { if (uarts_active & (1 << i) ) { MXC_UART_AsyncHandler(MXC_UART_GET_UART(i)); - uart_status[i] = UART_FREE; } } } -void uartCallback(mxc_uart_req_t *req, int error) { - +// Callback gets called when AsyncRequest is COMPLETE +// (e.g. txLen == txCnt) +static volatile void uartCallback(mxc_uart_req_t *req, int error) { + uart_status[MXC_UART_GET_IDX(req->uart)] = UART_FREE; } // Construct an underlying UART object. @@ -256,17 +261,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Indicate to this module that the UART is active uarts_active |= (1 << self->uart_id); - MXC_UART_ClearFlags(self->uart_regs, self->uart_regs->int_fl); /* Enable UART interrupt */ NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); - NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)UartISR); - - // FIXME: UART ISRs are NOT WORKING! - // MXC_UART_EnableInt(self->uart_regs, ???) - // NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)&UART0_IRQHandler); return; } @@ -321,23 +321,30 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, bytes_remaining = len * 4; - while(bytes_remaining > 0) { - mxc_uart_req_t uart_wr_req; - uart_wr_req.rxCnt = 0; - uart_wr_req.txCnt = 0; - uart_wr_req.rxData = data; - uart_wr_req.txData = NULL; - uart_wr_req.rxLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); - uart_wr_req.txLen = 0; - uart_wr_req.uart = self->uart_regs; + MXC_UART_ClearFlags(self->uart_regs, 0xFFFFFFFF); + NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - err = MXC_UART_Transaction(&uart_wr_req); + while(bytes_remaining > 0) { + mxc_uart_req_t uart_rd_req; + uart_rd_req.rxCnt = 0; + uart_rd_req.txCnt = 0; + uart_rd_req.rxData = data; + uart_rd_req.txData = NULL; + uart_rd_req.rxLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); + uart_rd_req.txLen = 0; + uart_rd_req.uart = self->uart_regs; + uart_rd_req.callback = (void *)uartCallback; + + err = MXC_UART_TransactionAsync(&uart_rd_req); if (err != E_NO_ERROR) { *errcode = err; + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); return ((len * 4) - bytes_remaining); } - bytes_remaining -= uart_wr_req.rxLen; + bytes_remaining -= uart_rd_req.rxLen; } + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + return len; } @@ -350,7 +357,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint32_t start_time=0; static size_t bytes_remaining; - bytes_remaining = len * 4; + bytes_remaining = len; + + MXC_UART_ClearFlags(self->uart_regs, 0xFFFFFFFF); + NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); while(bytes_remaining > 0) { mxc_uart_req_t uart_wr_req; @@ -358,28 +368,38 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uart_wr_req.txCnt = 0; uart_wr_req.rxData = NULL; uart_wr_req.txData = data; - uart_wr_req.txLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); + uart_wr_req.txLen = bytes_remaining; uart_wr_req.rxLen = 0; uart_wr_req.uart = self->uart_regs; + uart_wr_req.callback = (void *)uartCallback; uart_status[self->uart_id] = UART_BUSY; start_time = supervisor_ticks_ms64(); - err = MXC_UART_Transaction(&uart_wr_req); + err = MXC_UART_TransactionAsync(&uart_wr_req); if (err != E_NO_ERROR) { *errcode = err; - return ((len * 4) - bytes_remaining); + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Requested bus is busy\n")); } - // FIXME: NOT ENTERING ISR, NOT HANDLING TIMEOUT // Wait for transaction completion - // FIXME: Test timeout & status flags - while ( (supervisor_ticks_ms64() - start_time < 500) - && (uart_status[self->uart_id] != UART_FREE) + while ( (uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000)) ) {}; - bytes_remaining -= uart_wr_req.txLen; + // If the timeout gets hit, abort and error out + if (uart_status[self->uart_id] != UART_FREE) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); + } + + bytes_remaining -= uart_wr_req.txCnt; } + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); return len; + } uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) @@ -438,3 +458,5 @@ void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) common_hal_never_reset_pin(self->rts_pin); // uart_never_reset_mask |= ( 1 << (self->uart_id) ); } + +#endif // CIRCUITPY_BUSIO_UART From 0f1d915f7c3521d877ce589c01e465c4b48be781 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Fri, 24 Jan 2025 17:08:32 -0800 Subject: [PATCH 113/208] Fix issues with UART reads and unreliable UART writes. - No ISR for UART writes, but uses timeouts - Reads use ISRs, but also incorporate timeouts --- ports/analog/common-hal/busio/UART.c | 162 ++++++++++++++++----------- 1 file changed, 98 insertions(+), 64 deletions(-) diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 4b0c8bfba6a81..ad5425d62ea31 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -95,6 +95,7 @@ static uint32_t timeout_ms=0; // will be checked by ISR Handler for which ones to call static uint8_t uarts_active = 0; static uart_status_t uart_status[NUM_UARTS]; +static volatile int uart_err; // static uint8_t uart_never_reset_mask = 0; static int isValidBaudrate(uint32_t baudrate) { @@ -146,12 +147,9 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) } } -// FIXME: Find a better way of doing this without a for loop -// FIXME: Fixed @ UART0 for TESTING BUGFIXES!!! void UART0_IRQHandler(void) { - // MXC_UART_AsyncHandler(MXC_UART_GET_UART(0)); - for (int i=0; i < NUM_UARTS; i++) { - if (uarts_active & (1 << i) ) { + for (int i = 0; i < NUM_UARTS; i++) { + if (uarts_active & (1 << i)) { MXC_UART_AsyncHandler(MXC_UART_GET_UART(i)); } } @@ -161,6 +159,7 @@ void UART0_IRQHandler(void) { // (e.g. txLen == txCnt) static volatile void uartCallback(mxc_uart_req_t *req, int error) { uart_status[MXC_UART_GET_IDX(req->uart)] = UART_FREE; + uart_err = error; } // Construct an underlying UART object. @@ -262,7 +261,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uarts_active |= (1 << self->uart_id); - /* Enable UART interrupt */ + /* Setup UART interrupt */ NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); @@ -311,45 +310,67 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) }; } -// todo: test // Read characters. len is in characters NOT bytes! size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { int err; + uint32_t start_time=0; static size_t bytes_remaining; - bytes_remaining = len * 4; + // Setup globals & status tracking + uart_err = E_NO_ERROR; + uarts_active |= (1 << self->uart_id); + uart_status[self->uart_id] = UART_BUSY; + bytes_remaining = len; - MXC_UART_ClearFlags(self->uart_regs, 0xFFFFFFFF); NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - while(bytes_remaining > 0) { - mxc_uart_req_t uart_rd_req; - uart_rd_req.rxCnt = 0; - uart_rd_req.txCnt = 0; - uart_rd_req.rxData = data; - uart_rd_req.txData = NULL; - uart_rd_req.rxLen = (uint32_t)( (bytes_remaining >= 255) ? 255 : bytes_remaining ); - uart_rd_req.txLen = 0; - uart_rd_req.uart = self->uart_regs; - uart_rd_req.callback = (void *)uartCallback; - - err = MXC_UART_TransactionAsync(&uart_rd_req); - if (err != E_NO_ERROR) { - *errcode = err; - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - return ((len * 4) - bytes_remaining); - } - bytes_remaining -= uart_rd_req.rxLen; + mxc_uart_req_t uart_rd_req; + uart_rd_req.rxCnt = 0; + uart_rd_req.txCnt = 0; + uart_rd_req.rxData = data; + uart_rd_req.txData = NULL; + uart_rd_req.rxLen = bytes_remaining; + uart_rd_req.txLen = 0; + uart_rd_req.uart = self->uart_regs; + uart_rd_req.callback = (void *)uartCallback; + + // Initiate the read transaction + start_time = supervisor_ticks_ms64(); + err = MXC_UART_TransactionAsync(&uart_rd_req); + if (err != E_NO_ERROR) { + *errcode = err; + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("\nERR: Error starting trasaction: %d\n"), err); } - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + // Wait for transaction completion or timeout + while ( (uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { + } + + // If the timeout gets hit, abort and error out + if (uart_status[self->uart_id] != UART_FREE) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); + } + + // Check for errors from the callback + else if (uart_err != E_NO_ERROR) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); + } + + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); return len; } -//todo: test // Write characters. len is in characters NOT bytes! +// This function blocks until the timeout finishes size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { @@ -357,49 +378,62 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint32_t start_time=0; static size_t bytes_remaining; + // Setup globals & status tracking + uart_err = E_NO_ERROR; + uarts_active |= (1 << self->uart_id); + uart_status[self->uart_id] = UART_BUSY; bytes_remaining = len; - MXC_UART_ClearFlags(self->uart_regs, 0xFFFFFFFF); - NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - - while(bytes_remaining > 0) { - mxc_uart_req_t uart_wr_req; - uart_wr_req.rxCnt = 0; - uart_wr_req.txCnt = 0; - uart_wr_req.rxData = NULL; - uart_wr_req.txData = data; - uart_wr_req.txLen = bytes_remaining; - uart_wr_req.rxLen = 0; - uart_wr_req.uart = self->uart_regs; - uart_wr_req.callback = (void *)uartCallback; - - uart_status[self->uart_id] = UART_BUSY; - start_time = supervisor_ticks_ms64(); - err = MXC_UART_TransactionAsync(&uart_wr_req); - if (err != E_NO_ERROR) { - *errcode = err; - MXC_UART_AbortAsync(self->uart_regs); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Requested bus is busy\n")); - } + mxc_uart_req_t uart_wr_req = {}; + + // Setup transaction + uart_wr_req.rxCnt = 0; + uart_wr_req.txCnt = 0; + uart_wr_req.rxData = NULL; + uart_wr_req.txData = data; + uart_wr_req.txLen = bytes_remaining; + uart_wr_req.rxLen = 0; + uart_wr_req.uart = self->uart_regs; + uart_wr_req.callback = (void *)uartCallback; + + // Start the transaction + start_time = supervisor_ticks_ms64(); + err = MXC_UART_TransactionAsync(&uart_wr_req); + if (err != E_NO_ERROR) { + *errcode = err; + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Requested bus is busy\n")); + } - // Wait for transaction completion - while ( (uart_status[self->uart_id] != UART_FREE) && - (supervisor_ticks_ms64() - start_time < (self->timeout * 1000)) - ) {}; + // Wait for transaction completion or timeout + while ( (uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { - // If the timeout gets hit, abort and error out - if (uart_status[self->uart_id] != UART_FREE) { - MXC_UART_AbortAsync(self->uart_regs); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); + // Call the handler and abort if errors + uart_err = MXC_UART_AsyncHandler(MXC_UART_GET_UART(0)); + if (uart_err != E_NO_ERROR) { + MXC_UART_AbortAsync(MXC_UART_GET_UART(0)); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(0)); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); } + } - bytes_remaining -= uart_wr_req.txCnt; + // If the timeout gets hit, abort and error out + if (uart_status[self->uart_id] != UART_FREE) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); } - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - return len; + // Check for errors from the callback + else if (uart_err != E_NO_ERROR) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); + } + + return len; } uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) From 72c4d438e19b9b76f4e68b06194dd8cc92ae4f88 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Mon, 27 Jan 2025 13:50:52 -0800 Subject: [PATCH 114/208] Add pre-commit changes to UART - Formatting & codespell fixes from pre-commit --- ports/analog/common-hal/busio/I2C.h | 2 +- ports/analog/common-hal/busio/SPI.h | 2 +- ports/analog/common-hal/busio/UART.c | 115 +++++++----------- ports/analog/common-hal/busio/UART.h | 2 +- ports/analog/common-hal/microcontroller/Pin.c | 2 +- ports/analog/max32_port.h | 32 ++--- .../analog/peripherals/max32690/max32_uart.c | 16 +-- 7 files changed, 74 insertions(+), 97 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.h b/ports/analog/common-hal/busio/I2C.h index c92283d6c53b6..9571a8ab694f4 100644 --- a/ports/analog/common-hal/busio/I2C.h +++ b/ports/analog/common-hal/busio/I2C.h @@ -17,7 +17,7 @@ // Define a struct for what BUSIO.I2C should carry typedef struct { mp_obj_base_t base; - mxc_i2c_regs_t* i2c_regs; + mxc_i2c_regs_t *i2c_regs; bool has_lock; const mcu_pin_obj_t *scl; const mcu_pin_obj_t *sda; diff --git a/ports/analog/common-hal/busio/SPI.h b/ports/analog/common-hal/busio/SPI.h index 8c48147ff6c77..d90f55da111a0 100644 --- a/ports/analog/common-hal/busio/SPI.h +++ b/ports/analog/common-hal/busio/SPI.h @@ -17,7 +17,7 @@ // Define a struct for what BUSIO.SPI should carry typedef struct { mp_obj_base_t base; - mxc_spi_regs_t* spi_regs; + mxc_spi_regs_t *spi_regs; bool has_lock; const mcu_pin_obj_t *sck; const mcu_pin_obj_t *mosi; diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index ad5425d62ea31..b4b17126e60e9 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -89,7 +89,7 @@ typedef enum { UART_NEVER_RESET, } uart_status_t; -static uint32_t timeout_ms=0; +static uint32_t timeout_ms = 0; // Set each bit to indicate an active UART // will be checked by ISR Handler for which ones to call @@ -99,7 +99,7 @@ static volatile int uart_err; // static uint8_t uart_never_reset_mask = 0; static int isValidBaudrate(uint32_t baudrate) { - switch(baudrate) { + switch (baudrate) { case UART_9600: return 1; break; @@ -133,17 +133,16 @@ static int isValidBaudrate(uint32_t baudrate) { } } -static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) -{ - switch(busio_parity) { - case BUSIO_UART_PARITY_NONE: - return MXC_UART_PARITY_DISABLE; - case BUSIO_UART_PARITY_EVEN: - return MXC_UART_PARITY_EVEN_0; - case BUSIO_UART_PARITY_ODD: - return MXC_UART_PARITY_ODD_0; - default: - mp_raise_ValueError(MP_ERROR_TEXT("Parity must be ODD, EVEN, or NONE\n")); +static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) { + switch (busio_parity) { + case BUSIO_UART_PARITY_NONE: + return MXC_UART_PARITY_DISABLE; + case BUSIO_UART_PARITY_EVEN: + return MXC_UART_PARITY_EVEN_0; + case BUSIO_UART_PARITY_ODD: + return MXC_UART_PARITY_ODD_0; + default: + mp_raise_ValueError(MP_ERROR_TEXT("Parity must be ODD, EVEN, or NONE\n")); } } @@ -169,33 +168,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t *rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, - bool sigint_enabled) -{ + bool sigint_enabled) { int err, temp; // Check for NULL Pointers && valid UART settings - assert( self ); + assert(self); // Assign UART ID based on pins temp = pinsToUart(tx, rx); if (temp == -1) { // Error will be indicated by pinsToUart(tx, rx) function return; - } - else { + } else { self->uart_id = temp; self->uart_regs = MXC_UART_GET_UART(temp); } - assert( (self->uart_id >= 0) && (self->uart_id < NUM_UARTS) ); + assert((self->uart_id >= 0) && (self->uart_id < NUM_UARTS)); // Indicate RS485 not implemented - if ( (rs485_dir != NULL) || (rs485_invert) ) { + if ((rs485_dir != NULL) || (rs485_invert)) { mp_raise_NotImplementedError(MP_ERROR_TEXT("RS485")); } if ((rx != NULL) && (tx != NULL)) { - err = MXC_UART_Init(self->uart_regs, baudrate, MXC_UART_IBRO_CLK); + err = MXC_UART_Init(self->uart_regs, baudrate, MXC_UART_IBRO_CLK); if (err != E_NO_ERROR) { mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to initialize UART.\n")); } @@ -205,14 +202,11 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->rx_pin = rx; common_hal_mcu_pin_claim(self->tx_pin); common_hal_mcu_pin_claim(self->rx_pin); - } - else if (tx != NULL) { + } else if (tx != NULL) { mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); - } - else if (rx != NULL) { + } else if (rx != NULL) { mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); - } - else { + } else { // Should not get here, as shared-bindings API should not call this way } @@ -222,13 +216,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->rts_pin = rts; common_hal_mcu_pin_claim(self->cts_pin); common_hal_mcu_pin_claim(self->rts_pin); - } - else if (cts || rts) { + } else if (cts || rts) { mp_raise_ValueError(MP_ERROR_TEXT("Flow Ctrl needs both CTS & RTS")); } // Set stop bits & data size - assert( (stop == 1) || (stop == 2) ); + assert((stop == 1) || (stop == 2)); mp_arg_validate_int(bits, 8, MP_QSTR_bits); MXC_UART_SetDataSize(self->uart_regs, bits); MXC_UART_SetStopBits(self->uart_regs, stop); @@ -270,8 +263,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, return; } -void common_hal_busio_uart_deinit(busio_uart_obj_t *self) -{ +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { assert(self); if (!common_hal_busio_uart_deinited(self)) { @@ -300,22 +292,19 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) } } -bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) -{ +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { if (uarts_active & (1 << self->uart_id)) { return false; - } - else { + } else { return true; }; } // Read characters. len is in characters NOT bytes! size_t common_hal_busio_uart_read(busio_uart_obj_t *self, - uint8_t *data, size_t len, int *errcode) -{ + uint8_t *data, size_t len, int *errcode) { int err; - uint32_t start_time=0; + uint32_t start_time = 0; static size_t bytes_remaining; // Setup globals & status tracking @@ -343,12 +332,12 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, *errcode = err; MXC_UART_AbortAsync(self->uart_regs); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("\nERR: Error starting trasaction: %d\n"), err); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("\nERR: Error starting transaction: %d\n"), err); } // Wait for transaction completion or timeout - while ( (uart_status[self->uart_id] != UART_FREE) && - (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { + while ((uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { } // If the timeout gets hit, abort and error out @@ -357,7 +346,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); mp_raise_RuntimeError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); } - // Check for errors from the callback else if (uart_err != E_NO_ERROR) { MXC_UART_AbortAsync(self->uart_regs); @@ -371,11 +359,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, // Write characters. len is in characters NOT bytes! // This function blocks until the timeout finishes - size_t common_hal_busio_uart_write(busio_uart_obj_t *self, - const uint8_t *data, size_t len, int *errcode) -{ +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode) { int err; - uint32_t start_time=0; + uint32_t start_time = 0; static size_t bytes_remaining; // Setup globals & status tracking @@ -407,8 +394,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, } // Wait for transaction completion or timeout - while ( (uart_status[self->uart_id] != UART_FREE) && - (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { + while ((uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { // Call the handler and abort if errors uart_err = MXC_UART_AsyncHandler(MXC_UART_GET_UART(0)); @@ -425,7 +412,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); } - // Check for errors from the callback else if (uart_err != E_NO_ERROR) { MXC_UART_AbortAsync(self->uart_regs); @@ -436,29 +422,24 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, return len; } - uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) -{ +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { return self->baudrate; } // Validate baudrate -void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) -{ - if ( isValidBaudrate(baudrate) ) { +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + if (isValidBaudrate(baudrate)) { self->baudrate = baudrate; - } - else { + } else { mp_raise_ValueError(MP_ERROR_TEXT("Baudrate invalid. Must be a standard UART baudrate.\n")); } } -mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) -{ +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { return self->timeout; } -void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) -{ +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { if (timeout > 100.0) { mp_raise_ValueError(MP_ERROR_TEXT("Timeout must be < 100 seconds")); } @@ -469,23 +450,19 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou return; } -uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) -{ +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { return MXC_UART_GetRXFIFOAvailable(self->uart_regs); } -void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) -{ +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { MXC_UART_ClearRXFIFO(self->uart_regs); } -bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) -{ +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { return !(MXC_UART_GetStatus(self->uart_regs) & (MXC_F_UART_STATUS_TX_BUSY)); } -void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) -{ +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { common_hal_never_reset_pin(self->tx_pin); common_hal_never_reset_pin(self->rx_pin); common_hal_never_reset_pin(self->cts_pin); diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h index 3c76efc720e78..f24f310fe3a52 100644 --- a/ports/analog/common-hal/busio/UART.h +++ b/ports/analog/common-hal/busio/UART.h @@ -23,7 +23,7 @@ typedef struct { int uart_id; int uart_map; - mxc_uart_regs_t* uart_regs; + mxc_uart_regs_t *uart_regs; bool parity; uint8_t bits; diff --git a/ports/analog/common-hal/microcontroller/Pin.c b/ports/analog/common-hal/microcontroller/Pin.c index 6816054153e72..83e2f3b9c3a76 100644 --- a/ports/analog/common-hal/microcontroller/Pin.c +++ b/ports/analog/common-hal/microcontroller/Pin.c @@ -37,7 +37,7 @@ void reset_all_pins(void) { } void reset_pin_number(uint8_t pin_port, uint8_t pin_pad) { - if ( (pin_port == INVALID_PIN) || (pin_port > NUM_GPIO_PORTS) ) { + if ((pin_port == INVALID_PIN) || (pin_port > NUM_GPIO_PORTS)) { return; } diff --git a/ports/analog/max32_port.h b/ports/analog/max32_port.h index 5c3811b651554..3b4fe7bc87d90 100644 --- a/ports/analog/max32_port.h +++ b/ports/analog/max32_port.h @@ -30,27 +30,27 @@ #define GPIO4_PIN_MASK 0x00000003 #define GPIO4_RESET_MASK 0xFFFFFF77 #define GPIO4_OUTEN_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_OE_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_OE_POS - 1))) + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_OE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_OE_POS - 1))) #define GPIO4_PULLDIS_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_PE_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_PE_POS - 1))) + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_PE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_PE_POS - 1))) #define GPIO4_DATAOUT_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ - ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) #define GPIO4_DATAOUT_GET_MASK(mask) \ - ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_DO) >> MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ - ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_DO) >> \ - (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) & \ - mask) + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_DO) >> MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_DO) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) & \ + mask) #define GPIO4_DATAIN_MASK(mask) \ - ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_IN) >> MXC_F_MCR_GPIO4_CTRL_P40_IN_POS) | \ - ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_IN) >> \ - (MXC_F_MCR_GPIO4_CTRL_P41_IN_POS - 1))) & \ - mask) + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_IN) >> MXC_F_MCR_GPIO4_CTRL_P40_IN_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_IN) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_IN_POS - 1))) & \ + mask) #define GPIO4_AFEN_MASK(mask) \ - (((mask & (1 << 0)) << MXC_F_MCR_OUTEN_PDOWN_OUT_EN_POS) | \ - ((mask & (1 << 1)) >> (MXC_F_MCR_OUTEN_SQWOUT_EN_POS + 1))) + (((mask & (1 << 0)) << MXC_F_MCR_OUTEN_PDOWN_OUT_EN_POS) | \ + ((mask & (1 << 1)) >> (MXC_F_MCR_OUTEN_SQWOUT_EN_POS + 1))) /** END: GPIO4 Handling specific to MAX32690 */ #endif diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c index f8c53dc63218e..3ccb930d85c14 100644 --- a/ports/analog/peripherals/max32690/max32_uart.c +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -23,21 +23,21 @@ const mxc_gpio_cfg_t uart_maps[NUM_UARTS] = { { MXC_GPIO2, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, { MXC_GPIO2, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_16), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), - MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, - MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, + MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), - MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_WEAK_PULL_UP, - MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_WEAK_PULL_UP, + MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } }; int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { for (int i = 0; i < NUM_UARTS; i++) { - if ( (uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) - && (uart_maps[i].mask == (( tx->mask) | (rx->mask))) ) { + if ((uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) + && (uart_maps[i].mask == ((tx->mask) | (rx->mask)))) { return i; } } From b741b3a7519011d6f4619a85b18b433bea511292 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Fri, 31 Jan 2025 16:45:13 -0800 Subject: [PATCH 115/208] Resolve UART ISR naming issues - Call NVIC_SetRAM in supervisor/port.c to move NVIC table to RAM, enabling ISR RAM remapping. - Rename UART ISR to be generic for any UART IRQn. - Remove background led writes from background.c. --- ports/analog/background.c | 10 ++-------- ports/analog/common-hal/busio/UART.c | 11 +++++++++-- ports/analog/supervisor/port.c | 8 ++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ports/analog/background.c b/ports/analog/background.c index ffad007ffa51c..ad840c6dcdabc 100644 --- a/ports/analog/background.c +++ b/ports/analog/background.c @@ -19,19 +19,13 @@ extern const mxc_gpio_cfg_t led_pin[]; extern const int num_leds; /** NOTE: ALL "ticks" refer to a 1/1024 s period */ -static int status_led_ticks = 0; +static int status_ticks = 0; // This function is where port-specific background // tasks should be performed // Execute port specific actions during background tick. Only if ticks are enabled. void port_background_tick(void) { - status_led_ticks++; - - // Set an LED approx. 1/s - if (status_led_ticks > 1024) { - MXC_GPIO_OutToggle(led_pin[2].port, led_pin[2].mask); - status_led_ticks = 0; - } + status_ticks++; } // Execute port specific actions during background tasks. This is before the diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index b4b17126e60e9..310965e34609b 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -146,7 +146,7 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) { } } -void UART0_IRQHandler(void) { +void uart_isr(void) { for (int i = 0; i < NUM_UARTS; i++) { if (uarts_active & (1 << i)) { MXC_UART_AsyncHandler(MXC_UART_GET_UART(i)); @@ -237,6 +237,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->error = E_NO_ERROR; // Initialize ringbuffer for receiving data + // FIXME: Either the use the ringbuf or get rid of it! if (self->rx_pin) { // if given a ringbuff, use that if (receiver_buffer) { @@ -253,12 +254,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Indicate to this module that the UART is active uarts_active |= (1 << self->uart_id); + // Set the timeout to a default value + if (((timeout < 0.0) || (timeout > 100.0))) { + self->timeout = 1.0; + } else { + self->timeout = timeout; + } /* Setup UART interrupt */ NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); - NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)&UART0_IRQHandler); + NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)uart_isr); return; } diff --git a/ports/analog/supervisor/port.c b/ports/analog/supervisor/port.c index ff05ff2d28709..de83b011bdf0d 100644 --- a/ports/analog/supervisor/port.c +++ b/ports/analog/supervisor/port.c @@ -39,6 +39,7 @@ // Sys includes #include "max32_port.h" +#include "nvic_table.h" // Timers #include "mxc_delay.h" @@ -78,6 +79,13 @@ void SysTick_Handler(void) { safe_mode_t port_init(void) { int err = E_NO_ERROR; + // Set Vector Table to RAM & configure ARM core to use RAM-based ISRs + // This allows definition of ISRs with custom names + // + // Useful for mapping ISRs with names not related to a specific IRQn. + // Source: https://arm-software.github.io/CMSIS_5/Core/html/using_VTOR_pg.html + NVIC_SetRAM(); + // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); NVIC_EnableIRQ(SysTick_IRQn); From aaeee4db835e9575ef5fc683f73d6a82c4552a02 Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Thu, 6 Mar 2025 23:57:59 -0800 Subject: [PATCH 116/208] Add BUSIO.I2C and MAX32690 I2C structure - Data structure and constructor for I2C (tested) - Lock and probing functions complete and tested TODO: Implement I2C Write, Read, Wr/Rd Signed-off-by: Brandon-Hurst --- ports/analog/Makefile | 15 +- ports/analog/common-hal/busio/I2C.c | 131 ++++++++++++++++-- ports/analog/common-hal/busio/I2C.h | 7 +- ports/analog/max32_port.h | 2 +- ports/analog/peripherals/max32690/max32_i2c.c | 35 +++++ ports/analog/peripherals/max32690/max32_i2c.h | 16 +++ 6 files changed, 194 insertions(+), 12 deletions(-) create mode 100644 ports/analog/peripherals/max32690/max32_i2c.c create mode 100644 ports/analog/peripherals/max32690/max32_i2c.h diff --git a/ports/analog/Makefile b/ports/analog/Makefile index 96f9037aae924..cba5608feaad6 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -88,7 +88,11 @@ INC += \ -I$(PERIPH_SRC)/TMR \ -I$(PERIPH_SRC)/RTC \ -I$(PERIPH_SRC)/UART \ +<<<<<<< HEAD -I$(PERIPH_SRC)/TRNG +======= + -I$(PERIPH_SRC)/I2C +>>>>>>> edf069d0e7 (Add BUSIO.I2C and MAX32690 I2C structure) INC += -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/GCC @@ -124,13 +128,17 @@ SRC_MAX32 += \ $(PERIPH_SRC)/UART/uart_revb.c \ $(PERIPH_SRC)/TRNG/trng_revb.c \ $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c + $(PERIPH_SRC)/I2C/i2c_$(DIE_TYPE).c \ + $(PERIPH_SRC)/I2C/i2c_reva.c SRC_C += $(SRC_MAX32) \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ peripherals/$(MCU_VARIANT_LOWER)/pins.c \ peripherals/$(MCU_VARIANT_LOWER)/gpios.c \ - peripherals/$(MCU_VARIANT_LOWER)/max32_uart.c + peripherals/$(MCU_VARIANT_LOWER)/max32_uart.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_i2c.c + # ******************************************************************************* ### Compiler & Linker Flags ### @@ -271,6 +279,11 @@ flash-msdk: -f interface/cmsis-dap.cfg -f target/$(MCU_VARIANT_LOWER).cfg \ -c "program $(BUILD)/firmware.elf verify; init; reset; exit" +flash-openocd-jlink: + $(OPENOCD) -s $(OPENOCD_SCRIPTS) \ + -f interface/jlink.cfg -f target/$(MCU_VARIANT_LOWER).cfg \ + -c "program $(BUILD)/firmware.elf verify; init; reset; exit" + # flash target using JLink JLINK_DEVICE = $(MCU_VARIANT_LOWER) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index a8080fa5bc10d..306b4bc8f4ab1 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -30,7 +30,38 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -static bool in_used = false; +#include "max32_port.h" + +#define I2C_PRIORITY 1 + +typedef enum { + I2C_FREE = 0, + I2C_BUSY, + I2C_NEVER_RESET, +} i2c_status_t; + +// Set each bit to indicate an active UART +// will be checked by ISR Handler for which ones to call +static uint8_t i2c_active = 0; +static i2c_status_t i2c_status[NUM_I2C]; +static volatile int i2c_err; + +// I2C Interrupt Handler +void i2c_isr(void) { + for (int i = 0; i < NUM_I2C; i++) { + if (i2c_active & (1 << i)) { + // NOTE: I2C_GET_TMR actually returns the I2C registers + MXC_I2C_AsyncHandler(MXC_I2C_GET_I2C(i)); + } + } +} + +// Callback gets called when AsyncRequest is COMPLETE +// (e.g. txLen == txCnt) +// static volatile void i2cCallback(mxc_i2c_req_t *req, int error) { +// i2c_status[MXC_I2C_GET_IDX(req->i2c)] = I2C_FREE; +// i2c_err = error; +// } // Construct I2C protocol, this function init i2c peripheral void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, @@ -38,7 +69,64 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { - + int temp, err = 0; + + // Check for NULL Pointers && valid I2C settings + assert(self); + + // Assign I2C ID based on pins + temp = pinsToI2c(sda, scl); + if (temp == -1) { + // Error will be indicated by pinsToUart(tx, rx) function + return; + } else { + self->i2c_id = temp; + self->i2c_regs = MXC_I2C_GET_I2C(temp); + } + + assert((self->i2c_id >= 0) && (self->i2c_id < NUM_I2C)); + + // Init I2C as main / controller node (0x00 is ignored) + if ((scl != NULL) && (sda != NULL)) { + err = MXC_I2C_Init(self->i2c_regs, 1, 0x00); + if (err) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to init I2C.\n")); + } + err = MXC_I2C_SetFrequency(self->i2c_regs, frequency); + if (err < 0) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to set I2C frequency\n")); + } + } else if (scl != NULL) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("I2C needs SDA & SCL")); + } else if (sda != NULL) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("I2C needs SDA & SCL")); + } else { + // Should not get here, as shared-bindings API should not call this way + } + + // Attach I2C pins + self->sda = sda; + self->scl = scl; + common_hal_mcu_pin_claim(self->sda); + common_hal_mcu_pin_claim(self->scl); + + // Indicate to this module that the I2C is active + i2c_active |= (1 << self->i2c_id); + + // Set the timeout to a default value + if (((timeout < 0.0) || (timeout > 100.0))) { + self->timeout = 1.0; + } else { + self->timeout = timeout; + } + + /* Setup I2C interrupt */ + NVIC_ClearPendingIRQ(MXC_I2C_GET_IRQ(self->i2c_id)); + NVIC_DisableIRQ(MXC_I2C_GET_IRQ(self->i2c_id)); + NVIC_SetPriority(MXC_I2C_GET_IRQ(self->i2c_id), I2C_PRIORITY); + NVIC_SetVector(MXC_I2C_GET_IRQ(self->i2c_id), (uint32_t)i2c_isr); + + return; } // Never reset I2C obj when reload @@ -54,7 +142,13 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { // Deinit i2c obj, reset I2C pin void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { - // FIXME: Implement + MXC_I2C_Shutdown(self->i2c_regs); + + common_hal_reset_pin(self->sda); + common_hal_reset_pin(self->scl); + + self->sda = NULL; + self->scl = NULL; } void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { @@ -63,17 +157,36 @@ void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - // FIXME: Implement - - return true; + int nack = 0; + + mxc_i2c_req_t addr_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_len = 0, + .tx_buf = NULL, + .rx_len = 0, + .rx_buf = NULL, + .callback = NULL + }; + + // Probe the address + nack = MXC_I2C_MasterTransaction(&addr_req); + if (nack) { + return false; + } else { + return true; + } } // Lock I2C bus bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { - // FIXME: Implement - - return false; + if (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) { + return false; + } else { + self->has_lock = true; + return true; + } } // Check I2C lock status diff --git a/ports/analog/common-hal/busio/I2C.h b/ports/analog/common-hal/busio/I2C.h index 9571a8ab694f4..2c7ffec20785e 100644 --- a/ports/analog/common-hal/busio/I2C.h +++ b/ports/analog/common-hal/busio/I2C.h @@ -17,8 +17,13 @@ // Define a struct for what BUSIO.I2C should carry typedef struct { mp_obj_base_t base; + + int i2c_id; mxc_i2c_regs_t *i2c_regs; - bool has_lock; const mcu_pin_obj_t *scl; const mcu_pin_obj_t *sda; + const int frequency; + + uint32_t timeout; + bool has_lock; } busio_i2c_obj_t; diff --git a/ports/analog/max32_port.h b/ports/analog/max32_port.h index 3b4fe7bc87d90..fcab5b5976238 100644 --- a/ports/analog/max32_port.h +++ b/ports/analog/max32_port.h @@ -24,7 +24,7 @@ // UART Ports & pins #include "peripherals/max32690/max32_uart.h" -#define NUM_UARTS 4 +#include "peripherals/max32690/max32_i2c.h" /** START: GPIO4 Handling specific to MAX32690 */ #define GPIO4_PIN_MASK 0x00000003 diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c new file mode 100644 index 0000000000000..8a13cf7a9a5a3 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -0,0 +1,35 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/I2C.h" +#include "max32_i2c.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + +const mxc_gpio_cfg_t i2c_maps[NUM_I2C] = { + // I2C0A + { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // I2C1A + { MXC_GPIO2, (MXC_GPIO_PIN_17 | MXC_GPIO_PIN_18), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, +}; + +int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { + for (int i = 0; i < NUM_I2C; i++) { + if ((i2c_maps[i].port == (MXC_GPIO_GET_GPIO(sda->port))) + && (i2c_maps[i].mask == ((sda->mask) | (scl->mask)))) { + return i; + } + } + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an I2C matching pins...\nSCL: port %d mask %d\nSDA: port %d mask %d\n"), + sda->port, sda->mask, scl->port, scl->mask); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_i2c.h b/ports/analog/peripherals/max32690/max32_i2c.h new file mode 100644 index 0000000000000..3e554da5abcde --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_i2c.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "i2c_regs.h" +#include "mxc_sys.h" +#include "i2c.h" +#include "peripherals/pins.h" + +#define NUM_I2C 2 + +int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl); From 00c53ea87d3da15e53843ba1177f140bab4bed2b Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Fri, 7 Mar 2025 00:37:46 -0800 Subject: [PATCH 117/208] Add hardware mapping for BUSIO.SPI for MAX32690 Currently coupled a bit to APARD32690-SL board. Will refactor after testing BUSIO.SPI Signed-off-by: Brandon-Hurst --- ports/analog/Makefile | 16 +++--- ports/analog/peripherals/max32690/max32_spi.c | 49 +++++++++++++++++++ ports/analog/peripherals/max32690/max32_spi.h | 17 +++++++ 3 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 ports/analog/peripherals/max32690/max32_spi.c create mode 100644 ports/analog/peripherals/max32690/max32_spi.h diff --git a/ports/analog/Makefile b/ports/analog/Makefile index cba5608feaad6..bd26cdd80f295 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -88,11 +88,9 @@ INC += \ -I$(PERIPH_SRC)/TMR \ -I$(PERIPH_SRC)/RTC \ -I$(PERIPH_SRC)/UART \ -<<<<<<< HEAD - -I$(PERIPH_SRC)/TRNG -======= - -I$(PERIPH_SRC)/I2C ->>>>>>> edf069d0e7 (Add BUSIO.I2C and MAX32690 I2C structure) + -I$(PERIPH_SRC)/TRNG \ + -I$(PERIPH_SRC)/I2C \ + -I$(PERIPH_SRC)/SPI INC += -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/GCC @@ -129,7 +127,9 @@ SRC_MAX32 += \ $(PERIPH_SRC)/TRNG/trng_revb.c \ $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c $(PERIPH_SRC)/I2C/i2c_$(DIE_TYPE).c \ - $(PERIPH_SRC)/I2C/i2c_reva.c + $(PERIPH_SRC)/I2C/i2c_reva.c \ + $(PERIPH_SRC)/SPI/spi_$(DIE_TYPE).c \ + $(PERIPH_SRC)/SPI/spi_reva1.c SRC_C += $(SRC_MAX32) \ boards/$(BOARD)/board.c \ @@ -137,8 +137,8 @@ SRC_C += $(SRC_MAX32) \ peripherals/$(MCU_VARIANT_LOWER)/pins.c \ peripherals/$(MCU_VARIANT_LOWER)/gpios.c \ peripherals/$(MCU_VARIANT_LOWER)/max32_uart.c \ - peripherals/$(MCU_VARIANT_LOWER)/max32_i2c.c - + peripherals/$(MCU_VARIANT_LOWER)/max32_i2c.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_spi.c # ******************************************************************************* ### Compiler & Linker Flags ### diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c new file mode 100644 index 0000000000000..587349b7e2140 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/SPI.h" +#include "max32_spi.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + +// TODO Decouple from APARD board +const mxc_gpio_cfg_t spi_maps[NUM_SPI] = { + // DUMMY entry for SPI0 (not on APARD board) + { MXC_GPIO0, 0xFFFFFFFF, 0, 0, 0, 0}, + + // SPI1A + { MXC_GPIO1, (MXC_GPIO_PIN_23 | MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI2A + { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4 | MXC_GPIO_PIN_5), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI3A + { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_19 | MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI4A + { MXC_GPIO1, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, +}; + +int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *cs) { + for (int i = 0; i < NUM_SPI; i++) { + if ((spi_maps[i].port == (MXC_GPIO_GET_GPIO(mosi->port))) + && (spi_maps[i].mask == ((cs->mask) | (mosi->mask) | (miso->mask) | (sck->mask)))) { + return i; + } + } + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an SPI matching pins... \ + \nMOSI: port %d mask %d\nMISO: port %d mask %d\n \ + \nSCK: port %d mask %d\nCS: port %d mask%d\n"), + mosi->port, mosi->mask, miso->port, miso->mask, + sck->port, sck->mask, cs->port, cs->mask); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_spi.h b/ports/analog/peripherals/max32690/max32_spi.h new file mode 100644 index 0000000000000..d0b9c83201c2b --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_spi.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "spi_regs.h" +#include "mxc_sys.h" +#include "spi.h" +#include "peripherals/pins.h" + +#define NUM_SPI 5 + +int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *cs); From 1d30ce794d1499168c08930f37d73e3e95e33596 Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Fri, 7 Mar 2025 02:16:40 -0800 Subject: [PATCH 118/208] Add complete BUSIO driver structure for SPI & I2C. TODO: - Figure out assigning CS Pins for SPI - Test & Debug SPI / I2C Signed-off-by: Brandon-Hurst --- ports/analog/common-hal/busio/I2C.c | 50 +++- ports/analog/common-hal/busio/SPI.c | 214 +++++++++++++++++- ports/analog/common-hal/busio/SPI.h | 9 +- ports/analog/max32_port.h | 1 + ports/analog/peripherals/max32690/max32_spi.c | 17 +- ports/analog/peripherals/max32690/max32_spi.h | 2 +- 6 files changed, 267 insertions(+), 26 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 306b4bc8f4ab1..1834db0e4a3d4 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -200,28 +200,72 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } // Write data to the device selected by address +// todo test uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { - // FIXME: Implement + int ret; + mxc_i2c_req_t wr_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = (uint8_t *)data, + .tx_len = len, + .rx_buf = NULL, + .rx_len = 0, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&wr_req); + if (ret) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + } + return 0; } // Read into buffer from the device selected by address +// todo test uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - // FIXME: Implement + int ret; + mxc_i2c_req_t rd_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = NULL, + .tx_len = 0, + .rx_buf = data, + .rx_len = len, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&rd_req); + if (ret) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + } + return 0; } // Write the bytes from out_data to the device selected by address, +// todo test uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - // FIXME: Implement + int ret; + mxc_i2c_req_t wr_rd_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = out_data, + .tx_len = out_len, + .rx_buf = in_data, + .rx_len = in_len, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&wr_rd_req); + if (ret) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + } return 0; } diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 083403b12bbe3..0c882d3ecc991 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -31,9 +31,35 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" +#include "max32_port.h" +#include "spi_reva1.h" + // Note that any bugs introduced in this file can cause crashes // at startupfor chips using external SPI flash. +#define SPI_PRIORITY 1 + +typedef enum { + SPI_FREE = 0, + SPI_BUSY, + SPI_NEVER_RESET, +} spi_status_t; + +// Set each bit to indicate an active SPI +// will be checked by ISR Handler for which ones to call +static uint8_t spi_active = 0; +static spi_status_t spi_status[NUM_SPI]; +static volatile int spi_err; + +// SPI Interrupt Handler +void spi_isr(void) { + for (int i = 0; i < NUM_SPI; i++) { + if (spi_active & (1 << i)) { + MXC_SPI_AsyncHandler(MXC_SPI_GET_SPI(i)); + } + } +} + // Reset SPI when reload void spi_reset(void) { // FIXME: Implement @@ -41,19 +67,69 @@ void spi_reset(void) { } // Construct SPI protocol, this function init SPI peripheral +// todo: figure out Chip select behavior void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + int temp, err = 0; + // Check for NULL Pointers && valid I2C settings + assert(self); - // FIXME: Implement + // Assign I2C ID based on pins + temp = pinsToSpi(mosi, miso, sck); + if (temp == -1) { + // Error will be indicated by pinsToUart(tx, rx) function + return; + } else { + self->spi_id = temp; + self->spi_regs = MXC_SPI_GET_SPI(temp); + } + + assert((self->spi_id >= 0) && (self->spi_id < NUM_SPI)); + + // Init I2C as main / controller node (0x00 is ignored) + // FIXME: MUST map the SPI pins to a spi_pins_t struct + if ((mosi != NULL) && (miso != NULL) && (sck != NULL)) { + // spi, mastermode, quadModeUsed, numSubs, ssPolarity, frequency + err = MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)self->spi_regs, 1, 0, 1, 0x00, 1000000); + if (err) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to init SPI.\n")); + } + } else { + mp_raise_NotImplementedError(MP_ERROR_TEXT("SPI needs MOSI, MISO, and SCK")); + } + + // Attach SPI pins + self->mosi = mosi; + self->miso = miso; + self->sck = sck; + common_hal_mcu_pin_claim(self->mosi); + common_hal_mcu_pin_claim(self->miso); + common_hal_mcu_pin_claim(self->sck); + + // Indicate to this module that the SPI is active + spi_active |= (1 << self->spi_id); + + /* Setup I2C interrupt */ + NVIC_ClearPendingIRQ(MXC_SPI_GET_IRQ(self->spi_id)); + NVIC_DisableIRQ(MXC_SPI_GET_IRQ(self->spi_id)); + NVIC_SetPriority(MXC_SPI_GET_IRQ(self->spi_id), SPI_PRIORITY); + NVIC_SetVector(MXC_SPI_GET_IRQ(self->spi_id), (uint32_t)spi_isr); + + return; } // Never reset SPI when reload void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - // FIXME: Implement + common_hal_never_reset_pin(self->mosi); + common_hal_never_reset_pin(self->miso); + common_hal_never_reset_pin(self->sck); + common_hal_never_reset_pin(self->nss); + + spi_status[self->spi_id] = SPI_NEVER_RESET; } // Check SPI status, deinited or not @@ -64,7 +140,16 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { // Deinit SPI obj void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { - // FIXME: Implement + MXC_SPI_Shutdown(self->spi_regs); + common_hal_reset_pin(self->mosi); + common_hal_reset_pin(self->miso); + common_hal_reset_pin(self->sck); + common_hal_reset_pin(self->nss); + + self->mosi = NULL; + self->miso = NULL; + self->sck = NULL; + self->nss = NULL; } // Configures the SPI bus. The SPI object must be locked. @@ -74,14 +159,58 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint8_t phase, uint8_t bits) { - // FIXME: Implement + mxc_spi_clkmode_t clk_mode; + int ret; + + self->baudrate = baudrate; + self->polarity = polarity; + self->phase = phase; + self->bits = bits; + + switch ((polarity << 1) | (phase)) { + case 0b00: + clk_mode = MXC_SPI_CLKMODE_0; + break; + case 0b01: + clk_mode = MXC_SPI_CLKMODE_1; + break; + case 0b10: + clk_mode = MXC_SPI_CLKMODE_2; + break; + case 0b11: + clk_mode = MXC_SPI_CLKMODE_3; + break; + default: + mp_raise_ValueError(MP_ERROR_TEXT("CPOL / CPHA must both be either 0 or 1\n")); + return false; + } + + ret = MXC_SPI_SetFrequency(self->spi_regs, baudrate); + if (ret) { + mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Frequency\n")); + return false; + } + ret = MXC_SPI_SetDataSize(self->spi_regs, bits); + if (ret) { + mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Frame Size\n")); + return false; + } + ret = MXC_SPI_SetMode(self->spi_regs, clk_mode); + if (ret) { + mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Clock Mode\n")); + return false; + } return true; } // Lock SPI bus bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { - // FIXME: Implement - return false; + if (spi_status[self->spi_id] != SPI_BUSY) { + self->has_lock = true; + return true; + } else { + return false; + } } // Check SPI lock status @@ -98,9 +227,27 @@ void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) { + int ret = 0; - // FIXME: Implement - return false; + mxc_spi_req_t wr_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = (uint8_t *)data, + .txLen = len, + .rxData = NULL, + .rxLen = 0, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = 0xFF, + }; + ret = MXC_SPI_MasterTransaction(&wr_req); + if (ret) { + return false; + } else { + return true; + } } // Read data into buffer @@ -108,8 +255,32 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { - // FIXME: Implement - return false; + int ret = 0; + // uint8_t tx_buffer[len] = {0x0}; + + // for (int i = 0; i < len; i++) { + // tx_buffer[i] = write_value; + // } + + mxc_spi_req_t rd_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = NULL, + .txLen = len, + .rxData = data, + .rxLen = len, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = write_value, + }; + ret = MXC_SPI_MasterTransaction(&rd_req); + if (ret) { + return false; + } else { + return true; + } } // Write out the data in data_out @@ -119,8 +290,27 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_in, size_t len) { - // FIXME: Implement - return false; + int ret = 0; + + mxc_spi_req_t rd_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = (uint8_t *)data_out, + .txLen = len, + .rxData = data_in, + .rxLen = len, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = 0xFF, + }; + ret = MXC_SPI_MasterTransaction(&rd_req); + if (ret) { + return false; + } else { + return true; + } } // Get SPI baudrate diff --git a/ports/analog/common-hal/busio/SPI.h b/ports/analog/common-hal/busio/SPI.h index d90f55da111a0..e70d4234d9407 100644 --- a/ports/analog/common-hal/busio/SPI.h +++ b/ports/analog/common-hal/busio/SPI.h @@ -17,17 +17,24 @@ // Define a struct for what BUSIO.SPI should carry typedef struct { mp_obj_base_t base; + + // Spi regs & pins + int spi_id; mxc_spi_regs_t *spi_regs; - bool has_lock; const mcu_pin_obj_t *sck; const mcu_pin_obj_t *mosi; const mcu_pin_obj_t *miso; const mcu_pin_obj_t *nss; + + // Configuration uint32_t baudrate; uint16_t prescaler; uint8_t polarity; uint8_t phase; uint8_t bits; + + // Synch data + bool has_lock; } busio_spi_obj_t; void spi_reset(void); diff --git a/ports/analog/max32_port.h b/ports/analog/max32_port.h index fcab5b5976238..89830e96b0a49 100644 --- a/ports/analog/max32_port.h +++ b/ports/analog/max32_port.h @@ -25,6 +25,7 @@ // UART Ports & pins #include "peripherals/max32690/max32_uart.h" #include "peripherals/max32690/max32_i2c.h" +#include "peripherals/max32690/max32_spi.h" /** START: GPIO4 Handling specific to MAX32690 */ #define GPIO4_PIN_MASK 0x00000003 diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c index 587349b7e2140..5a1dc8a9dc2f1 100644 --- a/ports/analog/peripherals/max32690/max32_spi.c +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -19,31 +19,30 @@ const mxc_gpio_cfg_t spi_maps[NUM_SPI] = { { MXC_GPIO0, 0xFFFFFFFF, 0, 0, 0, 0}, // SPI1A - { MXC_GPIO1, (MXC_GPIO_PIN_23 | MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), + { MXC_GPIO1, (MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // SPI2A - { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4 | MXC_GPIO_PIN_5), + { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // SPI3A - { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_19 | MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21), + { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // SPI4A - { MXC_GPIO1, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), + { MXC_GPIO1, (MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, }; int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, - const mcu_pin_obj_t *sck, const mcu_pin_obj_t *cs) { + const mcu_pin_obj_t *sck) { for (int i = 0; i < NUM_SPI; i++) { if ((spi_maps[i].port == (MXC_GPIO_GET_GPIO(mosi->port))) - && (spi_maps[i].mask == ((cs->mask) | (mosi->mask) | (miso->mask) | (sck->mask)))) { + && (spi_maps[i].mask == ((mosi->mask) | (miso->mask) | (sck->mask)))) { return i; } } mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an SPI matching pins... \ - \nMOSI: port %d mask %d\nMISO: port %d mask %d\n \ - \nSCK: port %d mask %d\nCS: port %d mask%d\n"), + \nMOSI: port %d mask %d\nMISO: port %d mask %d\n"), mosi->port, mosi->mask, miso->port, miso->mask, - sck->port, sck->mask, cs->port, cs->mask); + sck->port, sck->mask); return -1; } diff --git a/ports/analog/peripherals/max32690/max32_spi.h b/ports/analog/peripherals/max32690/max32_spi.h index d0b9c83201c2b..76bb48a59a7e5 100644 --- a/ports/analog/peripherals/max32690/max32_spi.h +++ b/ports/analog/peripherals/max32690/max32_spi.h @@ -14,4 +14,4 @@ #define NUM_SPI 5 int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, - const mcu_pin_obj_t *sck, const mcu_pin_obj_t *cs); + const mcu_pin_obj_t *sck); From 7cccb66c2a9ea426eeff6d468f9ecd2b10da337f Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Fri, 7 Mar 2025 13:28:36 -0800 Subject: [PATCH 119/208] Add call to MXC_DelayHandler in SysTick ISR Signed-off-by: Brandon-Hurst --- ports/analog/supervisor/port.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/analog/supervisor/port.c b/ports/analog/supervisor/port.c index de83b011bdf0d..40e8e1d605038 100644 --- a/ports/analog/supervisor/port.c +++ b/ports/analog/supervisor/port.c @@ -73,6 +73,8 @@ volatile uint32_t system_ticks = 0; void SysTick_Handler(void) { system_ticks++; + + MXC_DelayHandler(); } From ebfbd01ce103d56655052efd5d6b3b71f5d49c85 Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Fri, 7 Mar 2025 14:35:50 -0800 Subject: [PATCH 120/208] Corrected I2C & SPI. Tested with example scripts; works with real peripherals. Signed-off-by: Brandon-Hurst --- ports/analog/Makefile | 2 +- ports/analog/common-hal/busio/I2C.c | 8 ++++++-- ports/analog/common-hal/busio/SPI.c | 20 ++++++++++++++++++- ports/analog/peripherals/max32690/max32_i2c.c | 4 ++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ports/analog/Makefile b/ports/analog/Makefile index bd26cdd80f295..4a758eff9c46d 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -288,7 +288,7 @@ flash-openocd-jlink: JLINK_DEVICE = $(MCU_VARIANT_LOWER) JLINKEXE ?= JLink.exe -JLINKEXE += -if SWD -device ${JLINK_DEVICE} -speed 10000 +JLINKEXE += -if SWD -device ${JLINK_DEVICE} -speed 4000 COMMAND_FILE := tools/flash_max32.jlink flash-jlink: $(BUILD)/firmware.bin diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 1834db0e4a3d4..cba8fca94f50e 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -46,6 +46,9 @@ static uint8_t i2c_active = 0; static i2c_status_t i2c_status[NUM_I2C]; static volatile int i2c_err; +// I2C struct for configuring GPIO pins +extern const mxc_gpio_cfg_t i2c_maps[NUM_I2C]; + // I2C Interrupt Handler void i2c_isr(void) { for (int i = 0; i < NUM_I2C; i++) { @@ -88,13 +91,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // Init I2C as main / controller node (0x00 is ignored) if ((scl != NULL) && (sda != NULL)) { + MXC_GPIO_Config(&i2c_maps[self->i2c_id]); err = MXC_I2C_Init(self->i2c_regs, 1, 0x00); if (err) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to init I2C.\n")); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to init I2C. ERR: %d\n"), err); } err = MXC_I2C_SetFrequency(self->i2c_regs, frequency); if (err < 0) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to set I2C frequency\n")); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to set I2C frequency. ERR: %d\n"), err); } } else if (scl != NULL) { mp_raise_NotImplementedError(MP_ERROR_TEXT("I2C needs SDA & SCL")); diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 0c882d3ecc991..7f19ebd1f945c 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -88,13 +88,28 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, self->spi_regs = MXC_SPI_GET_SPI(temp); } + // Other pins default to true + mxc_spi_pins_t spi_pins = { + .clock = TRUE, + .mosi = TRUE, + .miso = TRUE, + .ss0 = FALSE, + .ss1 = FALSE, + .ss2 = FALSE, + .vddioh = true, + .drvstr = MXC_GPIO_DRVSTR_0 + }; + assert((self->spi_id >= 0) && (self->spi_id < NUM_SPI)); // Init I2C as main / controller node (0x00 is ignored) // FIXME: MUST map the SPI pins to a spi_pins_t struct if ((mosi != NULL) && (miso != NULL) && (sck != NULL)) { // spi, mastermode, quadModeUsed, numSubs, ssPolarity, frequency - err = MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)self->spi_regs, 1, 0, 1, 0x00, 1000000); + // err = MXC_SPI_Init((mxc_spi_reva_regs_t *)self->spi_regs, 1, 0, 1, 0x00, 1000000, &spi_pins); + err = MXC_SPI_Init(self->spi_regs, MXC_SPI_TYPE_CONTROLLER, MXC_SPI_INTERFACE_STANDARD, + 1, 0x01, 1000000, spi_pins); + MXC_GPIO_SetVSSEL(MXC_GPIO_GET_GPIO(sck->port), MXC_GPIO_VSSEL_VDDIOH, (sck->mask | miso->mask | mosi->mask | MXC_GPIO_PIN_0)); if (err) { mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to init SPI.\n")); } @@ -102,6 +117,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError(MP_ERROR_TEXT("SPI needs MOSI, MISO, and SCK")); } + // FIXME: Debugging + + // Attach SPI pins self->mosi = mosi; self->miso = miso; diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c index 8a13cf7a9a5a3..2dabc9b16a768 100644 --- a/ports/analog/peripherals/max32690/max32_i2c.c +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -16,10 +16,10 @@ const mxc_gpio_cfg_t i2c_maps[NUM_I2C] = { // I2C0A { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, // I2C1A { MXC_GPIO2, (MXC_GPIO_PIN_17 | MXC_GPIO_PIN_18), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, }; int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { From 558eb93a590229c2eeff5c93b30500d8a8b90990 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Mon, 17 Mar 2025 17:14:08 -0700 Subject: [PATCH 121/208] Add extra I2C options for MAX32690 non-TQFN packages Also reformatted pinmaps for SPI/I2C/UART on MAX32690 Signed-off-by: Brandon Hurst --- ports/analog/peripherals/max32690/max32_i2c.c | 41 +++++++++++++++++++ ports/analog/peripherals/max32690/max32_spi.c | 15 ++++--- .../analog/peripherals/max32690/max32_uart.c | 20 +++------ 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c index 2dabc9b16a768..d5c8da0743129 100644 --- a/ports/analog/peripherals/max32690/max32_i2c.c +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -13,14 +13,44 @@ #include "py/runtime.h" #include "py/mperrno.h" + +/* Note: The MAX32690 assigns the same alternate function to multiple sets + * of pins. The drivers will enable both sets so that either can be used. + * Users should ensure the unused set is left unconnected. + * + * See MAX32690 Rev A2 Errata #16: + * https://www.analog.com/media/en/technical-documentation/data-sheets/max32690_a2_errata_rev2.pdf + * + * Additionally, note that the TQFN package does not expose some of the duplicate pins. For this package, + * enabling the un-routed GPIOs has been shown to cause initialization issues with the I2C block. + * To work around this, "MAX32690GTK_PACKAGE_TQFN" can be defined by the build system. The recommend place + * to do it is in the "board.mk" file of the BSP. This will prevent the inaccessible pins from being configured. + */ + const mxc_gpio_cfg_t i2c_maps[NUM_I2C] = { + // I2C0 + { MXC_GPIO2, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + // I2C1 + { MXC_GPIO0, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + // I2C2 + { MXC_GPIO1, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT3, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 };, +}; +#ifndef MAX32690GTK_PACKAGE_TQFN +const mxc_gpio_cfg_t i2c_maps_extra[NUM_I2C] = { // I2C0A { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, // I2C1A { MXC_GPIO2, (MXC_GPIO_PIN_17 | MXC_GPIO_PIN_18), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, + // I2C2C + { MXC_GPIO0, (MXC_GPIO_PIN_13 | MXC_GPIO_PIN_14), MXC_GPIO_FUNC_ALT3, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 };, }; +#endif int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { for (int i = 0; i < NUM_I2C; i++) { @@ -29,6 +59,17 @@ int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { return i; } } + + // Additional for loop to cover alternate potential I2C maps + #ifndef MAX32690GTK_PACKAGE_TQFN + for (int i = 0; i < NUM_I2C; i++) { + if ((i2c_maps_extra[i].port == (MXC_GPIO_GET_GPIO(sda->port))) + && (i2c_maps_extra[i].mask == ((sda->mask) | (scl->mask)))) { + return i; + } + } + #endif + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an I2C matching pins...\nSCL: port %d mask %d\nSDA: port %d mask %d\n"), sda->port, sda->mask, scl->port, scl->mask); return -1; diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c index 5a1dc8a9dc2f1..ecd197036a49d 100644 --- a/ports/analog/peripherals/max32690/max32_spi.c +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -13,21 +13,20 @@ #include "py/runtime.h" #include "py/mperrno.h" -// TODO Decouple from APARD board const mxc_gpio_cfg_t spi_maps[NUM_SPI] = { - // DUMMY entry for SPI0 (not on APARD board) - { MXC_GPIO0, 0xFFFFFFFF, 0, 0, 0, 0}, - - // SPI1A + // SPI0 + { MXC_GPIO2, (MXC_GPIO_PIN_27 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + // SPI1 { MXC_GPIO1, (MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - // SPI2A + // SPI2 { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - // SPI3A + // SPI3 { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - // SPI4A + // SPI4 { MXC_GPIO1, (MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, }; diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c index 3ccb930d85c14..3cfcc75ca0dc0 100644 --- a/ports/analog/peripherals/max32690/max32_uart.c +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -13,29 +13,19 @@ #include "py/runtime.h" #include "py/mperrno.h" -// FIXME: Remove upon test! -// mxc_uart_regs_t max32_uarts[NUM_UARTS] = { -// MXC_UART0, -// MXC_UART1, -// MXC_UART2, -// MXC_UART3, -// }; - const mxc_gpio_cfg_t uart_maps[NUM_UARTS] = { { MXC_GPIO2, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, { MXC_GPIO2, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_16), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), - MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, - MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), - MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_WEAK_PULL_UP, - MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } + { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } }; int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { - for (int i = 0; i < NUM_UARTS; i++) { + for (int i = 0; i < uart_entries; i++) { if ((uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) && (uart_maps[i].mask == ((tx->mask) | (rx->mask)))) { return i; From 479e0e181122c8888acd0c79151ce0e2c88bf28f Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Thu, 1 May 2025 17:23:33 -0700 Subject: [PATCH 122/208] Clean up MAX32 BUSIO drivers - Fixed errors with peripheral bus hardware descriptions in MAX32690 "peripherals/" - Resolved all FIXME comments - Removed unused ringbuf API from common-hal/busio/UART.c Signed-off-by: Brandon Hurst --- ports/analog/common-hal/busio/I2C.c | 4 --- ports/analog/common-hal/busio/SPI.c | 13 +--------- ports/analog/common-hal/busio/UART.c | 25 ++++--------------- ports/analog/common-hal/busio/UART.h | 2 -- ports/analog/peripherals/max32690/max32_i2c.c | 10 ++++---- ports/analog/peripherals/max32690/max32_i2c.h | 2 +- ports/analog/peripherals/max32690/max32_spi.c | 2 +- .../analog/peripherals/max32690/max32_uart.c | 6 ++--- 8 files changed, 16 insertions(+), 48 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index cba8fca94f50e..f8a5a8bd20971 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -155,10 +155,6 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { self->scl = NULL; } -void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { - // FIXME: Implement -} - // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { int nack = 0; diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 7f19ebd1f945c..d158f09673189 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -60,12 +60,6 @@ void spi_isr(void) { } } -// Reset SPI when reload -void spi_reset(void) { - // FIXME: Implement - return; -} - // Construct SPI protocol, this function init SPI peripheral // todo: figure out Chip select behavior void common_hal_busio_spi_construct(busio_spi_obj_t *self, @@ -102,11 +96,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, assert((self->spi_id >= 0) && (self->spi_id < NUM_SPI)); - // Init I2C as main / controller node (0x00 is ignored) - // FIXME: MUST map the SPI pins to a spi_pins_t struct + // Init SPI controller if ((mosi != NULL) && (miso != NULL) && (sck != NULL)) { // spi, mastermode, quadModeUsed, numSubs, ssPolarity, frequency - // err = MXC_SPI_Init((mxc_spi_reva_regs_t *)self->spi_regs, 1, 0, 1, 0x00, 1000000, &spi_pins); err = MXC_SPI_Init(self->spi_regs, MXC_SPI_TYPE_CONTROLLER, MXC_SPI_INTERFACE_STANDARD, 1, 0x01, 1000000, spi_pins); MXC_GPIO_SetVSSEL(MXC_GPIO_GET_GPIO(sck->port), MXC_GPIO_VSSEL_VDDIOH, (sck->mask | miso->mask | mosi->mask | MXC_GPIO_PIN_0)); @@ -117,9 +109,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError(MP_ERROR_TEXT("SPI needs MOSI, MISO, and SCK")); } - // FIXME: Debugging - - // Attach SPI pins self->mosi = mosi; self->miso = miso; diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 310965e34609b..408ae8452352e 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -96,7 +96,7 @@ static uint32_t timeout_ms = 0; static uint8_t uarts_active = 0; static uart_status_t uart_status[NUM_UARTS]; static volatile int uart_err; -// static uint8_t uart_never_reset_mask = 0; +static uint8_t uart_never_reset_mask = 0; static int isValidBaudrate(uint32_t baudrate) { switch (baudrate) { @@ -167,8 +167,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, const mcu_pin_obj_t *rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, - mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, - bool sigint_enabled) { + mp_float_t timeout, bool sigint_enabled) { int err, temp; // Check for NULL Pointers && valid UART settings @@ -236,21 +235,6 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->baudrate = baudrate; self->error = E_NO_ERROR; - // Initialize ringbuffer for receiving data - // FIXME: Either the use the ringbuf or get rid of it! - if (self->rx_pin) { - // if given a ringbuff, use that - if (receiver_buffer) { - ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); - } - // else create one and attach it - else { - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { - m_malloc_fail(receiver_buffer_size); - } - } - } - // Indicate to this module that the UART is active uarts_active |= (1 << self->uart_id); @@ -277,6 +261,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { // First disable the ISR to avoid pre-emption NVIC_DisableIRQ(UART0_IRQn); + // Shutdown the UART Controller MXC_UART_Shutdown(self->uart_regs); self->error = E_UNINITIALIZED; @@ -307,7 +292,7 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { }; } -// Read characters. len is in characters NOT bytes! +// Read characters. len is in characters. size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { int err; @@ -474,7 +459,7 @@ void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { common_hal_never_reset_pin(self->rx_pin); common_hal_never_reset_pin(self->cts_pin); common_hal_never_reset_pin(self->rts_pin); - // uart_never_reset_mask |= ( 1 << (self->uart_id) ); + uart_never_reset_mask |= (1 << (self->uart_id)); } #endif // CIRCUITPY_BUSIO_UART diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h index f24f310fe3a52..c2c2d837ca8a5 100644 --- a/ports/analog/common-hal/busio/UART.h +++ b/ports/analog/common-hal/busio/UART.h @@ -33,8 +33,6 @@ typedef struct { int error; float timeout; - ringbuf_t ringbuf; - const mcu_pin_obj_t *rx_pin; const mcu_pin_obj_t *tx_pin; const mcu_pin_obj_t *rts_pin; diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c index d5c8da0743129..daf665bbee741 100644 --- a/ports/analog/peripherals/max32690/max32_i2c.c +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -20,7 +20,7 @@ * * See MAX32690 Rev A2 Errata #16: * https://www.analog.com/media/en/technical-documentation/data-sheets/max32690_a2_errata_rev2.pdf - * + * * Additionally, note that the TQFN package does not expose some of the duplicate pins. For this package, * enabling the un-routed GPIOs has been shown to cause initialization issues with the I2C block. * To work around this, "MAX32690GTK_PACKAGE_TQFN" can be defined by the build system. The recommend place @@ -30,13 +30,13 @@ const mxc_gpio_cfg_t i2c_maps[NUM_I2C] = { // I2C0 { MXC_GPIO2, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // I2C1 { MXC_GPIO0, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // I2C2 { MXC_GPIO1, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT3, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 };, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, }; #ifndef MAX32690GTK_PACKAGE_TQFN const mxc_gpio_cfg_t i2c_maps_extra[NUM_I2C] = { @@ -48,7 +48,7 @@ const mxc_gpio_cfg_t i2c_maps_extra[NUM_I2C] = { MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, // I2C2C { MXC_GPIO0, (MXC_GPIO_PIN_13 | MXC_GPIO_PIN_14), MXC_GPIO_FUNC_ALT3, - MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 };, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, }; #endif diff --git a/ports/analog/peripherals/max32690/max32_i2c.h b/ports/analog/peripherals/max32690/max32_i2c.h index 3e554da5abcde..b64cfd308dcf5 100644 --- a/ports/analog/peripherals/max32690/max32_i2c.h +++ b/ports/analog/peripherals/max32690/max32_i2c.h @@ -11,6 +11,6 @@ #include "i2c.h" #include "peripherals/pins.h" -#define NUM_I2C 2 +#define NUM_I2C 3 int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl); diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c index ecd197036a49d..f2594787598b2 100644 --- a/ports/analog/peripherals/max32690/max32_spi.c +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -16,7 +16,7 @@ const mxc_gpio_cfg_t spi_maps[NUM_SPI] = { // SPI0 { MXC_GPIO2, (MXC_GPIO_PIN_27 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), - MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, // SPI1 { MXC_GPIO1, (MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c index 3cfcc75ca0dc0..5f7a8568fb426 100644 --- a/ports/analog/peripherals/max32690/max32_uart.c +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -18,14 +18,14 @@ const mxc_gpio_cfg_t uart_maps[NUM_UARTS] = { MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, { MXC_GPIO2, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_16), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), MXC_GPIO_FUNC_ALT1, + { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, - { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT2, + { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } }; int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { - for (int i = 0; i < uart_entries; i++) { + for (int i = 0; i < NUM_UARTS; i++) { if ((uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) && (uart_maps[i].mask == ((tx->mask) | (rx->mask)))) { return i; From 3a8e56d0c8c5dacd664a0483217b85b189c5b0a9 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Thu, 1 May 2025 17:39:22 -0700 Subject: [PATCH 123/208] Cleanup copy-paste comments in MAX32 busio files Signed-off-by: Brandon Hurst --- ports/analog/common-hal/busio/I2C.c | 27 +-------------------------- ports/analog/common-hal/busio/I2C.h | 1 - ports/analog/common-hal/busio/SPI.c | 22 ++-------------------- ports/analog/common-hal/busio/SPI.h | 1 - ports/analog/common-hal/busio/UART.c | 3 ++- ports/analog/common-hal/busio/UART.h | 5 ----- 6 files changed, 5 insertions(+), 54 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index f8a5a8bd20971..9fe903428f5b9 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -40,8 +40,7 @@ typedef enum { I2C_NEVER_RESET, } i2c_status_t; -// Set each bit to indicate an active UART -// will be checked by ISR Handler for which ones to call +// Set each bit to indicate an active I2c static uint8_t i2c_active = 0; static i2c_status_t i2c_status[NUM_I2C]; static volatile int i2c_err; @@ -49,23 +48,6 @@ static volatile int i2c_err; // I2C struct for configuring GPIO pins extern const mxc_gpio_cfg_t i2c_maps[NUM_I2C]; -// I2C Interrupt Handler -void i2c_isr(void) { - for (int i = 0; i < NUM_I2C; i++) { - if (i2c_active & (1 << i)) { - // NOTE: I2C_GET_TMR actually returns the I2C registers - MXC_I2C_AsyncHandler(MXC_I2C_GET_I2C(i)); - } - } -} - -// Callback gets called when AsyncRequest is COMPLETE -// (e.g. txLen == txCnt) -// static volatile void i2cCallback(mxc_i2c_req_t *req, int error) { -// i2c_status[MXC_I2C_GET_IDX(req->i2c)] = I2C_FREE; -// i2c_err = error; -// } - // Construct I2C protocol, this function init i2c peripheral void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, @@ -80,7 +62,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // Assign I2C ID based on pins temp = pinsToI2c(sda, scl); if (temp == -1) { - // Error will be indicated by pinsToUart(tx, rx) function return; } else { self->i2c_id = temp; @@ -124,12 +105,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, self->timeout = timeout; } - /* Setup I2C interrupt */ - NVIC_ClearPendingIRQ(MXC_I2C_GET_IRQ(self->i2c_id)); - NVIC_DisableIRQ(MXC_I2C_GET_IRQ(self->i2c_id)); - NVIC_SetPriority(MXC_I2C_GET_IRQ(self->i2c_id), I2C_PRIORITY); - NVIC_SetVector(MXC_I2C_GET_IRQ(self->i2c_id), (uint32_t)i2c_isr); - return; } diff --git a/ports/analog/common-hal/busio/I2C.h b/ports/analog/common-hal/busio/I2C.h index 2c7ffec20785e..55c230ee2f97f 100644 --- a/ports/analog/common-hal/busio/I2C.h +++ b/ports/analog/common-hal/busio/I2C.h @@ -7,7 +7,6 @@ #pragma once #include "common-hal/microcontroller/Pin.h" -// FIXME: Silabs includes "peripherals/periph.h. Figure out what's in this file. " #include "py/obj.h" // HAL-specific diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index d158f09673189..999eb8490b0eb 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -46,22 +46,11 @@ typedef enum { } spi_status_t; // Set each bit to indicate an active SPI -// will be checked by ISR Handler for which ones to call static uint8_t spi_active = 0; static spi_status_t spi_status[NUM_SPI]; static volatile int spi_err; -// SPI Interrupt Handler -void spi_isr(void) { - for (int i = 0; i < NUM_SPI; i++) { - if (spi_active & (1 << i)) { - MXC_SPI_AsyncHandler(MXC_SPI_GET_SPI(i)); - } - } -} - // Construct SPI protocol, this function init SPI peripheral -// todo: figure out Chip select behavior void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, @@ -69,13 +58,12 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, bool half_duplex) { int temp, err = 0; - // Check for NULL Pointers && valid I2C settings + // Check for NULL Pointer assert(self); - // Assign I2C ID based on pins + // Assign SPI ID based on pins temp = pinsToSpi(mosi, miso, sck); if (temp == -1) { - // Error will be indicated by pinsToUart(tx, rx) function return; } else { self->spi_id = temp; @@ -120,12 +108,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Indicate to this module that the SPI is active spi_active |= (1 << self->spi_id); - /* Setup I2C interrupt */ - NVIC_ClearPendingIRQ(MXC_SPI_GET_IRQ(self->spi_id)); - NVIC_DisableIRQ(MXC_SPI_GET_IRQ(self->spi_id)); - NVIC_SetPriority(MXC_SPI_GET_IRQ(self->spi_id), SPI_PRIORITY); - NVIC_SetVector(MXC_SPI_GET_IRQ(self->spi_id), (uint32_t)spi_isr); - return; } diff --git a/ports/analog/common-hal/busio/SPI.h b/ports/analog/common-hal/busio/SPI.h index e70d4234d9407..d10601876fb5e 100644 --- a/ports/analog/common-hal/busio/SPI.h +++ b/ports/analog/common-hal/busio/SPI.h @@ -8,7 +8,6 @@ #define MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H #include "common-hal/microcontroller/Pin.h" -// FIXME: Silabs includes "peripherals/periph.h. Figure out what's in this file. " #include "py/obj.h" // HAL-specific diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 408ae8452352e..3b159c7b29026 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -167,7 +167,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, const mcu_pin_obj_t *rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, - mp_float_t timeout, bool sigint_enabled) { + mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, + bool sigint_enabled) { int err, temp; // Check for NULL Pointers && valid UART settings diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h index c2c2d837ca8a5..a727116f7b882 100644 --- a/ports/analog/common-hal/busio/UART.h +++ b/ports/analog/common-hal/busio/UART.h @@ -9,11 +9,6 @@ #include "common-hal/microcontroller/Pin.h" #include "py/obj.h" -#include "py/ringbuf.h" - -// #include "uart.h" -// #include "uart_regs.h" -// #include "mxc_sys.h" #include "max32_port.h" From ba301159140b562debb10504af8eaba087a8e60a Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Mon, 5 May 2025 10:31:25 -0700 Subject: [PATCH 124/208] Correct ringbuffer code for ports/analog BUSIO - Add correct ringbuffer handling code to ports/analog/common-hal/UART.c Signed-off-by: Brandon Hurst --- ports/analog/common-hal/busio/UART.c | 103 +++++++++++++++------------ ports/analog/common-hal/busio/UART.h | 8 +-- 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 3b159c7b29026..f781da8705545 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -24,20 +24,27 @@ * THE SOFTWARE. */ +/** TODO: + * - Fix readline issue + * +*/ + #if CIRCUITPY_BUSIO_UART +#include "mpconfigport.h" +#include "supervisor/shared/tick.h" + #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -#include "supervisor/shared/tick.h" #include "shared-bindings/busio/UART.h" - #include "shared-bindings/microcontroller/Pin.h" - -#include "mpconfigport.h" #include "shared/readline/readline.h" #include "shared/runtime/interrupt_char.h" + #include "py/gc.h" +#include "py/ringbuf.h" #include "py/mperrno.h" +#include "py/mpprint.h" #include "py/runtime.h" #include "max32_port.h" @@ -47,29 +54,6 @@ // UART IRQ Priority #define UART_PRIORITY 1 -/** - * -// Define a struct for what BUSIO.UART should contain -typedef struct { - mp_obj_base_t base; - int uart_id; - mxc_uart_regs_t* uart_regs; - - const mcu_pin_obj_t *rx_pin; - const mcu_pin_obj_t *tx_pin; - const mcu_pin_obj_t *rts_pin; - const mcu_pin_obj_t *cts_pin; - - uint8_t bits; - uint32_t baudrate; - bool parity; - uint8_t stop_bits; - - uint32_t timeout_ms; - bool error; -} busio_uart_obj_t; - */ - typedef enum { UART_9600 = 9600, UART_14400 = 14400, @@ -82,7 +66,6 @@ typedef enum { UART_921600 = 921600, } uart_valid_baudrates; - typedef enum { UART_FREE = 0, UART_BUSY, @@ -97,6 +80,7 @@ static uint8_t uarts_active = 0; static uart_status_t uart_status[NUM_UARTS]; static volatile int uart_err; static uint8_t uart_never_reset_mask = 0; +static busio_uart_obj_t *context; static int isValidBaudrate(uint32_t baudrate) { switch (baudrate) { @@ -159,6 +143,10 @@ void uart_isr(void) { static volatile void uartCallback(mxc_uart_req_t *req, int error) { uart_status[MXC_UART_GET_IDX(req->uart)] = UART_FREE; uart_err = error; + + MXC_SYS_Crit_Enter(); + ringbuf_put_n(context->ringbuf, req->rxData, req->rxLen); + MXC_SYS_Crit_Exit(); } // Construct an underlying UART object. @@ -183,9 +171,15 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->uart_id = temp; self->uart_regs = MXC_UART_GET_UART(temp); } - assert((self->uart_id >= 0) && (self->uart_id < NUM_UARTS)); + // Check for size of ringbuffer, desire powers of 2 + // At least use 1 byte if no size is given + assert((receiver_buffer_size & (receiver_buffer_size - 1)) == 0); + if (receiver_buffer_size == 0) { + receiver_buffer_size += 1; + } + // Indicate RS485 not implemented if ((rs485_dir != NULL) || (rs485_invert)) { mp_raise_NotImplementedError(MP_ERROR_TEXT("RS485")); @@ -246,12 +240,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->timeout = timeout; } - /* Setup UART interrupt */ + // Initialize ringbuffer + if (receiver_buffer == NULL) { + self->ringbuf = gc_alloc(receiver_buffer_size, false); + if (!ringbuf_alloc(self->ringbuf, receiver_buffer_size)) { + m_malloc_fail(receiver_buffer_size); + mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); + } + } else { + if (!(ringbuf_init(self->ringbuf, receiver_buffer, receiver_buffer_size))) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); + } + ; + } + + context = self; + + // Setup UART interrupt + NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)uart_isr); + NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + return; } @@ -260,7 +273,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { if (!common_hal_busio_uart_deinited(self)) { // First disable the ISR to avoid pre-emption - NVIC_DisableIRQ(UART0_IRQn); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); // Shutdown the UART Controller MXC_UART_Shutdown(self->uart_regs); @@ -280,6 +293,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { self->cts_pin = NULL; self->rts_pin = NULL; + ringbuf_deinit(self->ringbuf); + // Indicate to this module that the UART is not active uarts_active &= ~(1 << self->uart_id); } @@ -306,8 +321,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uart_status[self->uart_id] = UART_BUSY; bytes_remaining = len; - NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mxc_uart_req_t uart_rd_req; uart_rd_req.rxCnt = 0; uart_rd_req.txCnt = 0; @@ -341,13 +354,16 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, } // Check for errors from the callback else if (uart_err != E_NO_ERROR) { + mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); MXC_UART_AbortAsync(self->uart_regs); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); } - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - return len; + // Copy the data from the ringbuf (or return error) + MXC_SYS_Crit_Enter(); + err = ringbuf_get_n(context->ringbuf, data, len); + MXC_SYS_Crit_Exit(); + + return err; } // Write characters. len is in characters NOT bytes! @@ -391,11 +407,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { // Call the handler and abort if errors - uart_err = MXC_UART_AsyncHandler(MXC_UART_GET_UART(0)); + uart_err = MXC_UART_AsyncHandler(self->uart_regs); if (uart_err != E_NO_ERROR) { - MXC_UART_AbortAsync(MXC_UART_GET_UART(0)); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(0)); - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); + mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); + MXC_UART_AbortAsync(self->uart_regs); } } @@ -407,9 +422,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, } // Check for errors from the callback else if (uart_err != E_NO_ERROR) { + mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); MXC_UART_AbortAsync(self->uart_regs); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("MAX32 ERR: %d\n"), uart_err); } return len; @@ -444,11 +458,12 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { - return MXC_UART_GetRXFIFOAvailable(self->uart_regs); + return ringbuf_num_filled(self->ringbuf); } void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { MXC_UART_ClearRXFIFO(self->uart_regs); + ringbuf_clear(self->ringbuf); } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h index a727116f7b882..296c738772e68 100644 --- a/ports/analog/common-hal/busio/UART.h +++ b/ports/analog/common-hal/busio/UART.h @@ -9,25 +9,25 @@ #include "common-hal/microcontroller/Pin.h" #include "py/obj.h" +#include "py/ringbuf.h" #include "max32_port.h" // Define a struct for what BUSIO.UART should contain typedef struct { mp_obj_base_t base; + int error; + float timeout; int uart_id; int uart_map; mxc_uart_regs_t *uart_regs; - + ringbuf_t *ringbuf; bool parity; uint8_t bits; uint8_t stop_bits; uint32_t baudrate; - int error; - float timeout; - const mcu_pin_obj_t *rx_pin; const mcu_pin_obj_t *tx_pin; const mcu_pin_obj_t *rts_pin; From b9dd6a043941063c50ad2d2313366ed3f53b21d1 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Mon, 5 May 2025 10:34:22 -0700 Subject: [PATCH 125/208] Update jlink script for ports/analog Signed-off-by: Brandon Hurst --- ports/analog/tools/flash_max32.jlink | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/analog/tools/flash_max32.jlink b/ports/analog/tools/flash_max32.jlink index 4c9cbacb96fee..8e3647cb0afc7 100644 --- a/ports/analog/tools/flash_max32.jlink +++ b/ports/analog/tools/flash_max32.jlink @@ -1,6 +1,7 @@ si 1 erase -loadbin build-APARD/firmware.bin 0x10000000 -r -g +loadbin build-apard32690/firmware.bin 0x10000000 +reset +halt +go exit From 0ffcc782969f0eb4cde6eaba45a1d8676e515325 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 6 May 2025 09:19:43 -0700 Subject: [PATCH 126/208] Refactor ports/analog/common-hal/busio i2c probe function. - Used direct hardware values to rely on common HW implementation - Accounted for TX Lockout conditions in Transmit FIFO causing errors Signed-off-by: Brandon Hurst --- ports/analog/common-hal/busio/I2C.c | 54 +++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 9fe903428f5b9..ca114d337ede0 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -132,25 +132,49 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - int nack = 0; + int32_t flags = 0x0; + bool ret = false; + + MXC_I2C_ClearFlags(self->i2c_regs, 0xFF, 0xFF); + MXC_I2C_EnableInt(self->i2c_regs, 0xFF, 0xFF); + + // Pre-load target address into transmit FIFO + addr = (addr << 1); + self->i2c_regs->fifo = addr; + + // Set start bit & wait for it to clear + self->i2c_regs->mstctrl |= MXC_F_I2C_MSTCTRL_START; + + // wait for ACK/NACK + // if tx_lockout occurs, clear the error and re-load the target address + while (!(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK) && + !(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_NACK_ERR)) { + if (self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_TX_LOCKOUT) { + self->i2c_regs->intfl0 |= MXC_F_I2C_INTFL0_TX_LOCKOUT; + self->i2c_regs->fifo = addr; + } + } + flags = self->i2c_regs->intfl0; + self->i2c_regs->intfl0 = MXC_F_I2C_INTFL0_ADDR_ACK | MXC_F_I2C_INTFL0_ADDR_NACK_ERR - mxc_i2c_req_t addr_req = { - .addr = addr, - .i2c = self->i2c_regs, - .tx_len = 0, - .tx_buf = NULL, - .rx_len = 0, - .rx_buf = NULL, - .callback = NULL - }; + // Set / Wait for stop + self->i2c_regs->mstctrl |= MXC_F_I2C_MSTCTRL_STOP; + while ((self->i2c_regs->mstctrl & MXC_F_I2C_MSTCTRL_STOP)) { + ; + } - // Probe the address - nack = MXC_I2C_MasterTransaction(&addr_req); - if (nack) { - return false; + // Wait for controller not busy, then clear flags + while (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) { + ; + } + + if (flags & MXC_F_I2C_INTFL0_ADDR_ACK) { + ret = true; } else { - return true; + ret = false; } + MXC_I2C_ClearFlags(self->i2c_regs, 0xff, 0xff); + return ret; } // Lock I2C bus From 94eafa5d0ce45ada21c30b6f270c0895f04c1e2d Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 6 May 2025 09:21:14 -0700 Subject: [PATCH 127/208] Expand command in ports/analog/tools/flash_max32.jlink for clarity. Signed-off-by: Brandon Hurst --- ports/analog/tools/flash_max32.jlink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/analog/tools/flash_max32.jlink b/ports/analog/tools/flash_max32.jlink index 8e3647cb0afc7..0453f4cb077fd 100644 --- a/ports/analog/tools/flash_max32.jlink +++ b/ports/analog/tools/flash_max32.jlink @@ -1,4 +1,4 @@ -si 1 +selectinterface swd erase loadbin build-apard32690/firmware.bin 0x10000000 reset From 4cb58b64f75aa9e6df9bbf74ce53d573106c2a9a Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 6 May 2025 14:08:22 -0700 Subject: [PATCH 128/208] Fix i2c scan bug with ports/analog/ BUSIO. - Probe function caused infinite loops / unreliable ACK values - Replaced with probe-function with low-level routines Signed-off-by: Brandon Hurst --- ports/analog/common-hal/busio/I2C.c | 42 +++++++++++------------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index ca114d337ede0..c1b1d9efe1b17 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -34,15 +34,8 @@ #define I2C_PRIORITY 1 -typedef enum { - I2C_FREE = 0, - I2C_BUSY, - I2C_NEVER_RESET, -} i2c_status_t; - // Set each bit to indicate an active I2c static uint8_t i2c_active = 0; -static i2c_status_t i2c_status[NUM_I2C]; static volatile int i2c_err; // I2C struct for configuring GPIO pins @@ -68,7 +61,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, self->i2c_regs = MXC_I2C_GET_I2C(temp); } + // Check for valid I2C controller assert((self->i2c_id >= 0) && (self->i2c_id < NUM_I2C)); + assert(!(i2c_active & (1 << self->i2c_id))); // Init I2C as main / controller node (0x00 is ignored) if ((scl != NULL) && (sda != NULL)) { @@ -132,48 +127,43 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - int32_t flags = 0x0; - bool ret = false; + uint32_t int_fl0, int_fl1; + bool ret = 0; - MXC_I2C_ClearFlags(self->i2c_regs, 0xFF, 0xFF); - MXC_I2C_EnableInt(self->i2c_regs, 0xFF, 0xFF); + // Clear FIFOs & all interrupt flags + MXC_I2C_ClearRXFIFO(self->i2c_regs); + MXC_I2C_ClearTXFIFO(self->i2c_regs); + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); // Pre-load target address into transmit FIFO addr = (addr << 1); self->i2c_regs->fifo = addr; // Set start bit & wait for it to clear - self->i2c_regs->mstctrl |= MXC_F_I2C_MSTCTRL_START; + MXC_I2C_Start(self->i2c_regs); // wait for ACK/NACK - // if tx_lockout occurs, clear the error and re-load the target address while (!(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK) && !(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_NACK_ERR)) { - if (self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_TX_LOCKOUT) { - self->i2c_regs->intfl0 |= MXC_F_I2C_INTFL0_TX_LOCKOUT; - self->i2c_regs->fifo = addr; - } } - flags = self->i2c_regs->intfl0; - self->i2c_regs->intfl0 = MXC_F_I2C_INTFL0_ADDR_ACK | MXC_F_I2C_INTFL0_ADDR_NACK_ERR - // Set / Wait for stop - self->i2c_regs->mstctrl |= MXC_F_I2C_MSTCTRL_STOP; - while ((self->i2c_regs->mstctrl & MXC_F_I2C_MSTCTRL_STOP)) { - ; - } + // Save interrupt flags for ACK/NACK checking + int_fl0 = self->i2c_regs->intfl0; + + // Set / Wait for stop + MXC_I2C_Stop(self->i2c_regs); // Wait for controller not busy, then clear flags while (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) { ; } + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); - if (flags & MXC_F_I2C_INTFL0_ADDR_ACK) { + if (int_fl0 & MXC_F_I2C_INTFL0_ADDR_ACK) { ret = true; } else { ret = false; } - MXC_I2C_ClearFlags(self->i2c_regs, 0xff, 0xff); return ret; } From 814047d60fcd4fad5334cd204f6346fff5504a56 Mon Sep 17 00:00:00 2001 From: Brandon Hurst Date: Tue, 6 May 2025 14:41:26 -0700 Subject: [PATCH 129/208] Add translations for ports/analog/busio Signed-off-by: Brandon Hurst --- locale/circuitpython.pot | 114 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 98fc54741eb39..5b9e9afed76bf 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -28,6 +28,25 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#, c-format +msgid "" +"\n" +"ERR: Error starting transaction: %d\n" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "" +"\n" +"ERR: Requested bus is busy\n" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "" +"\n" +"ERR: Uart transaction timed out.\n" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -628,6 +647,10 @@ msgid "" "disable.\n" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Baudrate invalid. Must be a standard UART baudrate.\n" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" msgstr "" @@ -717,6 +740,10 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "CPOL / CPHA must both be either 0 or 1\n" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -943,6 +970,38 @@ msgstr "" msgid "ECB only operates on 16 bytes at a time" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "ERR: Could not init ringbuffer\n" +msgstr "" + +#: ports/analog/peripherals/max32690/max32_uart.c +#, c-format +msgid "" +"ERR: Unable to find a uart matching pins...\n" +"TX: port %d mask %d\n" +"RX: port %d mask %d\n" +msgstr "" + +#: ports/analog/peripherals/max32690/max32_i2c.c +#, c-format +msgid "" +"ERR: Unable to find an I2C matching pins...\n" +"SCL: port %d mask %d\n" +"SDA: port %d mask %d\n" +msgstr "" + +#: ports/analog/peripherals/max32690/max32_spi.c +#, c-format +msgid "" +"ERR: Unable to find an SPI matching pins... \n" +"MOSI: port %d mask %d\n" +"MISO: port %d mask %d\n" +msgstr "" + +#: ports/analog/common-hal/busio/I2C.c +msgid "ERROR during I2C Transaction\n" +msgstr "" + #: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/canio/CAN.c msgid "ESP-IDF memory allocation failed" @@ -1036,6 +1095,19 @@ msgstr "" msgid "Failed to enable continuous" msgstr "" +#: ports/analog/common-hal/busio/I2C.c +#, c-format +msgid "Failed to init I2C. ERR: %d\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to init SPI.\n" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "Failed to initialize UART.\n" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -1049,6 +1121,23 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" +#: ports/analog/common-hal/busio/I2C.c +#, c-format +msgid "Failed to set I2C frequency. ERR: %d\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Frame Size\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Frequency\n" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1089,6 +1178,10 @@ msgstr "" msgid "Firmware is too big" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Flow Ctrl needs both CTS & RTS" +msgstr "" + #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" @@ -1148,6 +1241,10 @@ msgstr "" msgid "I2C init error" msgstr "" +#: ports/analog/common-hal/busio/I2C.c +msgid "I2C needs SDA & SCL" +msgstr "" + #: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" @@ -1765,6 +1862,10 @@ msgstr "" msgid "Parameter error" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Parity must be ODD, EVEN, or NONE\n" +msgstr "" + #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" msgstr "" @@ -1902,6 +2003,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1994,6 +2096,10 @@ msgstr "" msgid "SPI init error" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" @@ -2125,6 +2231,10 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2168,6 +2278,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "" From b19a86111cd736c5a65a5bb5354bfba9e4e277b7 Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Sat, 5 Jul 2025 12:32:20 -0700 Subject: [PATCH 130/208] Fix error reporting on ports/analog BUSIO for PR 10413 - Use existing error messages from locale/circuitpython.pot for most error messages - Replace ConnectionError (networking specific) calls with others (usually RuntimeError) - Remove '\n' from mp error calls (since they add it already) - Remove some redundant validation code that repeats checks done by shared-bindings/common-hal/busio code. e.g. pin validation Signed-off-by: Brandon-Hurst --- ports/analog/common-hal/busio/I2C.c | 35 +++++---------- ports/analog/common-hal/busio/SPI.c | 5 ++- ports/analog/common-hal/busio/UART.c | 45 ++++++++++--------- ports/analog/peripherals/max32690/max32_i2c.c | 3 +- ports/analog/peripherals/max32690/max32_spi.c | 5 +-- .../analog/peripherals/max32690/max32_uart.c | 3 +- 6 files changed, 39 insertions(+), 57 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index c1b1d9efe1b17..b75d916c9faf0 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -52,6 +52,11 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // Check for NULL Pointers && valid I2C settings assert(self); + /* NOTE: The validate_obj_is_free_pin() calls in shared-bindings/busio/I2C.c + will ensure that scl and sda are both pins and cannot be null + ref: https://github.com/adafruit/circuitpython/pull/10413 + */ + // Assign I2C ID based on pins temp = pinsToI2c(sda, scl); if (temp == -1) { @@ -65,25 +70,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, assert((self->i2c_id >= 0) && (self->i2c_id < NUM_I2C)); assert(!(i2c_active & (1 << self->i2c_id))); - // Init I2C as main / controller node (0x00 is ignored) - if ((scl != NULL) && (sda != NULL)) { - MXC_GPIO_Config(&i2c_maps[self->i2c_id]); - err = MXC_I2C_Init(self->i2c_regs, 1, 0x00); - if (err) { - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to init I2C. ERR: %d\n"), err); - } - err = MXC_I2C_SetFrequency(self->i2c_regs, frequency); - if (err < 0) { - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to set I2C frequency. ERR: %d\n"), err); - } - } else if (scl != NULL) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("I2C needs SDA & SCL")); - } else if (sda != NULL) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("I2C needs SDA & SCL")); - } else { - // Should not get here, as shared-bindings API should not call this way - } - // Attach I2C pins self->sda = sda; self->scl = scl; @@ -94,8 +80,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, i2c_active |= (1 << self->i2c_id); // Set the timeout to a default value - if (((timeout < 0.0) || (timeout > 100.0))) { - self->timeout = 1.0; + if (timeout > 100) { + self->timeout = 1; } else { self->timeout = timeout; } @@ -212,7 +198,6 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, } // Read into buffer from the device selected by address -// todo test uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -229,14 +214,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, }; ret = MXC_I2C_MasterTransaction(&rd_req); if (ret) { - mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + // Return I/O error + return MP_EIO; } return 0; } // Write the bytes from out_data to the device selected by address, -// todo test uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { @@ -253,7 +238,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, }; ret = MXC_I2C_MasterTransaction(&wr_rd_req); if (ret) { - mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + return MP_EIO; } return 0; diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 999eb8490b0eb..95ad1851a59ed 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -91,7 +91,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, 1, 0x01, 1000000, spi_pins); MXC_GPIO_SetVSSEL(MXC_GPIO_GET_GPIO(sck->port), MXC_GPIO_VSSEL_VDDIOH, (sck->mask | miso->mask | mosi->mask | MXC_GPIO_PIN_0)); if (err) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to init SPI.\n")); + // NOTE: Reuse existing messages from locales/circuitpython.pot to save space + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_SPI); } } else { mp_raise_NotImplementedError(MP_ERROR_TEXT("SPI needs MOSI, MISO, and SCK")); @@ -170,7 +171,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, clk_mode = MXC_SPI_CLKMODE_3; break; default: - mp_raise_ValueError(MP_ERROR_TEXT("CPOL / CPHA must both be either 0 or 1\n")); + // should not be reachable; validated in shared-bindings/busio/SPI.c return false; } diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index f781da8705545..80feebfb8f4b6 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -82,37 +82,37 @@ static volatile int uart_err; static uint8_t uart_never_reset_mask = 0; static busio_uart_obj_t *context; -static int isValidBaudrate(uint32_t baudrate) { +static bool isValidBaudrate(uint32_t baudrate) { switch (baudrate) { case UART_9600: - return 1; + return true; break; case UART_14400: - return 1; + return true; break; case UART_19200: - return 1; + return true; break; case UART_38400: - return 1; + return true; break; case UART_57600: - return 1; + return true; break; case UART_115200: - return 1; + return true; break; case UART_230400: - return 1; + return true; break; case UART_460800: - return 1; + return true; break; case UART_921600: - return 1; + return true; break; default: - return 0; + return false; break; } } @@ -126,7 +126,8 @@ static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) { case BUSIO_UART_PARITY_ODD: return MXC_UART_PARITY_ODD_0; default: - mp_raise_ValueError(MP_ERROR_TEXT("Parity must be ODD, EVEN, or NONE\n")); + // not reachable due to validation in shared-bindings/busio/SPI.c + return MXC_UART_PARITY_DISABLE; } } @@ -188,7 +189,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if ((rx != NULL) && (tx != NULL)) { err = MXC_UART_Init(self->uart_regs, baudrate, MXC_UART_IBRO_CLK); if (err != E_NO_ERROR) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to initialize UART.\n")); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_UART); } // attach & configure pins @@ -211,7 +212,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, common_hal_mcu_pin_claim(self->cts_pin); common_hal_mcu_pin_claim(self->rts_pin); } else if (cts || rts) { - mp_raise_ValueError(MP_ERROR_TEXT("Flow Ctrl needs both CTS & RTS")); + mp_raise_ValueError(MP_ERROR_TEXT("Both RX and TX required for flow control")); } // Set stop bits & data size @@ -338,7 +339,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, *errcode = err; MXC_UART_AbortAsync(self->uart_regs); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("\nERR: Error starting transaction: %d\n"), err); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("UART read error")); } // Wait for transaction completion or timeout @@ -350,11 +351,11 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, if (uart_status[self->uart_id] != UART_FREE) { MXC_UART_AbortAsync(self->uart_regs); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); + mp_raise_RuntimeError(MP_ERROR_TEXT("UART transaction timeout")); } // Check for errors from the callback else if (uart_err != E_NO_ERROR) { - mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); + // todo: indicate error? MXC_UART_AbortAsync(self->uart_regs); } @@ -399,7 +400,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, *errcode = err; MXC_UART_AbortAsync(self->uart_regs); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Requested bus is busy\n")); + mp_raise_ValueError(MP_ERROR_TEXT("All UART peripherals are in use")); } // Wait for transaction completion or timeout @@ -409,7 +410,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, // Call the handler and abort if errors uart_err = MXC_UART_AsyncHandler(self->uart_regs); if (uart_err != E_NO_ERROR) { - mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); + // todo: indicate error? MXC_UART_AbortAsync(self->uart_regs); } } @@ -418,11 +419,11 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, if (uart_status[self->uart_id] != UART_FREE) { MXC_UART_AbortAsync(self->uart_regs); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_ConnectionError(MP_ERROR_TEXT("\nERR: Uart transaction timed out.\n")); + mp_raise_RuntimeError(MP_ERROR_TEXT("Uart transaction timed out.")); } // Check for errors from the callback else if (uart_err != E_NO_ERROR) { - mp_printf(&mp_sys_stdout_print, "MAX32 ERR: %d\n", uart_err); + // todo: indicate error? MXC_UART_AbortAsync(self->uart_regs); } @@ -438,7 +439,7 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat if (isValidBaudrate(baudrate)) { self->baudrate = baudrate; } else { - mp_raise_ValueError(MP_ERROR_TEXT("Baudrate invalid. Must be a standard UART baudrate.\n")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_baudrate); } } diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c index daf665bbee741..4b9ec8b4db264 100644 --- a/ports/analog/peripherals/max32690/max32_i2c.c +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -70,7 +70,6 @@ int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { } #endif - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an I2C matching pins...\nSCL: port %d mask %d\nSDA: port %d mask %d\n"), - sda->port, sda->mask, scl->port, scl->mask); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); return -1; } diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c index f2594787598b2..c78fd64dbd705 100644 --- a/ports/analog/peripherals/max32690/max32_spi.c +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -39,9 +39,6 @@ int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, return i; } } - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find an SPI matching pins... \ - \nMOSI: port %d mask %d\nMISO: port %d mask %d\n"), - mosi->port, mosi->mask, miso->port, miso->mask, - sck->port, sck->mask); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); return -1; } diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c index 5f7a8568fb426..7d37708797415 100644 --- a/ports/analog/peripherals/max32690/max32_uart.c +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -31,7 +31,6 @@ int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { return i; } } - mp_raise_RuntimeError_varg(MP_ERROR_TEXT("ERR: Unable to find a uart matching pins...\nTX: port %d mask %d\nRX: port %d mask %d\n"), - tx->port, tx->mask, rx->port, rx->mask); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); return -1; } From 85410e22084c7b660301ba0812974d3bc3dc37ff Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Sat, 5 Jul 2025 12:38:42 -0700 Subject: [PATCH 131/208] Minor changes in ports/analog/ busio UART. - Use m_malloc_without_collect storage API change from CircuitPython - Remove err number for asynchronous read error; just report it Signed-off-by: Brandon-Hurst --- ports/analog/common-hal/busio/UART.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 80feebfb8f4b6..71da89652af39 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -197,12 +197,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->rx_pin = rx; common_hal_mcu_pin_claim(self->tx_pin); common_hal_mcu_pin_claim(self->rx_pin); - } else if (tx != NULL) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); - } else if (rx != NULL) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); } else { - // Should not get here, as shared-bindings API should not call this way + mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); } if ((cts) && (rts)) { @@ -243,7 +239,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Initialize ringbuffer if (receiver_buffer == NULL) { - self->ringbuf = gc_alloc(receiver_buffer_size, false); + self->ringbuf = m_malloc_without_collect(receiver_buffer_size, false); if (!ringbuf_alloc(self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); From f395fadeb59d4aa45632ac936fed6dd1507c734a Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Sat, 5 Jul 2025 12:44:05 -0700 Subject: [PATCH 132/208] Fix UART malloc for ports/analog BUSIO - Remove excess argument from UART ringbuf malloc call - Remove unused err and intfl0 in I2C driver to remove warnings Signed-off-by: Brandon-Hurst --- ports/analog/common-hal/busio/I2C.c | 4 ++-- ports/analog/common-hal/busio/UART.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index b75d916c9faf0..19c71034eea4c 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -47,7 +47,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { - int temp, err = 0; + int temp = 0; // Check for NULL Pointers && valid I2C settings assert(self); @@ -113,7 +113,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { // Probe device in I2C bus bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - uint32_t int_fl0, int_fl1; + uint32_t int_fl0; bool ret = 0; // Clear FIFOs & all interrupt flags diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 71da89652af39..633ecb1684005 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -239,7 +239,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Initialize ringbuffer if (receiver_buffer == NULL) { - self->ringbuf = m_malloc_without_collect(receiver_buffer_size, false); + self->ringbuf = m_malloc_without_collect(receiver_buffer_size); if (!ringbuf_alloc(self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); From e5437cd688120e1c7bdfc90a42afd16b9addf84b Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Sat, 5 Jul 2025 13:03:03 -0700 Subject: [PATCH 133/208] Commit locale changes from ports/analog BUSIO updates Signed-off-by: Brandon-Hurst --- locale/circuitpython.pot | 106 +++++++++------------------------------ 1 file changed, 24 insertions(+), 82 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 5b9e9afed76bf..a0477d71abc19 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -28,25 +28,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: ports/analog/common-hal/busio/UART.c -#, c-format -msgid "" -"\n" -"ERR: Error starting transaction: %d\n" -msgstr "" - -#: ports/analog/common-hal/busio/UART.c -msgid "" -"\n" -"ERR: Requested bus is busy\n" -msgstr "" - -#: ports/analog/common-hal/busio/UART.c -msgid "" -"\n" -"ERR: Uart transaction timed out.\n" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -149,6 +130,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" @@ -177,6 +159,10 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "" + #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -517,7 +503,8 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "" @@ -647,10 +634,6 @@ msgid "" "disable.\n" msgstr "" -#: ports/analog/common-hal/busio/UART.c -msgid "Baudrate invalid. Must be a standard UART baudrate.\n" -msgstr "" - #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" msgstr "" @@ -672,6 +655,7 @@ msgstr "" msgid "Boot device must be first (interface #0)." msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "" @@ -740,10 +724,6 @@ msgstr "" msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: ports/analog/common-hal/busio/SPI.c -msgid "CPOL / CPHA must both be either 0 or 1\n" -msgstr "" - #: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" msgstr "" @@ -974,30 +954,6 @@ msgstr "" msgid "ERR: Could not init ringbuffer\n" msgstr "" -#: ports/analog/peripherals/max32690/max32_uart.c -#, c-format -msgid "" -"ERR: Unable to find a uart matching pins...\n" -"TX: port %d mask %d\n" -"RX: port %d mask %d\n" -msgstr "" - -#: ports/analog/peripherals/max32690/max32_i2c.c -#, c-format -msgid "" -"ERR: Unable to find an I2C matching pins...\n" -"SCL: port %d mask %d\n" -"SDA: port %d mask %d\n" -msgstr "" - -#: ports/analog/peripherals/max32690/max32_spi.c -#, c-format -msgid "" -"ERR: Unable to find an SPI matching pins... \n" -"MOSI: port %d mask %d\n" -"MISO: port %d mask %d\n" -msgstr "" - #: ports/analog/common-hal/busio/I2C.c msgid "ERROR during I2C Transaction\n" msgstr "" @@ -1095,19 +1051,6 @@ msgstr "" msgid "Failed to enable continuous" msgstr "" -#: ports/analog/common-hal/busio/I2C.c -#, c-format -msgid "Failed to init I2C. ERR: %d\n" -msgstr "" - -#: ports/analog/common-hal/busio/SPI.c -msgid "Failed to init SPI.\n" -msgstr "" - -#: ports/analog/common-hal/busio/UART.c -msgid "Failed to initialize UART.\n" -msgstr "" - #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" @@ -1121,11 +1064,6 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: ports/analog/common-hal/busio/I2C.c -#, c-format -msgid "Failed to set I2C frequency. ERR: %d\n" -msgstr "" - #: ports/analog/common-hal/busio/SPI.c msgid "Failed to set SPI Clock Mode\n" msgstr "" @@ -1178,10 +1116,6 @@ msgstr "" msgid "Firmware is too big" msgstr "" -#: ports/analog/common-hal/busio/UART.c -msgid "Flow Ctrl needs both CTS & RTS" -msgstr "" - #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" @@ -1241,10 +1175,6 @@ msgstr "" msgid "I2C init error" msgstr "" -#: ports/analog/common-hal/busio/I2C.c -msgid "I2C needs SDA & SCL" -msgstr "" - #: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" @@ -1348,6 +1278,10 @@ msgstr "" msgid "Interrupted by output function" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1862,10 +1796,6 @@ msgstr "" msgid "Parameter error" msgstr "" -#: ports/analog/common-hal/busio/UART.c -msgid "Parity must be ODD, EVEN, or NONE\n" -msgstr "" - #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" msgstr "" @@ -2290,6 +2220,14 @@ msgstr "" msgid "UART re-init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "" @@ -2326,6 +2264,10 @@ msgstr "" msgid "UUID value is not str, int or byte buffer" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Uart transaction timed out." +msgstr "" + #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to access unaligned IO register" msgstr "" From ed92610e506d4f63bcf28152fa10c0d8eedbc010 Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Thu, 10 Jul 2025 21:57:47 -0700 Subject: [PATCH 134/208] Reuse more existing error messages in ports/analog BUSIO - Reuse more messages in locales/circuitpython.pot in BUSIO - Remove UART write timeout - Refine some error handling for SPI initialization Signed-off-by: Brandon-Hurst --- locale/circuitpython.pot | 26 ++++----------------- ports/analog/common-hal/busio/I2C.c | 2 +- ports/analog/common-hal/busio/SPI.c | 15 +++++------- ports/analog/common-hal/busio/UART.c | 34 +++++++--------------------- 4 files changed, 19 insertions(+), 58 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a0477d71abc19..1e167c30353dd 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -242,6 +242,7 @@ msgstr "" msgid "%q out of bounds" msgstr "" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -950,14 +951,6 @@ msgstr "" msgid "ECB only operates on 16 bytes at a time" msgstr "" -#: ports/analog/common-hal/busio/UART.c -msgid "ERR: Could not init ringbuffer\n" -msgstr "" - -#: ports/analog/common-hal/busio/I2C.c -msgid "ERROR during I2C Transaction\n" -msgstr "" - #: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/canio/CAN.c msgid "ESP-IDF memory allocation failed" @@ -1006,7 +999,7 @@ msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "" @@ -1065,15 +1058,7 @@ msgid "Failed to release mutex, err 0x%04x" msgstr "" #: ports/analog/common-hal/busio/SPI.c -msgid "Failed to set SPI Clock Mode\n" -msgstr "" - -#: ports/analog/common-hal/busio/SPI.c -msgid "Failed to set SPI Frame Size\n" -msgstr "" - -#: ports/analog/common-hal/busio/SPI.c -msgid "Failed to set SPI Frequency\n" +msgid "Failed to set SPI Clock Mode" msgstr "" #: ports/zephyr-cp/common-hal/wifi/Radio.c @@ -1374,6 +1359,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -2264,10 +2250,6 @@ msgstr "" msgid "UUID value is not str, int or byte buffer" msgstr "" -#: ports/analog/common-hal/busio/UART.c -msgid "Uart transaction timed out." -msgstr "" - #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to access unaligned IO register" msgstr "" diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 19c71034eea4c..2c8f2e328eb1f 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -191,7 +191,7 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, }; ret = MXC_I2C_MasterTransaction(&wr_req); if (ret) { - mp_raise_RuntimeError(MP_ERROR_TEXT("ERROR during I2C Transaction\n")); + return MP_EIO; } return 0; diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 95ad1851a59ed..516ae26a8cf69 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -177,17 +177,19 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, ret = MXC_SPI_SetFrequency(self->spi_regs, baudrate); if (ret) { - mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Frequency\n")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q out of range"), MP_QSTR_baudrate); return false; } ret = MXC_SPI_SetDataSize(self->spi_regs, bits); - if (ret) { - mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Frame Size\n")); + if (ret == E_BAD_PARAM) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q out of range"), MP_QSTR_bits); return false; + } else if (ret == E_BAD_STATE) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid state")); } ret = MXC_SPI_SetMode(self->spi_regs, clk_mode); if (ret) { - mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Clock Mode\n")); + mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Clock Mode")); return false; } return true; @@ -246,11 +248,6 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t write_value) { int ret = 0; - // uint8_t tx_buffer[len] = {0x0}; - - // for (int i = 0; i < len; i++) { - // tx_buffer[i] = write_value; - // } mxc_spi_req_t rd_req = { .spi = self->spi_regs, diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c index 633ecb1684005..be7851f52a21c 100644 --- a/ports/analog/common-hal/busio/UART.c +++ b/ports/analog/common-hal/busio/UART.c @@ -24,11 +24,6 @@ * THE SOFTWARE. */ -/** TODO: - * - Fix readline issue - * -*/ - #if CIRCUITPY_BUSIO_UART #include "mpconfigport.h" @@ -242,19 +237,19 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->ringbuf = m_malloc_without_collect(receiver_buffer_size); if (!ringbuf_alloc(self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); - mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to allocate %q buffer"), + MP_QSTR_UART); } } else { if (!(ringbuf_init(self->ringbuf, receiver_buffer, receiver_buffer_size))) { - mp_raise_RuntimeError(MP_ERROR_TEXT("ERR: Could not init ringbuffer\n")); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to allocate %q buffer"), + MP_QSTR_UART); } - ; } context = self; // Setup UART interrupt - NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); @@ -351,7 +346,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, } // Check for errors from the callback else if (uart_err != E_NO_ERROR) { - // todo: indicate error? + mp_raise_RuntimeError(MP_ERROR_TEXT("UART read error")); MXC_UART_AbortAsync(self->uart_regs); } @@ -368,7 +363,6 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { int err; - uint32_t start_time = 0; static size_t bytes_remaining; // Setup globals & status tracking @@ -390,7 +384,6 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, uart_wr_req.callback = (void *)uartCallback; // Start the transaction - start_time = supervisor_ticks_ms64(); err = MXC_UART_TransactionAsync(&uart_wr_req); if (err != E_NO_ERROR) { *errcode = err; @@ -399,27 +392,16 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, mp_raise_ValueError(MP_ERROR_TEXT("All UART peripherals are in use")); } - // Wait for transaction completion or timeout - while ((uart_status[self->uart_id] != UART_FREE) && - (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { - + // Wait for transaction completion + while (uart_status[self->uart_id] != UART_FREE) { // Call the handler and abort if errors uart_err = MXC_UART_AsyncHandler(self->uart_regs); if (uart_err != E_NO_ERROR) { - // todo: indicate error? MXC_UART_AbortAsync(self->uart_regs); } } - - // If the timeout gets hit, abort and error out - if (uart_status[self->uart_id] != UART_FREE) { - MXC_UART_AbortAsync(self->uart_regs); - NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); - mp_raise_RuntimeError(MP_ERROR_TEXT("Uart transaction timed out.")); - } // Check for errors from the callback - else if (uart_err != E_NO_ERROR) { - // todo: indicate error? + if (uart_err != E_NO_ERROR) { MXC_UART_AbortAsync(self->uart_regs); } From 183a517ba1e4ab818904254e2c4bd932caf4f52a Mon Sep 17 00:00:00 2001 From: Brandon-Hurst Date: Mon, 22 Sep 2025 20:30:39 -0700 Subject: [PATCH 135/208] Fix I2C bug in ports/analog/busio - Add clear flags + Shutdown/Init to I2C constructor - Explicitly set frequency - Add failsafe in probe function if MST mode disabled (can happen in some error conditions) - Fix Makefile bug with missing "\" for source files Signed-off-by: Brandon-Hurst --- ports/analog/Makefile | 2 +- ports/analog/common-hal/busio/I2C.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ports/analog/Makefile b/ports/analog/Makefile index 4a758eff9c46d..0ae276985f7f4 100644 --- a/ports/analog/Makefile +++ b/ports/analog/Makefile @@ -125,7 +125,7 @@ SRC_MAX32 += \ $(PERIPH_SRC)/UART/uart_$(DIE_TYPE).c \ $(PERIPH_SRC)/UART/uart_revb.c \ $(PERIPH_SRC)/TRNG/trng_revb.c \ - $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c + $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c \ $(PERIPH_SRC)/I2C/i2c_$(DIE_TYPE).c \ $(PERIPH_SRC)/I2C/i2c_reva.c \ $(PERIPH_SRC)/SPI/spi_$(DIE_TYPE).c \ diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index 2c8f2e328eb1f..b3aeac76ce2d3 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -76,6 +76,16 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, common_hal_mcu_pin_claim(self->sda); common_hal_mcu_pin_claim(self->scl); + // Clear all flags + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); + + // Init as master, no slave address + MXC_I2C_Shutdown(self->i2c_regs); + MXC_I2C_Init(self->i2c_regs, 1, 0); + + // Set frequency arg (CircuitPython shared-bindings validate) + MXC_I2C_SetFrequency(self->i2c_regs, frequency); + // Indicate to this module that the I2C is active i2c_active |= (1 << self->i2c_id); @@ -116,6 +126,11 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { uint32_t int_fl0; bool ret = 0; + // If not in Master mode, error out (can happen in some error conditions) + if (!(self->i2c_regs->ctrl & MXC_F_I2C_CTRL_MST_MODE)) { + return false; + } + // Clear FIFOs & all interrupt flags MXC_I2C_ClearRXFIFO(self->i2c_regs); MXC_I2C_ClearTXFIFO(self->i2c_regs); @@ -175,7 +190,6 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } // Write data to the device selected by address -// todo test uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { @@ -221,7 +235,7 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, return 0; } -// Write the bytes from out_data to the device selected by address, +// Write the bytes from out_data to the device selected by address uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { From 29914f88b80954cfb59a6bbb6152af78e8e1a098 Mon Sep 17 00:00:00 2001 From: gychang Date: Tue, 23 Sep 2025 15:03:40 -0700 Subject: [PATCH 136/208] Remove neopixel_write workaround Turns out it was a workaround for a bad LED on one particular board. --- .../boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk | 4 ---- ports/espressif/common-hal/neopixel_write/__init__.c | 10 ---------- 2 files changed, 14 deletions(-) diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk index a233eb526fdbd..4b23a76ba6a15 100644 --- a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk @@ -8,7 +8,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 - -ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD = 1 - -CFLAGS += -DESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD=$(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) diff --git a/ports/espressif/common-hal/neopixel_write/__init__.c b/ports/espressif/common-hal/neopixel_write/__init__.c index 945b309372ac7..d0d46a3179787 100644 --- a/ports/espressif/common-hal/neopixel_write/__init__.c +++ b/ports/espressif/common-hal/neopixel_write/__init__.c @@ -126,11 +126,6 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, // Update the next start to +2 ticks. It ensures that we've gone 300+ us. next_start_raw_ticks = port_get_raw_ticks(NULL) + 2; - #if defined(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) - // Hold the pin, deleting the channel seems to glitch pixels into turning off. - gpio_hold_en(digitalinout->pin->number); - #endif - // Free channel again rmt_del_encoder(encoder); rmt_disable(channel); @@ -138,9 +133,4 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, CHECK_ESP_RESULT(result); // Swap pin back to GPIO mode gpio_set_direction(digitalinout->pin->number, GPIO_MODE_OUTPUT); - - #if defined(ESPRESSIF_ESP32C3_LYRA_STATUS_LED_HOLD) - // Release hold - gpio_hold_dis(digitalinout->pin->number); - #endif } From bb27b4010c27e47912741be88481e77d6d7c580b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 24 Sep 2025 12:35:08 -0400 Subject: [PATCH 137/208] Use more explicit names for i2c_id and spi_id --- ports/analog/common-hal/busio/I2C.c | 11 ++++------- ports/analog/common-hal/busio/SPI.c | 10 +++++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c index b3aeac76ce2d3..336c04fe039f9 100644 --- a/ports/analog/common-hal/busio/I2C.c +++ b/ports/analog/common-hal/busio/I2C.c @@ -46,9 +46,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { - - int temp = 0; - // Check for NULL Pointers && valid I2C settings assert(self); @@ -58,12 +55,12 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, */ // Assign I2C ID based on pins - temp = pinsToI2c(sda, scl); - if (temp == -1) { + int i2c_id = pinsToI2c(sda, scl); + if (i2c_id == -1) { return; } else { - self->i2c_id = temp; - self->i2c_regs = MXC_I2C_GET_I2C(temp); + self->i2c_id = i2c_id; + self->i2c_regs = MXC_I2C_GET_I2C(i2c_id); } // Check for valid I2C controller diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index 516ae26a8cf69..b4a519c37a72d 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -56,18 +56,18 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { - int temp, err = 0; + int err = 0; // Check for NULL Pointer assert(self); // Assign SPI ID based on pins - temp = pinsToSpi(mosi, miso, sck); - if (temp == -1) { + int spi_id = pinsToSpi(mosi, miso, sck); + if (spi_id == -1) { return; } else { - self->spi_id = temp; - self->spi_regs = MXC_SPI_GET_SPI(temp); + self->spi_id = spi_id; + self->spi_regs = MXC_SPI_GET_SPI(spi_id); } // Other pins default to true From caf65d3ac9ef9db9619eb4c1ed781339686df778 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 24 Sep 2025 20:11:32 +0200 Subject: [PATCH 138/208] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/cs.po | 42 ++++++++++++++++++++++++++++++++++++++++-- locale/el.po | 45 ++++++++++++++++++++++++++++++++++++++++----- locale/hi.po | 42 ++++++++++++++++++++++++++++++++++++++++-- locale/ko.po | 47 +++++++++++++++++++++++++++++++++++++++++------ locale/ru.po | 45 ++++++++++++++++++++++++++++++++++++++++----- locale/tr.po | 42 ++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 241 insertions(+), 22 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index eab928c2aaaf6..fa1cb2d40b738 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -141,6 +141,7 @@ msgstr "Index %q je mimo rozsah" msgid "%q indices must be integers, not %s" msgstr "Indexy %q musí být celá čísla, nikoli %s" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "Inicializace %q selhala" @@ -169,6 +170,10 @@ msgstr "Délka %q musí být <= %d" msgid "%q length must be >= %d" msgstr "Délka %q musí být >= %d" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "" + #: py/argcheck.c msgid "%q must be %d" msgstr "%q musí být %d" @@ -248,6 +253,7 @@ msgstr "%q musí být mocnina 2" msgid "%q out of bounds" msgstr "%q je mimo hranice" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -509,7 +515,8 @@ msgstr "Všechny RX FIFO jsou používány" msgid "All SPI peripherals are in use" msgstr "Všechny SPI periferie jsou používány" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Všechny UART periferie jsou používány" @@ -662,6 +669,7 @@ msgstr "Velikost bitmapy a počet bitů na hodnotu se musí shodovat" msgid "Boot device must be first (interface #0)." msgstr "Bootovací zařízení musí být první (rozhraní #0)." +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "RX a TX jsou vyžadovány pro kontrolu toku" @@ -1009,7 +1017,7 @@ msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "Chyba alokace %q bufferu" @@ -1067,6 +1075,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "Nepodařilo se uvolnit mutex, err 0x%04x" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1271,6 +1283,10 @@ msgstr "Chyba přerušení." msgid "Interrupted by output function" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1363,6 +1379,7 @@ msgstr "Chybná velikost" msgid "Invalid socket for TLS" msgstr "Chybný soket pro TLS" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1925,6 +1942,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -2017,6 +2035,10 @@ msgstr "Konfigurace SPI selhala" msgid "SPI init error" msgstr "Chyba inicializace SPI" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "SPI periferie je používána" @@ -2148,6 +2170,10 @@ msgstr "Čas je v minulosti." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Časový limit je příliš dlouhý: maximální limit je %d vteřin" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "V samplu je příliš mnoho kanálů" @@ -2192,6 +2218,10 @@ msgstr "De-inicializace UART" msgid "UART init" msgstr "Inicializace UART" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "UART periférie je používána" @@ -2200,6 +2230,14 @@ msgstr "UART periférie je používána" msgid "UART re-init" msgstr "Opětovná inicializace UART" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "Zápis na UART" diff --git a/locale/el.po b/locale/el.po index 871ce82f6725c..91624ceb08672 100644 --- a/locale/el.po +++ b/locale/el.po @@ -145,6 +145,7 @@ msgstr "%q δείκτης εκτός εμβέλειας" msgid "%q indices must be integers, not %s" msgstr "%q δείκτες πρέπει να είναι ακέραιοι, όχι %s" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "%q εκκίνηση απέτυχε" @@ -173,6 +174,10 @@ msgstr "%q μήκος πρέπει να είναι <= %d" msgid "%q length must be >= %d" msgstr "%q μήκος πρέπει να είναι >= %d" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "%q μετακινήθηκε από το %q στο %q" + #: py/argcheck.c msgid "%q must be %d" msgstr "%q πρέπει να είναι %d" @@ -252,6 +257,7 @@ msgstr "%q πρέπει να είναι δύναμη του 2" msgid "%q out of bounds" msgstr "%q εκτός ορίων" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -513,7 +519,8 @@ msgstr "Όλα τα RX FIFOs είναι σε χρήση" msgid "All SPI peripherals are in use" msgstr "Όλα τα SPI περιφεριακά είναι σε χρήση" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Όλα τα UART περιφεριακά ειναι σε χρήση" @@ -666,6 +673,7 @@ msgstr "Το μέγεθος του bitmap και τα bits ανα τιμή πρ msgid "Boot device must be first (interface #0)." msgstr "Η συσκευή εκκίνησης πρέπει να επιλεχθεί πρώτα (διεπαφή #0)." +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "Και RX και TX απαιτούνται για έλεγχο flow" @@ -1017,7 +1025,7 @@ msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "" @@ -1075,6 +1083,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1277,6 +1289,10 @@ msgstr "" msgid "Interrupted by output function" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1369,6 +1385,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1930,6 +1947,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -2022,6 +2040,10 @@ msgstr "" msgid "SPI init error" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" @@ -2153,6 +2175,10 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2196,6 +2222,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "" @@ -2204,6 +2234,14 @@ msgstr "" msgid "UART re-init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "" @@ -4545,9 +4583,6 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" -#~ msgid "%q moved from %q to %q" -#~ msgstr "%q μετακινήθηκε από το %q στο %q" - #, c-format #~ msgid "%%c requires int or char" #~ msgstr "%%c απαιτεί ακέραιο ή χαρακτήρα" diff --git a/locale/hi.po b/locale/hi.po index f8408f6c119a5..1ab48338ebaba 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -132,6 +132,7 @@ msgstr "" msgid "%q indices must be integers, not %s" msgstr "" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" @@ -160,6 +161,10 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "" + #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -239,6 +244,7 @@ msgstr "" msgid "%q out of bounds" msgstr "" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -500,7 +506,8 @@ msgstr "" msgid "All SPI peripherals are in use" msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "" @@ -651,6 +658,7 @@ msgstr "" msgid "Boot device must be first (interface #0)." msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "" @@ -993,7 +1001,7 @@ msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "" @@ -1051,6 +1059,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1253,6 +1265,10 @@ msgstr "" msgid "Interrupted by output function" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1345,6 +1361,7 @@ msgstr "" msgid "Invalid socket for TLS" msgstr "" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1904,6 +1921,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1996,6 +2014,10 @@ msgstr "" msgid "SPI init error" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" @@ -2127,6 +2149,10 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2170,6 +2196,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "" @@ -2178,6 +2208,14 @@ msgstr "" msgid "UART re-init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 4a74ec9003488..35bfed4de08e9 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -143,6 +143,7 @@ msgstr "%q 인덱스 범위를 벗어났습니다" msgid "%q indices must be integers, not %s" msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "%q 초기화 실패" @@ -171,6 +172,11 @@ msgstr "%q 길이는 <= %d>여야 합니다" msgid "%q length must be >= %d" msgstr "%q 길이는 >= %d이어야 합니다" +#: py/runtime.c +#, fuzzy +msgid "%q moved from %q to %q" +msgstr "%q가 %q에서 %q로 이동했습니다" + #: py/argcheck.c msgid "%q must be %d" msgstr "%q는 %d이어야 합니다" @@ -256,6 +262,7 @@ msgstr "%q는 2의 거듭제곱이어야 합니다" msgid "%q out of bounds" msgstr "%q가 경계를 벗어남" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -531,7 +538,8 @@ msgstr "모든 RX FIFOs가 사용 중입니다" msgid "All SPI peripherals are in use" msgstr "사용중인 모든 SPI주변 기기" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "사용중인 모든 UART주변 기기" @@ -692,6 +700,7 @@ msgstr "비트맵 크기와 값 당 비트가 일치해야 합니다" msgid "Boot device must be first (interface #0)." msgstr "부팅 장치는 첫 번째(인터페이스 #0)여야 합니다." +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "플로우 제어에 RX와 TX가 모두 필요합니다" @@ -1041,7 +1050,7 @@ msgstr "" "서비스 TXT 레코드를 추가하는 것에 실패했습니다; txt_records에서 비문자열 또" "는 바이트가 발견되었습니다" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "%q 버퍼 할당에 실패했습니다" @@ -1099,6 +1108,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "뮤텍스 해제에 실패했습니다, 오류 0x%04x" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1304,6 +1317,10 @@ msgstr "인터럽트 오류." msgid "Interrupted by output function" msgstr "출력 함수로 인해 종료되었다" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1396,6 +1413,7 @@ msgstr "잘못된 크기" msgid "Invalid socket for TLS" msgstr "TLS에 대한 잘못된 소켓" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1978,6 +1996,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -2070,6 +2089,10 @@ msgstr "" msgid "SPI init error" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" @@ -2201,6 +2224,10 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2244,6 +2271,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "" @@ -2252,6 +2283,14 @@ msgstr "" msgid "UART re-init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "" @@ -4594,10 +4633,6 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" -#, fuzzy -#~ msgid "%q moved from %q to %q" -#~ msgstr "%q가 %q에서 %q로 이동했습니다" - #, c-format #~ msgid "%%c requires int or char" #~ msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" diff --git a/locale/ru.po b/locale/ru.po index 24b880972cb42..af7c8bca194d2 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -145,6 +145,7 @@ msgstr "Индекс %q вне диапазона" msgid "%q indices must be integers, not %s" msgstr "Индексы %q должны быть целыми числами, а не %s" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "Инициализация %q не удалась" @@ -173,6 +174,10 @@ msgstr "Длинна %q должна быть <= %d" msgid "%q length must be >= %d" msgstr "Длинна %q должна быть >= %d" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "%q переместился из %q в %q" + #: py/argcheck.c msgid "%q must be %d" msgstr "%q должно быть %d" @@ -252,6 +257,7 @@ msgstr "%q должен быть во 2-й степени" msgid "%q out of bounds" msgstr "%q за пределом" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -513,7 +519,8 @@ msgstr "Все RX FIFO уже используются" msgid "All SPI peripherals are in use" msgstr "Все периферийные устройства SPI уже используются" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Все периферийные устройства UART уже используются" @@ -667,6 +674,7 @@ msgstr "" msgid "Boot device must be first (interface #0)." msgstr "Загрузочное устройство должно быть первым (интерфейс #0)." +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "Для управления потоком требуется как RX так и TX" @@ -1022,7 +1030,7 @@ msgstr "" "Не удалось добавить служебную TXT-запись; в txt_records обнаружена нестрока " "или байт" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "Не удалось выделить буфер %q" @@ -1080,6 +1088,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "Не удалось освободить mutex, ошибка 0x%04x" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1292,6 +1304,10 @@ msgstr "Прерванная ошибка." msgid "Interrupted by output function" msgstr "Прерывается функцией выхода" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1384,6 +1400,7 @@ msgstr "Неверный размер" msgid "Invalid socket for TLS" msgstr "Неверный сокет для TLS" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1955,6 +1972,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -2047,6 +2065,10 @@ msgstr "Сбой конфигурации SPI" msgid "SPI init error" msgstr "Ошибка инициализации SPI" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "Используемое периферийное устройство SPI" @@ -2183,6 +2205,10 @@ msgstr "Время в прошлом." msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "Таймаут слишком длинный: максимальная длина таймаута %d секунд" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "Слишком много каналов в выборке" @@ -2226,6 +2252,10 @@ msgstr "Деинициализация UART" msgid "UART init" msgstr "Инициализация UART" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "Используемое периферийное устройство UART" @@ -2234,6 +2264,14 @@ msgstr "Используемое периферийное устройство U msgid "UART re-init" msgstr "Повторная инициализация UART" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "Запись UART" @@ -4612,9 +4650,6 @@ msgstr "zi должно быть типа float" msgid "zi must be of shape (n_section, 2)" msgstr "zi должен иметь форму (n_section, 2)" -#~ msgid "%q moved from %q to %q" -#~ msgstr "%q переместился из %q в %q" - #~ msgid "start/end indices" #~ msgstr "Начальные/конечные индексы" diff --git a/locale/tr.po b/locale/tr.po index f51ad3e8c12ee..758137eae21f8 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -143,6 +143,7 @@ msgstr "%q indeksi aralık dışında" msgid "%q indices must be integers, not %s" msgstr "%q indeksleri integer olmalı, %s değil" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "%q init başarısız oldu" @@ -171,6 +172,10 @@ msgstr "%q boyutu <= %d olmalıdır" msgid "%q length must be >= %d" msgstr "%q boyutu >= %d olmalıdır" +#: py/runtime.c +msgid "%q moved from %q to %q" +msgstr "" + #: py/argcheck.c msgid "%q must be %d" msgstr "%q, %d olmalıdır" @@ -250,6 +255,7 @@ msgstr "%q, 2'nin kuvveti olmalıdır" msgid "%q out of bounds" msgstr "%q sınırların dışında" +#: ports/analog/common-hal/busio/SPI.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/pulseio/PulseIn.c @@ -511,7 +517,8 @@ msgstr "Tüm RX FIFO'ları kullanımda" msgid "All SPI peripherals are in use" msgstr "Tüm SPI çevre birimleri kullanımda" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Tüm UART çevre birimleri kullanımda" @@ -664,6 +671,7 @@ msgstr "Bitmap boyutu ve bit başına değer uyuşmalı" msgid "Boot device must be first (interface #0)." msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" msgstr "Hem RX hem de TX akış kontrolü için gerekli" @@ -1007,7 +1015,7 @@ msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "" @@ -1065,6 +1073,10 @@ msgstr "" msgid "Failed to release mutex, err 0x%04x" msgstr "Muteks serbest bırakılamadı, err 0x%04x" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + #: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Failed to set hostname" msgstr "" @@ -1271,6 +1283,10 @@ msgstr "" msgid "Interrupted by output function" msgstr "" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c #: ports/espressif/common-hal/microcontroller/Processor.c @@ -1364,6 +1380,7 @@ msgstr "Geçersiz boyut" msgid "Invalid socket for TLS" msgstr "TLS için geçersiz soket" +#: ports/analog/common-hal/busio/SPI.c #: ports/espressif/common-hal/espidf/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" @@ -1926,6 +1943,7 @@ msgstr "" msgid "ROS topic failed to initialize" msgstr "" +#: ports/analog/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -2018,6 +2036,10 @@ msgstr "" msgid "SPI init error" msgstr "" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" @@ -2149,6 +2171,10 @@ msgstr "" msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" msgstr "" @@ -2192,6 +2218,10 @@ msgstr "" msgid "UART init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" msgstr "" @@ -2200,6 +2230,14 @@ msgstr "" msgid "UART re-init" msgstr "" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "UART write" msgstr "" From 34725676049ff52fbb5a34090aabc7640cd8a01e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 25 Sep 2025 11:32:05 -0400 Subject: [PATCH 139/208] use gc_ptr_on_heap() instead of checking if gc_bytes is zero --- main.c | 2 +- ports/espressif/common-hal/_bleio/Characteristic.c | 2 +- ports/nordic/common-hal/_bleio/Characteristic.c | 2 +- ports/nordic/common-hal/_bleio/Service.c | 2 +- ports/nordic/common-hal/busio/UART.c | 4 ++-- py/circuitpy_mpconfig.h | 8 ++++++++ py/gc.c | 2 +- py/gc.h | 2 +- shared-bindings/_bleio/Adapter.c | 2 +- supervisor/shared/usb/usb_msc_flash.c | 2 +- 10 files changed, 18 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 6c8e9c8804906..78148f2cb019c 100644 --- a/main.c +++ b/main.c @@ -214,7 +214,7 @@ static void stop_mp(void) { mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); // Unmount all heap allocated vfs mounts. - while (gc_nbytes(vfs) > 0) { + while (gc_ptr_on_heap(vfs)) { vfs = vfs->next; } MP_STATE_VM(vfs_mount_table) = vfs; diff --git a/ports/espressif/common-hal/_bleio/Characteristic.c b/ports/espressif/common-hal/_bleio/Characteristic.c index 7e917d6334b6b..805c6d160f325 100644 --- a/ports/espressif/common-hal/_bleio/Characteristic.c +++ b/ports/espressif/common-hal/_bleio/Characteristic.c @@ -120,7 +120,7 @@ void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) { return; } if (self->current_value != NULL) { - if (gc_nbytes(self->current_value) > 0) { + if (gc_ptr_on_heap(self->current_value)) { m_free(self->current_value); } else { port_free(self->current_value); diff --git a/ports/nordic/common-hal/_bleio/Characteristic.c b/ports/nordic/common-hal/_bleio/Characteristic.c index 1975c2c3d79ce..51335be9e59be 100644 --- a/ports/nordic/common-hal/_bleio/Characteristic.c +++ b/ports/nordic/common-hal/_bleio/Characteristic.c @@ -80,7 +80,7 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, // to allocate. self->initial_value_len = initial_value_bufinfo->len; if (gc_alloc_possible()) { - if (gc_nbytes(initial_value_bufinfo->buf) > 0) { + if (gc_ptr_on_heap(initial_value_bufinfo->buf)) { uint8_t *initial_value = m_malloc_without_collect(self->initial_value_len); memcpy(initial_value, initial_value_bufinfo->buf, self->initial_value_len); self->initial_value = initial_value; diff --git a/ports/nordic/common-hal/_bleio/Service.c b/ports/nordic/common-hal/_bleio/Service.c index edd67a5fe739d..1bd75f8a48114 100644 --- a/ports/nordic/common-hal/_bleio/Service.c +++ b/ports/nordic/common-hal/_bleio/Service.c @@ -131,7 +131,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, BLE_GAP_CONN_SEC_MODE_SET_OPEN(&user_desc_md.read_perm); // If the description is on the Python heap, then have the SD copy it. If not, assume it's // static and will live for longer than the SD. - user_desc_md.vloc = gc_nbytes(user_description) > 0 ? BLE_GATTS_VLOC_STACK : BLE_GATTS_VLOC_USER; + user_desc_md.vloc = gc_ptr_on_heap(user_description) ? BLE_GATTS_VLOC_STACK : BLE_GATTS_VLOC_USER; char_md.p_user_desc_md = &user_desc_md; char_md.p_char_user_desc = (const uint8_t *)user_description; char_md.char_user_desc_max_size = strlen(user_description); diff --git a/ports/nordic/common-hal/busio/UART.c b/ports/nordic/common-hal/busio/UART.c index 0dfe6ae3f5de2..6939486a5e673 100644 --- a/ports/nordic/common-hal/busio/UART.c +++ b/ports/nordic/common-hal/busio/UART.c @@ -122,7 +122,7 @@ void uart_reset(void) { void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { // Don't never reset objects on the heap. - if (gc_alloc_possible() && gc_nbytes(self) > 0) { + if (gc_alloc_possible() && gc_ptr_on_heap(self)) { return; } for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { @@ -346,7 +346,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, RUN_BACKGROUND_TASKS; } - if (!nrfx_is_in_ram(data) && gc_alloc_possible() && gc_nbytes(tx_buf) > 0) { + if (!nrfx_is_in_ram(data) && gc_alloc_possible() && gc_ptr_on_heap(tx_buf)) { gc_free(tx_buf); } diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 3ca06f7a0fd3a..127baa51ffc57 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -513,6 +513,14 @@ void background_callback_run_all(void); // USB settings +#ifndef CIRCUITPY_SDCARD_USB +#define CIRCUITPY_SDCARD_USB (1) +#endif + +#if CIRCUITPY_SDCARD_USB && !(CIRCUITPY_SDCARDIO) +#error CIRCUITPY_SDCARD_USB requires CIRCUITPY_SDCARDIO +#endif + // Debug level for TinyUSB. Only outputs over debug UART so it doesn't cause // additional USB logging. #ifndef CIRCUITPY_DEBUG_TINYUSB diff --git a/py/gc.c b/py/gc.c index 2cf4dbb64a83b..c6da81d495c10 100644 --- a/py/gc.c +++ b/py/gc.c @@ -446,7 +446,7 @@ bool gc_is_locked(void) { } // CIRCUITPY-CHANGE: additional function -bool gc_ptr_on_heap(void *ptr) { +bool gc_ptr_on_heap(const void *ptr) { for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { if (ptr >= (void *)area->gc_pool_start // must be above start of pool && ptr < (void *)area->gc_pool_end) { // must be below end of pool diff --git a/py/gc.h b/py/gc.h index ebc32b080fb47..0752478d1f286 100644 --- a/py/gc.h +++ b/py/gc.h @@ -87,7 +87,7 @@ void *gc_realloc(void *ptr, size_t n_bytes, bool allow_move); // CIRCUITPY-CHANGE // True if the pointer is on the MP heap. Doesn't require that it is the start // of a block. -bool gc_ptr_on_heap(void *ptr); +bool gc_ptr_on_heap(const void *ptr); typedef struct _gc_info_t { size_t total; diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index 92b910c8b2e0f..839b8b19addfa 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -339,7 +339,7 @@ static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args if (args[ARG_prefixes].u_obj != MP_OBJ_NULL) { mp_get_buffer_raise(args[ARG_prefixes].u_obj, &prefix_bufinfo, MP_BUFFER_READ); // An empty buffer may not be on the heap, but that doesn't matter. - if (prefix_bufinfo.len > 0 && gc_nbytes(prefix_bufinfo.buf) == 0) { + if (prefix_bufinfo.len > 0 && !gc_ptr_on_heap(prefix_bufinfo.buf)) { mp_raise_ValueError(MP_ERROR_TEXT("Prefix buffer must be on the heap")); } } diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 0b02faa5c18cb..4a23a5ec6c6c8 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -132,7 +132,7 @@ static fs_user_mount_t *get_vfs(int lun) { if (lun == SAVES_LUN) { const char *path_under_mount; fs_user_mount_t *saves = filesystem_for_path("/saves", &path_under_mount); - if (saves != root && (saves->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0 && gc_nbytes(saves) == 0) { + if (saves != root && (saves->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0 && !gc_ptr_on_heap(saves)) { return saves; } } From 3e1441e1926ffa26c1f2fe0d3930a1054d625b31 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 25 Sep 2025 18:12:33 -0400 Subject: [PATCH 140/208] allow enable/disable of presenting SD card to USB; suppress auto-reload when writing dirty bit --- ports/atmel-samd/mpconfigport.h | 3 ++ ports/cxd56/mpconfigport.h | 3 ++ ports/espressif/mpconfigport.h | 5 ++++ shared-module/sdcardio/__init__.c | 2 +- supervisor/shared/filesystem.c | 3 +- supervisor/shared/usb/usb_msc_flash.c | 40 +++++++++++++++++++++------ 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 087e0bc7d6820..e953ea0fc50d4 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -11,6 +11,9 @@ // Definitions that control circuitpy_mpconfig.h: +// On SAMD, presenting the SD card as a second LUN causes USB disconnect. This needs to be fixed eventually. +#define CIRCUITPY_SDCARD_USB (0) + //////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef SAMD21 diff --git a/ports/cxd56/mpconfigport.h b/ports/cxd56/mpconfigport.h index 3bcb252868786..f0a57248bebef 100644 --- a/ports/cxd56/mpconfigport.h +++ b/ports/cxd56/mpconfigport.h @@ -8,6 +8,9 @@ #define MICROPY_PY_SYS_PLATFORM "CXD56" +// SD card socket on board is configured for sdioio, which is not supported for automatic USB presentation. +#define CIRCUITPY_SDCARD_USB (0) + // 64kiB stack #define CIRCUITPY_DEFAULT_STACK_SIZE (0x10000) diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index 712eb67f1f42a..8fdc1fad94d19 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -17,6 +17,11 @@ #define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (1) +// // Present SD card as USB MSC device by default +// #ifndef CIRCUITPY_SDCARD_USB +// #define CIRCUITPY_SDCARD_USB (1) +// #endif + #include "py/circuitpy_mpconfig.h" #define MICROPY_NLR_SETJMP (1) diff --git a/shared-module/sdcardio/__init__.c b/shared-module/sdcardio/__init__.c index a49a1506712db..29c890c6870c1 100644 --- a/shared-module/sdcardio/__init__.c +++ b/shared-module/sdcardio/__init__.c @@ -123,5 +123,5 @@ void automount_sd_card(void) { sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); MP_STATE_VM(vfs_mount_table) = sdcard_vfs; _mounted = true; - #endif + #endif // DEFAULT_SD_CARD_DETECT } diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 0df600e77fd2f..df70d963de6f1 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -148,8 +148,7 @@ bool filesystem_init(bool create_allowed, bool force_create) { res = f_mkdir(&circuitpy->fatfs, "/sd"); #if CIRCUITPY_FULL_BUILD MAKE_FILE_WITH_OPTIONAL_CONTENTS(&circuitpy->fatfs, "/sd/placeholder.txt", - "SD cards mounted at /sd will hide this file from Python." - " SD cards are not visible via USB CIRCUITPY.\n"); + "SD cards mounted at /sd will hide this file from Python.\n"); #endif #endif diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 4a23a5ec6c6c8..e4e4801de9c88 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -45,6 +45,11 @@ static bool ejected[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = true}; static bool eject_once[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; static bool locked[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; +// Set to true if a write was in a file data or metadata area, +// as opposed to in the filesystem metadata area (e.g., dirty bit). +// Used to determine if an auto-reload is warranted. +static bool content_write[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; + #include "tusb.h" static const uint8_t usb_msc_descriptor_template[] = { @@ -141,6 +146,7 @@ static fs_user_mount_t *get_vfs(int lun) { if (lun == SDCARD_LUN) { const char *path_under_mount; fs_user_mount_t *sdcard = filesystem_for_path("/sd", &path_under_mount); + // If "/sd" is on the root filesystem, nothing has been mounted there. if (sdcard != root && (sdcard->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0) { return sdcard; } else { @@ -290,16 +296,19 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * if (vfs == NULL) { return -1; } + disk_write(vfs, buffer, lba, block_count); // Since by getting here we assume the mount is read-only to - // MicroPython let's update the cached FatFs sector if it's the one + // CircuitPython let's update the cached FatFs sector if it's the one // we just wrote. + if #if FF_MAX_SS != FF_MIN_SS - if (vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) { + (vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) #else // The compiler can optimize this away. - if (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) { - #endif + (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) + #endif + { if (lba == vfs->fatfs.winsect && lba > 0) { memcpy(vfs->fatfs.win, buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), @@ -307,17 +316,30 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * } } + // A write to an lba below fatbase is in the filesystem metadata (BPB) area or the "Reserved Region", + // and is probably setting or clearing the dirty bit. This should not trigger auto-reload. + // All other writes will trigger auto-reload. + if (lba >= vfs->fatfs.fatbase) { + content_write[lun] = true; + } + return block_count * MSC_FLASH_BLOCK_SIZE; } // Callback invoked when WRITE10 command is completed (status received and accepted by host). // used to flush any pending cache. void tud_msc_write10_complete_cb(uint8_t lun) { - (void)lun; - - // This write is complete; initiate an autoreload. autoreload_resume(AUTORELOAD_SUSPEND_USB); - autoreload_trigger(); + + // This write is complete; initiate an autoreload if this was a file data or metadata write, + // not just a dirty-bit write. + if (content_write[lun] && + // Fast path: lun == 0 is CIRCUITPY, which can always trigger auto-reload if enabled. + // Don't autoreload if this lun was mounted by the user: that will cause a VM stop and an unmount. + (lun == 0 || !gc_ptr_on_heap(get_vfs(lun)))) { + autoreload_trigger(); + content_write[lun] = false; + } } // Invoked when received SCSI_CMD_INQUIRY @@ -337,7 +359,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { return false; } - #if CIRCUITPY_SDCARDIO + #if CIRCUITPY_SDCARD_USB if (lun == SDCARD_LUN) { automount_sd_card(); } From f143e1d164c7e3b3ff5aa5dfcd8362d893e79862 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 25 Sep 2025 23:28:00 -0400 Subject: [PATCH 141/208] ports/espressif/mpconfigport.h: remove commented code --- ports/espressif/mpconfigport.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index 8fdc1fad94d19..712eb67f1f42a 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -17,11 +17,6 @@ #define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (1) -// // Present SD card as USB MSC device by default -// #ifndef CIRCUITPY_SDCARD_USB -// #define CIRCUITPY_SDCARD_USB (1) -// #endif - #include "py/circuitpy_mpconfig.h" #define MICROPY_NLR_SETJMP (1) From d5ca68573dc230eec5f593245b5e2d2cebe2d3f9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 25 Sep 2025 23:41:31 -0400 Subject: [PATCH 142/208] fix CIRCUITPY_SDCARD_USB default --- py/circuitpy_mpconfig.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 127baa51ffc57..541c0420a6e80 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -514,7 +514,11 @@ void background_callback_run_all(void); // USB settings #ifndef CIRCUITPY_SDCARD_USB -#define CIRCUITPY_SDCARD_USB (1) +#if CIRCUITPY_USB_DEVICE +#define CIRCUITPY_SDCARD_USB (CIRCUITPY_SDCARDIO && CIRCUITPY_USB_MSC) +#else +#define CIRCUITPY_SDCARD_USB (0) +#endif #endif #if CIRCUITPY_SDCARD_USB && !(CIRCUITPY_SDCARDIO) From edd4532bf566ffae058acaf90e6c1eda1b24c1ec Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 26 Sep 2025 00:13:11 -0400 Subject: [PATCH 143/208] document SD card USB presentation --- docs/workflows.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/workflows.md b/docs/workflows.md index 761504144d8b9..84d7530e2fe99 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -44,6 +44,12 @@ A few boards have SD card automounting. (This is based on the ``DEFAULT_SD`` set ``mpconfigboard.h``.) The card is writable from CircuitPython by default and read-only to the host. `storage.remount()` can be used to remount the drive to the host as read-write. +On most other boards, except for ``atmel-samd`` boards, an SD card mounted in user code +at ``/sd`` will become visible after a few seconds on the attached host computer, as an +additional drive besides CIRCUITPY and (if present) CPSAVES. It will present with the volume +label on the SD card. Depending on the host operating system settings, the drive may or may not be +auto-mounted on the host. Host writes to drives mounted by user code will not trigger a reload. + ### CDC serial CircuitPython exposes one CDC USB interface for CircuitPython serial. This is a standard serial USB interface. From 3d22d521fe8d5a6c62adb1857b838166d1cf747f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 29 Sep 2025 20:15:51 -0400 Subject: [PATCH 144/208] Prevent both host and CircuitPython rw access to mounted filesystems --- py/circuitpy_mpconfig.h | 3 +++ shared-bindings/storage/__init__.c | 10 +++++++++- shared-module/storage/__init__.c | 5 +++++ supervisor/shared/filesystem.c | 8 ++++---- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 27d4e97ad4d45..2754d57b01c9b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -345,6 +345,9 @@ typedef long mp_off_t; #endif +// For easy debugging printf's. +#define PLAT_PRINTF(...) mp_printf(&mp_plat_print, __VA_ARGS__) + #if MICROPY_PY_ASYNC_AWAIT && !CIRCUITPY_TRACEBACK #error CIRCUITPY_ASYNCIO requires CIRCUITPY_TRACEBACK #endif diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index ee0fb4ab53c3a..93c360d564e2f 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -54,15 +54,23 @@ static mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t // get the mount point const char *mnt_str = mp_obj_str_get_str(args[ARG_mount_path].u_obj); + + mp_obj_t vfs_obj = args[ARG_filesystem].u_obj; + + // Currently, the only supported filesystem is VfsFat. + mp_arg_validate_type(vfs_obj, &mp_fat_vfs_type, MP_QSTR_filesystem); + + // Add this back if/when we start supporting other filesystems. + #if 0 // Make sure we're given an object we can mount. // TODO(tannewt): Make sure we have all the methods we need to operating it // as a file system. - mp_obj_t vfs_obj = args[ARG_filesystem].u_obj; mp_obj_t dest[2]; mp_load_method_maybe(vfs_obj, MP_QSTR_mount, dest); if (dest[0] == MP_OBJ_NULL) { mp_raise_ValueError(MP_ERROR_TEXT("filesystem must provide mount method")); } + #endif common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool); diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 9a2c8271222e0..dedcee1ff23f5 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -126,6 +126,11 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool rea // call the underlying object to do any mounting operation mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t *)&args); + fs_user_mount_t *vfs_fat = MP_OBJ_TO_PTR(vfs_obj); + // Filesystem is read-only to USB if writable by CircuitPython, and vice versa. + filesystem_set_writable_by_usb(vfs_fat, readonly); + filesystem_set_concurrent_write_protection(vfs_fat, true); + // Insert the vfs into the mount table by pushing it onto the front of the // mount table. mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index df70d963de6f1..24c7f9bffc552 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -247,13 +247,13 @@ void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) { } bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) { - return (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0 || - (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0; + return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0); } bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) { - return (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0 || - (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0; + return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0); } void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) { From 81e77aa71e1dfdd4989f832346874e89d3dd564a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 30 Sep 2025 10:57:27 -0400 Subject: [PATCH 145/208] main.c: unmount user-mounted vfs regardless of order --- main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 78148f2cb019c..d7f3c7aaf1bce 100644 --- a/main.c +++ b/main.c @@ -211,14 +211,22 @@ static void start_mp(safe_mode_t safe_mode) { static void stop_mp(void) { #if MICROPY_VFS - mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); // Unmount all heap allocated vfs mounts. - while (gc_ptr_on_heap(vfs)) { + mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); + do { + if (gc_ptr_on_heap(vfs)) { + // mp_vfs_umount will splice out an unmounted vfs from the vfs_mount_table linked list. + mp_vfs_umount(vfs->obj); + // Start over at the beginning of the list since the first entry may have been removed. + vfs = MP_STATE_VM(vfs_mount_table); + continue; + } vfs = vfs->next; - } - MP_STATE_VM(vfs_mount_table) = vfs; + } while (vfs != NULL); + // The last vfs is CIRCUITPY and the root directory. + vfs = MP_STATE_VM(vfs_mount_table); while (vfs->next != NULL) { vfs = vfs->next; } From 216b3100652f93466730b49c5993293e0dc23459 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 30 Sep 2025 12:09:13 -0400 Subject: [PATCH 146/208] shrink some atmel-samd boards --- .../atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk | 3 ++- ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk | 1 + ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk | 1 + ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk index 7c301e3ea9692..121becc472d36 100755 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk @@ -11,4 +11,5 @@ EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 -CIRCUITPY_JPEGIO = 0 +CIRCUITPY_ERRNO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index 783e2cb565783..1152fb4acc419 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -11,4 +11,5 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index bd068adc943e2..dd58e8d1ce5a7 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -11,4 +11,5 @@ EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk index a7c18acba3c55..ee414b6e214b0 100644 --- a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk @@ -17,6 +17,7 @@ CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_GIFIO = 0 CIRCUITPY_I2CTARGET = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_PS2IO = 0 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_LTO_PARTITION = one From 179a52ec5321a3ad9a45f102f88b771852a96025 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 30 Sep 2025 13:40:56 -0400 Subject: [PATCH 147/208] remove unused code --- shared-bindings/storage/__init__.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index 93c360d564e2f..14ec16f3096c7 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -60,18 +60,6 @@ static mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t // Currently, the only supported filesystem is VfsFat. mp_arg_validate_type(vfs_obj, &mp_fat_vfs_type, MP_QSTR_filesystem); - // Add this back if/when we start supporting other filesystems. - #if 0 - // Make sure we're given an object we can mount. - // TODO(tannewt): Make sure we have all the methods we need to operating it - // as a file system. - mp_obj_t dest[2]; - mp_load_method_maybe(vfs_obj, MP_QSTR_mount, dest); - if (dest[0] == MP_OBJ_NULL) { - mp_raise_ValueError(MP_ERROR_TEXT("filesystem must provide mount method")); - } - #endif - common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool); return mp_const_none; From 0b89ac1e245bbf5070b8cb752ebc18a6516c2adf Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 30 Sep 2025 16:32:41 -0400 Subject: [PATCH 148/208] update frozen libraries --- frozen/Adafruit_CircuitPython_PortalBase | 2 +- frozen/Adafruit_CircuitPython_Wiznet5k | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index c87f120723e9f..d26e2324de496 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit c87f120723e9fa742e3da25eaf33f3be1ae33715 +Subproject commit d26e2324de496761e0aa72abc30ba07cdce8814b diff --git a/frozen/Adafruit_CircuitPython_Wiznet5k b/frozen/Adafruit_CircuitPython_Wiznet5k index 6b3484d1ee243..736241c7a22f8 160000 --- a/frozen/Adafruit_CircuitPython_Wiznet5k +++ b/frozen/Adafruit_CircuitPython_Wiznet5k @@ -1 +1 @@ -Subproject commit 6b3484d1ee243a7e8bc0513ab84956e1b6e2a520 +Subproject commit 736241c7a22f86dcf8ff73a77c4536cedfdc4cdd From 3de2c639fd9070bf49f09f4f8af0da6148af7817 Mon Sep 17 00:00:00 2001 From: Juergen Pabel Date: Thu, 2 Oct 2025 18:15:47 +0200 Subject: [PATCH 149/208] Added new board: M5Stack DinMeter (esp32s3) --- .../espressif/boards/m5stack_dinmeter/board.c | 107 ++++++++++++++++++ .../boards/m5stack_dinmeter/mpconfigboard.h | 22 ++++ .../boards/m5stack_dinmeter/mpconfigboard.mk | 15 +++ .../espressif/boards/m5stack_dinmeter/pins.c | 61 ++++++++++ .../boards/m5stack_dinmeter/sdkconfig | 14 +++ 5 files changed, 219 insertions(+) create mode 100644 ports/espressif/boards/m5stack_dinmeter/board.c create mode 100644 ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h create mode 100644 ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk create mode 100644 ports/espressif/boards/m5stack_dinmeter/pins.c create mode 100644 ports/espressif/boards/m5stack_dinmeter/sdkconfig diff --git a/ports/espressif/boards/m5stack_dinmeter/board.c b/ports/espressif/boards/m5stack_dinmeter/board.c new file mode 100644 index 0000000000000..cd49318fd1cec --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/board.c @@ -0,0 +1,107 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" +#include "supervisor/board.h" +#include "supervisor/shared/serial.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "py/runtime.h" +#include "py/ringbuf.h" +#include "shared/runtime/interrupt_char.h" + + +uint8_t display_init_sequence[] = { + 0x01, 0x80, 0x96, // SWRESET and Delay 150ms + 0x11, 0x80, 0xff, // SLPOUT and Delay + 0xb1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR2 + 0xb3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xb4, 0x01, 0x07, // _INVCTR line inversion + 0xc0, 0x03, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 0x01, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 0x02, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 0x02, 0x8a, 0x2a, + 0xc4, 0x02, 0x8a, 0xee, + 0xc5, 0x01, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36, 0x01, 0xc8, // MADCTL Rotate display + 0x21, 0x00, // _INVON + 0x3a, 0x01, 0x05, // COLMOD - 16bit color + 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0x80, 0x0a, // _NORON + 0x29, 0x80, 0x64 // _DISPON +}; + + +// Overrides the weakly linked function from supervisor/shared/board.c +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + // see here for inspiration: https://github.com/m5stack/M5GFX/blob/33d7d3135e816a86a008fae8ab3757938cee95d2/src/M5GFX.cpp#L1350 + common_hal_fourwire_fourwire_construct( + bus, + spi, + &pin_GPIO4, // DC + &pin_GPIO7, // CS + &pin_GPIO8, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 40, // column start + 52, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO9, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 80, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Hold pin must be set high to avoid a power off when battery powered + if (pin_number == 46) { + // Turn on hold output + config_pin_as_output_with_level(pin_number, true); + return true; + } + return false; +} + +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h new file mode 100644 index 0000000000000..2d69e61ea950a --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 CDarius +// SPDX-FileCopyrightText: Copyright (c) 2025 juergenpabel +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack DinMeter" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO12, .sda = &pin_GPIO11}, \ + {.scl = &pin_GPIO15, .sda = &pin_GPIO13}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO6, .mosi = &pin_GPIO5}} + +#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP (1) diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk new file mode 100644 index 0000000000000..7b7e941b6bc0a --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x303A +USB_PID = 0x81DD + +USB_PRODUCT = "M5stack - DinMeter" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Very few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/m5stack_dinmeter/pins.c b/ports/espressif/boards/m5stack_dinmeter/pins.c new file mode 100644 index 0000000000000..f75e05e848b0b --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/pins.c @@ -0,0 +1,61 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Juergen Pabel +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Port A + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + // Port B + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + + // Encoder + { MP_ROM_QSTR(MP_QSTR_ENC_A), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_ENC_B), MP_ROM_PTR(&pin_GPIO40) }, + + // Button + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + // Misc + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_KNOB_BUTTON), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_POWER_HOLD), MP_ROM_PTR(&pin_GPIO46) }, + + // Display + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_dinmeter/sdkconfig b/ports/espressif/boards/m5stack_dinmeter/sdkconfig new file mode 100644 index 0000000000000..e962866216039 --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration From 7806098d3866ce805b63c358ab64c837e008669d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Pabel?= Date: Thu, 2 Oct 2025 20:48:31 +0200 Subject: [PATCH 150/208] Update ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk Co-authored-by: Scott Shawcroft --- ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk index 7b7e941b6bc0a..02570b54230d7 100644 --- a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x303A USB_PID = 0x81DD -USB_PRODUCT = "M5stack - DinMeter" +USB_PRODUCT = "DinMeter" USB_MANUFACTURER = "M5Stack" IDF_TARGET = esp32s3 From 5b4b9e8db19c097e8422c15b04705050fab98798 Mon Sep 17 00:00:00 2001 From: Juergen Pabel Date: Thu, 2 Oct 2025 20:57:03 +0200 Subject: [PATCH 151/208] Updated USB-PID as per https://github.com/espressif/usb-pids/pull/261 --- ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk index 02570b54230d7..81a23af1fe464 100644 --- a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk @@ -1,5 +1,5 @@ USB_VID = 0x303A -USB_PID = 0x81DD +USB_PID = 0x830B USB_PRODUCT = "DinMeter" USB_MANUFACTURER = "M5Stack" From 1ad0d5fcb113b9c44ed0328e9f28de4596bd789f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 3 Oct 2025 14:02:14 -0400 Subject: [PATCH 152/208] drop Nano from Microchip Curiosity CircuitPython Nano --- .../board.c | 0 .../mpconfigboard.h | 2 +- .../mpconfigboard.mk | 2 +- .../pins.c | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename ports/atmel-samd/boards/{microchip_curiosity_circuitpython_nano => microchip_curiosity_circuitpython}/board.c (100%) rename ports/atmel-samd/boards/{microchip_curiosity_circuitpython_nano => microchip_curiosity_circuitpython}/mpconfigboard.h (99%) rename ports/atmel-samd/boards/{microchip_curiosity_circuitpython_nano => microchip_curiosity_circuitpython}/mpconfigboard.mk (83%) rename ports/atmel-samd/boards/{microchip_curiosity_circuitpython_nano => microchip_curiosity_circuitpython}/pins.c (100%) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/board.c similarity index 100% rename from ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/board.c rename to ports/atmel-samd/boards/microchip_curiosity_circuitpython/board.c diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h similarity index 99% rename from ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h rename to ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h index 6e67197e757f1..4416d8517d279 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.h +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h @@ -1,7 +1,7 @@ #pragma once -#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython Nano" +#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython" #define MICROPY_HW_MCU_NAME "same51j20" #define CIRCUITPY_MCU_FAMILY samd51 diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk similarity index 83% rename from ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk rename to ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk index 4bb7b68550922..985eb4c6a4465 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/mpconfigboard.mk +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk @@ -1,6 +1,6 @@ USB_VID = 0x04D8 USB_PID = 0xE52B -USB_PRODUCT = "Microchip Curiosity CircuitPython Nano" +USB_PRODUCT = "Microchip Curiosity CircuitPython" USB_MANUFACTURER = "Microchip Technology Inc" CHIP_VARIANT = SAME51J20A diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c similarity index 100% rename from ports/atmel-samd/boards/microchip_curiosity_circuitpython_nano/pins.c rename to ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c From ea15d7461402e5a5346b28e73458c115fe72b419 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 5 Oct 2025 15:45:42 -0400 Subject: [PATCH 153/208] Allow subclassing deque --- py/objdeque.c | 36 ++++++++++++++++-------- tests/circuitpython/deque_subclass.py | 40 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 tests/circuitpython/deque_subclass.py diff --git a/py/objdeque.c b/py/objdeque.c index 264c795801ba4..4e1ee82e9d4de 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -46,6 +46,11 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in); static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf); #endif +// CIRCUITPY-CHANGE +static mp_obj_deque_t *native_deque(mp_obj_t self_in) { + return MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_deque))); +} + static mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 3, false); @@ -79,7 +84,8 @@ static size_t deque_len(mp_obj_deque_t *self) { } static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->i_get != self->i_put); @@ -98,7 +104,8 @@ static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_put = self->i_put + 1; if (new_i_put == self->alloc) { @@ -123,7 +130,8 @@ static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_append_obj, mp_obj_deque_append); static mp_obj_t mp_obj_deque_appendleft(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_get = self->i_get - 1; if (self->i_get == 0) { @@ -162,7 +170,8 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_extend_obj, mp_obj_deque_extend); static mp_obj_t deque_popleft(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -180,7 +189,8 @@ static mp_obj_t deque_popleft(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(deque_popleft_obj, deque_popleft); static mp_obj_t deque_pop(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -205,7 +215,8 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { // delete not supported, fall back to mp_obj_subscr() error message return MP_OBJ_NULL; } - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t offset = mp_get_index(self->base.type, deque_len(self), index, false); size_t index_val = self->i_get + offset; @@ -226,7 +237,8 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if 0 static mp_obj_t deque_clear(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); self->i_get = self->i_put = 0; mp_seq_clear(self->items, 0, self->alloc, sizeof(*self->items)); return mp_const_none; @@ -286,7 +298,8 @@ typedef struct _mp_obj_deque_it_t { static mp_obj_t deque_it_iternext(mp_obj_t self_in) { mp_obj_deque_it_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_deque_t *deque = MP_OBJ_TO_PTR(self->deque); + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(self->deque); if (self->cur != deque->i_put) { mp_obj_t o_out = deque->items[self->cur]; if (++self->cur == deque->alloc) { @@ -298,9 +311,10 @@ static mp_obj_t deque_it_iternext(mp_obj_t self_in) { } } -static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf) { - mp_obj_deque_t *deque_ = MP_OBJ_TO_PTR(deque); - size_t i_get = deque_->i_get; +static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque_in, mp_obj_iter_buf_t *iter_buf) { + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(deque_in); + size_t i_get = deque->i_get; assert(sizeof(mp_obj_deque_it_t) <= sizeof(mp_obj_iter_buf_t)); mp_obj_deque_it_t *o = (mp_obj_deque_it_t *)iter_buf; o->base.type = &mp_type_polymorph_iter; diff --git a/tests/circuitpython/deque_subclass.py b/tests/circuitpython/deque_subclass.py new file mode 100644 index 0000000000000..5708407a9b630 --- /dev/null +++ b/tests/circuitpython/deque_subclass.py @@ -0,0 +1,40 @@ +try: + from collections import deque +except ImportError: + print("SKIP") + raise SystemExit + + +class DequeSubclass(deque): + def __init__(self, values, maxlen): + super().__init__(values, maxlen) + + def pop(self): + print("pop") + return super().pop() + + def popleft(self): + print("popleft") + return super().popleft() + + def append(self, value): + print("append") + return super().append(value) + + def appendleft(self, value): + print("appendleft") + return super().appendleft(value) + + def extend(self, value): + print("extend") + return super().extend(value) + + +d = DequeSubclass([1, 2, 3], 10) +print(d.append(4)) +print(d.appendleft(0)) +print(d.pop()) +print(d.popleft()) +d.extend([6, 7]) +# calling list() tests iteration. +print(list(d)) From 36d53efa7c6f9a3f0172620df309904a01a8e854 Mon Sep 17 00:00:00 2001 From: Chris Wilson <14631+cdwilson@users.noreply.github.com> Date: Mon, 6 Oct 2025 11:41:37 -0700 Subject: [PATCH 154/208] stm/boards: Fix USB PID for SparkFun STM32 MicroMod. When I originally created the PR to add support for the SparkFun STM32 MicroMod, SparkFun provided me with the following PID/VID: PID: 0x0027 VID: 0X1B4F I missed a follow-up post from SparkFun about 5 months later which provided a corrected PID for this device: PID: 0x0029 See https://community.sparkfun.com/t/circuitpython-support-for-micromod-stm32-need-usb-pid/42486/5 --- ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk index d1df685c6764e..31c2b7e2874f9 100644 --- a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk @@ -1,5 +1,5 @@ USB_VID = 0X1B4F -USB_PID = 0x0027 +USB_PID = 0x0029 USB_PRODUCT = "SparkFun STM32 MicroMod Processor" USB_MANUFACTURER = "SparkFun Electronics" From 3d40ba3531701407daa13f9a979ddbdd44806bcd Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 14 Aug 2025 11:40:43 -0700 Subject: [PATCH 155/208] Update to ESP IDF 5.5.1 --- .gitmodules | 2 +- lib/protomatter | 2 +- lib/tinyusb | 2 +- ports/espressif/Makefile | 31 +++++++++++++------ .../espressif/common-hal/alarm/pin/PinAlarm.c | 2 ++ .../espressif/common-hal/analogio/AnalogIn.c | 6 ---- ports/espressif/common-hal/espnow/ESPNow.c | 2 +- .../paralleldisplaybus/ParallelBus.c | 2 +- .../paralleldisplaybus/ParallelBus.h | 2 +- ports/espressif/esp-idf | 2 +- .../esp-idf-config/partitions-8MB-no-uf2.csv | 3 +- .../esp-idf-config/sdkconfig.defaults | 6 ++++ ports/espressif/mpconfigport.mk | 2 ++ ports/espressif/peripherals/pins.h | 2 +- py/circuitpy_mpconfig.mk | 4 +++ supervisor/supervisor.mk | 5 ++- 16 files changed, 48 insertions(+), 27 deletions(-) diff --git a/.gitmodules b/.gitmodules index b89769942af7f..7eaa0b04142b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -143,7 +143,7 @@ [submodule "ports/espressif/esp-idf"] path = ports/espressif/esp-idf url = https://github.com/adafruit/esp-idf.git - branch = circuitpython-v5.4.1 + branch = circuitpython-v5.5.1 [submodule "ports/espressif/esp-protocols"] path = ports/espressif/esp-protocols url = https://github.com/adafruit/esp-protocols.git diff --git a/lib/protomatter b/lib/protomatter index 0bd9873153ab0..f83bac7e42107 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit 0bd9873153ab0a91d6737c392622159a4515a2e5 +Subproject commit f83bac7e421077812523fddb83d3e25f29753315 diff --git a/lib/tinyusb b/lib/tinyusb index 5fb3c09963bca..8304587d77745 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 5fb3c09963bca362e535788e289d4b3518da5973 +Subproject commit 8304587d7774526a03c6881d11e6d6208fe759be diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index a063101991fdb..157b59d9aaa0f 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -64,6 +64,7 @@ INC += \ -isystem esp-idf/components/esp_driver_i2s/include \ -isystem esp-idf/components/esp_driver_$(IDF_TARGET)/include \ -isystem esp-idf/components/esp_driver_ledc/include \ + -isystem esp-idf/components/esp_driver_parlio/include \ -isystem esp-idf/components/esp_driver_pcnt/include \ -isystem esp-idf/components/esp_driver_rmt/include \ -isystem esp-idf/components/esp_driver_sdio/include \ @@ -149,6 +150,8 @@ CFLAGS += -DSTACK_CANARY_VALUE=0xa5a5a5a5 REGISTRATION_FUNCTIONS = \ -u ld_include_highint_hdl \ -u __cxx_fatal_exception \ + -u __cxx_init_dummy \ + -u __cxa_guard_dummy \ -u esp_app_desc \ -u esp_timer_init_include_func \ -u uart_vfs_include_dev_init \ @@ -156,13 +159,17 @@ REGISTRATION_FUNCTIONS = \ -u __ubsan_include \ -u esp_system_include_startup_funcs \ -u esp_efuse_startup_include_func \ - -u newlib_include_heap_impl \ - -u newlib_include_syscalls_impl \ - -u newlib_include_pthread_impl \ - -u newlib_include_assert_impl \ - -u newlib_include_init_funcs \ + -u esp_libc_include_heap_impl \ + -u esp_libc_include_reent_syscalls_impl \ + -u esp_libc_include_syscalls_impl \ + -u esp_libc_include_pthread_impl \ + -u esp_libc_include_assert_impl \ + -u esp_libc_include_getentropy_impl \ + -u esp_libc_include_init_funcs \ + -u esp_libc_init_funcs \ -u include_esp_phy_override \ - -u vfs_include_syscalls_impl + -u vfs_include_syscalls_impl \ + -u esp_vfs_include_nullfs_register #Debugging/Optimization @@ -222,7 +229,6 @@ else ifeq ($(IDF_TARGET_ARCH),riscv) -Trom.api.ld endif -$(BUILD)/lib/tlsf/tlsf.o: CFLAGS += -Wno-cast-align LDFLAGS += $(CFLAGS) -Wl,-nostdlib -Wl,-Map=$@.map -Wl,-cref -Wl,--undefined=uxTopUsedPriority @@ -244,7 +250,9 @@ LDFLAGS += \ ifeq ($(IDF_TARGET),esp32) LDFLAGS += \ -Tesp32.rom.newlib-data.ld \ - -Tesp32.rom.newlib-funcs.ld \ + -Tesp32.rom.syscalls.ld \ + -Tesp32.rom.libc-funcs.ld \ + -Tesp32.rom.newlib-reent-funcs.ld \ -Tesp32.rom.spiflash_legacy.ld CHIP_COMPONENTS = \ @@ -280,7 +288,9 @@ LDFLAGS += \ -Tesp32c6.rom.phy.ld \ -Tesp32c6.rom.pp.ld \ -Tesp32c6.rom.net80211.ld \ + -Tesp32c6.rom.libc.ld \ -Tesp32c6.rom.newlib.ld \ + -Tesp32c6.rom.spiflash.ld \ -Tesp32c6.rom.coexist.ld \ -Tesp32c6.rom.heap.ld \ -Tesp32c6.rom.systimer.ld \ @@ -312,8 +322,9 @@ CHIP_COMPONENTS = \ else ifeq ($(IDF_TARGET),esp32s2) LDFLAGS += \ + -Tesp32s2.rom.libc-funcs.ld \ -Tesp32s2.rom.newlib-data.ld \ - -Tesp32s2.rom.newlib-funcs.ld \ + -Tesp32s2.rom.newlib-reent-funcs.ld \ -Tesp32s2.rom.spiflash_legacy.ld CHIP_COMPONENTS = \ @@ -782,7 +793,7 @@ endif IDF_CMAKE_TARGETS = \ bootloader/bootloader.bin \ - esp-idf/esp_system/__ldgen_output_sections.ld \ + __ldgen_output_sections.ld \ $(foreach component, $(ESP_IDF_COMPONENTS_LINK), esp-idf/$(component)/lib$(component).a) PARTITION_TABLE_OFFSET = 0x8000 diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index 8e3e46785f2e7..cecb91fe46df9 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -14,10 +14,12 @@ #include "esp_sleep.h" #include "hal/gpio_ll.h" +#include "driver/gpio.h" #include "esp_debug_helpers.h" #ifdef SOC_PM_SUPPORT_EXT0_WAKEUP #include "soc/rtc_cntl_reg.h" +#include "soc/rtc_io_reg.h" #endif #include "driver/rtc_io.h" diff --git a/ports/espressif/common-hal/analogio/AnalogIn.c b/ports/espressif/common-hal/analogio/AnalogIn.c index 16340e91ac91c..b4039b3d32dd8 100644 --- a/ports/espressif/common-hal/analogio/AnalogIn.c +++ b/ports/espressif/common-hal/analogio/AnalogIn.c @@ -86,10 +86,8 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { adc_cali_scheme_ver_t supported_schemes; adc_cali_check_scheme(&supported_schemes); - #ifndef CONFIG_IDF_TARGET_ESP32P4 adc_cali_scheme_ver_t calibration_scheme = 0; adc_cali_handle_t calibration; - #endif #if defined(ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED) && ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED adc_cali_curve_fitting_config_t config = { .unit_id = self->pin->adc_index, @@ -137,11 +135,7 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { // This corrects non-linear regions of the ADC range with a LUT, so it's a better reading than raw int voltage; - #ifdef CONFIG_IDF_TARGET_ESP32P4 - voltage = 0; - #else adc_cali_raw_to_voltage(calibration, adc_reading, &voltage); - #endif #if defined(ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED) && ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED if (calibration_scheme == ADC_CALI_SCHEME_VER_CURVE_FITTING) { diff --git a/ports/espressif/common-hal/espnow/ESPNow.c b/ports/espressif/common-hal/espnow/ESPNow.c index 79bded96fb41d..ae11db250321c 100644 --- a/ports/espressif/common-hal/espnow/ESPNow.c +++ b/ports/espressif/common-hal/espnow/ESPNow.c @@ -56,7 +56,7 @@ typedef struct { // Callback triggered when a sent packet is acknowledged by the peer (or not). // Just count the number of responses and number of failures. // These are used in the send() logic. -static void send_cb(const uint8_t *mac, esp_now_send_status_t status) { +static void send_cb(const esp_now_send_info_t *tx_info, esp_now_send_status_t status) { espnow_obj_t *self = MP_STATE_PORT(espnow_singleton); if (status == ESP_NOW_SEND_SUCCESS) { self->send_success++; diff --git a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c index 7721b5e197f49..52c4b67bf4efe 100644 --- a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +++ b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c @@ -18,7 +18,7 @@ #include "common-hal/microcontroller/Pin.h" #include "py/runtime.h" -#include "driver/gpio.h" +#include /* * Current pin limitations for ESP32-S2 ParallelBus: diff --git a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h index 4724ba7231a4e..114a1e527a6d5 100644 --- a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h +++ b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h @@ -8,7 +8,7 @@ #include "common-hal/digitalio/DigitalInOut.h" -#include "esp-idf/components/esp_lcd/include/esp_lcd_panel_io.h" +#include typedef struct { mp_obj_base_t base; diff --git a/ports/espressif/esp-idf b/ports/espressif/esp-idf index f50ec8ecdb31f..f4fddd2d05b44 160000 --- a/ports/espressif/esp-idf +++ b/ports/espressif/esp-idf @@ -1 +1 @@ -Subproject commit f50ec8ecdb31f681e6a778f145de95f849c1089d +Subproject commit f4fddd2d05b44d1d606b546b596d17de0a73e9eb diff --git a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv index 6d78fe8af5916..44121812ea2bf 100644 --- a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv @@ -3,6 +3,5 @@ # partition_table, data, table, 0x8000, 4K nvs, data, nvs, 0x9000, 20K otadata, data, ota, 0xe000, 8K -ota_0, app, ota_0, 0x10000, 2048K -ota_1, app, ota_1, 0x210000, 2048K +ota_0, app, ota_0, 0x10000, 4096K user_fs, data, fat, 0x410000, 4032K diff --git a/ports/espressif/esp-idf-config/sdkconfig.defaults b/ports/espressif/esp-idf-config/sdkconfig.defaults index dd766675136d9..3c174057ceb19 100644 --- a/ports/espressif/esp-idf-config/sdkconfig.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig.defaults @@ -20,6 +20,12 @@ CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y CONFIG_GPTIMER_ISR_IRAM_SAFE=y # end of GPTimer Configuration +# +# Touch Configuration +# +CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN=y +# end of Touch Configuration + # end of Driver Configurations # diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index 42bf3418f9639..b632c5dfd6fe1 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -54,6 +54,8 @@ CIRCUITPY_HASHLIB_MBEDTLS_ONLY = 0 CIRCUITPY_PORT_SERIAL = 1 +CIRCUITPY_LIB_TLSF = 0 + # These modules are implemented in ports//common-hal: CIRCUITPY__EVE ?= 1 CIRCUITPY_ALARM ?= 1 diff --git a/ports/espressif/peripherals/pins.h b/ports/espressif/peripherals/pins.h index f89855e308f59..f185cee92c437 100644 --- a/ports/espressif/peripherals/pins.h +++ b/ports/espressif/peripherals/pins.h @@ -14,7 +14,7 @@ #include "components/hal/include/hal/gpio_types.h" #include "components/hal/include/hal/adc_types.h" -#include "components/hal/include/hal/touch_sensor_types.h" +#include "components/hal/include/hal/touch_sensor_legacy_types.h" typedef struct { mp_obj_base_t base; diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 8c838a41218a3..76ee8a1d72bce 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -62,6 +62,10 @@ CFLAGS += -DCIRCUITPY_FULL_BUILD=$(CIRCUITPY_FULL_BUILD) # increased build time CIRCUITPY_MESSAGE_COMPRESSION_LEVEL ?= 9 +# By default, use our copy of TLSF. Some vendor SDKs may provide their own +# implementation of TLSF, which can be used instead by setting CIRCUITPY_LIB_TLSF=0. +CIRCUITPY_LIB_TLSF ?= 1 + # Reduce the size of in-flash properties. Requires support in the .ld linker # file, so not enabled by default. CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 0 diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 0ecc6ea3acfe6..21bda334131c7 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -1,6 +1,5 @@ SRC_SUPERVISOR = \ main.c \ - lib/tlsf/tlsf.c \ supervisor/port.c \ supervisor/shared/background_callback.c \ supervisor/shared/board.c \ @@ -20,6 +19,10 @@ SRC_SUPERVISOR = \ supervisor/shared/translate/translate.c \ supervisor/shared/workflow.c \ +ifeq ($(CIRCUITPY_LIB_TLSF),1) +SRC_SUPERVISOR += lib/tlsf/tlsf.c +endif + # For tlsf CFLAGS += -D_DEBUG=0 From c25ce600013058817b08f7838eab61e0ab0be490 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 11 Sep 2025 16:47:23 -0700 Subject: [PATCH 156/208] Stop using our own memcpy. Enhance decode backtrace script. --- ports/espressif/Makefile | 1 - .../esp-idf-config/sdkconfig-debug.defaults | 26 ++++++++++++ .../esp-idf-config/sdkconfig.defaults | 7 ++++ ports/espressif/tools/decode_backtrace.py | 41 ++++++++++++++----- py/circuitpy_defns.mk | 1 - 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 157b59d9aaa0f..5e4256749ee2e 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -290,7 +290,6 @@ LDFLAGS += \ -Tesp32c6.rom.net80211.ld \ -Tesp32c6.rom.libc.ld \ -Tesp32c6.rom.newlib.ld \ - -Tesp32c6.rom.spiflash.ld \ -Tesp32c6.rom.coexist.ld \ -Tesp32c6.rom.heap.ld \ -Tesp32c6.rom.systimer.ld \ diff --git a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults index a9c8e34e54706..368ba81bb4aa7 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults @@ -7,6 +7,21 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y # end of Compiler options +# Bootloader config +# +# +# Log +# +# +# Format +# +CONFIG_BOOTLOADER_LOG_COLORS=y +# end of Format + +# end of Log + +# end of Bootloader config + # # Component config # @@ -19,6 +34,17 @@ CONFIG_ESP_CONSOLE_SECONDARY_NONE=y # CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set # end of ESP System Settings +# +# Log +# +# +# Format +# +CONFIG_LOG_COLORS=y +# end of Format + +# end of Log + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig.defaults b/ports/espressif/esp-idf-config/sdkconfig.defaults index 3c174057ceb19..5c4d6a31a62c1 100644 --- a/ports/espressif/esp-idf-config/sdkconfig.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig.defaults @@ -65,6 +65,13 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 CONFIG_FREERTOS_HZ=1000 # end of Kernel +# +# LibC +# +# end of LWIP +CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS=y +# end of LibC + # # LWIP # diff --git a/ports/espressif/tools/decode_backtrace.py b/ports/espressif/tools/decode_backtrace.py index 024e636207ec8..1733c69b5bb57 100644 --- a/ports/espressif/tools/decode_backtrace.py +++ b/ports/espressif/tools/decode_backtrace.py @@ -12,20 +12,39 @@ board = sys.argv[1] print(board) +elfs = [ + f"build-{board}/firmware.elf", + "/home/tannewt/Downloads/esp-rom-elfs-20241011/esp32c6_rev0_rom.elf", +] + while True: + print('"Backtrace:" or "Stack memory:". CTRL-D to finish multiline paste') addresses = input("? ") if addresses.startswith("Backtrace:"): addresses = addresses[len("Backtrace:") :] + addresses = addresses.strip().split() + addresses = [address.split(":")[0] for address in addresses] if addresses.startswith("Stack memory:"): - addresses = addresses[len("Stack memory:") :] - addresses = addresses.strip().split() - addresses = [address.split(":")[0] for address in addresses] + addresses = [] + extra_lines = sys.stdin.readlines() + for line in extra_lines: + if not line.strip(): + continue + addresses.extend(line.split(":")[1].strip().split()) for address in addresses: - result = subprocess.run( - ["xtensa-esp32s2-elf-addr2line", "-aipfe", "build-{}/firmware.elf".format(board)] - + [address], - capture_output=True, - ) - stdout = result.stdout.decode("utf-8") - if "?? ??" not in stdout: - print(stdout.strip()) + if address == "0xa5a5a5a5": + # Skip stack fill value. + continue + for elf in elfs: + result = subprocess.run( + ["riscv32-esp-elf-addr2line", "-aipfe", elf, address], + capture_output=True, + ) + stdout = result.stdout.decode("utf-8") + if not stdout: + continue + if "?? ??" not in stdout: + print(stdout.strip()) + break + + print("loop") diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index d6569bc39bd8e..f3d25f6270cef 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -992,7 +992,6 @@ endif # Sources used in all ports except unix. SRC_CIRCUITPY_COMMON = \ - shared/libc/string0.c \ shared/readline/readline.c \ lib/oofatfs/ff.c \ lib/oofatfs/ffunicode.c \ From f98014475dd2e91b29bc817f0d8c6afd4d43f114 Mon Sep 17 00:00:00 2001 From: Derek Daniels Date: Mon, 15 Sep 2025 14:38:14 -0400 Subject: [PATCH 157/208] [ports/espressif] esp-idf v5.5 changes --- ports/espressif/Makefile | 8 +++- .../espressif/common-hal/alarm/pin/PinAlarm.c | 40 +++++++++---------- .../common-hal/digitalio/DigitalInOut.c | 24 ++++++----- .../common-hal/microcontroller/Pin.c | 5 +-- ports/espressif/common-hal/wifi/__init__.c | 7 +++- 5 files changed, 47 insertions(+), 37 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 5e4256749ee2e..a080939e220a9 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -672,7 +672,7 @@ ifneq ($(IDF_TARGET),esp32p4) BINARY_BLOBS = esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libphy.a endif ifneq ($(CIRCUITPY_WIFI),0) - BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, $(BINARY_WIFI_BLOBS)) + BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, $(BINARY_WIFI_BLOBS)) ifneq ($(IDF_TARGET),esp32c2) BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, libmesh.a libwapi.a) endif @@ -683,6 +683,12 @@ BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/librtc.a endif ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log newlib nvs_flash pthread soc spi_flash vfs esp_vfs_console +NEEDS_COEX = $(CIRCUITPY_BLEIO_NATIVE) + $(CIRCUITPY_WIFI) +ifneq ($(NEEDS_COEX),0) + # esp_system_include_startup_funcs requires coexist as well BT regardless of wifi + BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a + ESP_IDF_COMPONENTS_LINK += esp_coex +endif ifneq ($(CIRCUITPY_WIFI),0) ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy endif diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index cecb91fe46df9..2b09c630925c0 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -360,38 +360,36 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) { mp_raise_ValueError(MP_ERROR_TEXT("Can only alarm on RTC IO from deep sleep.")); } - for (size_t i = 0; i < 64; i++) { - uint64_t mask = 1ull << i; + for (gpio_num_t pin = 0; pin < SOC_GPIO_PIN_COUNT; pin++) { + uint64_t mask = 1ULL << pin; bool high = (high_alarms & mask) != 0; bool low = (low_alarms & mask) != 0; bool pull = (pull_pins & mask) != 0; if (!(high || low)) { continue; } - if (rtc_gpio_is_valid_gpio(i)) { + if (rtc_gpio_is_valid_gpio(pin)) { #ifdef SOC_PM_SUPPORT_RTC_PERIPH_PD - rtc_gpio_deinit(i); + rtc_gpio_deinit(pin); #endif } - gpio_int_type_t interrupt_mode = GPIO_INTR_DISABLE; - gpio_pull_mode_t pull_mode = GPIO_FLOATING; - if (high) { - interrupt_mode = GPIO_INTR_HIGH_LEVEL; - pull_mode = GPIO_PULLDOWN_ONLY; - } - if (low) { - interrupt_mode = GPIO_INTR_LOW_LEVEL; - pull_mode = GPIO_PULLUP_ONLY; - } - gpio_set_direction(i, GPIO_MODE_DEF_INPUT); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[i], PIN_FUNC_GPIO); + gpio_set_direction(pin, GPIO_MODE_INPUT); if (pull) { - gpio_set_pull_mode(i, pull_mode); + if (high) { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_PULLDOWN_ONLY)); + } else { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_PULLUP_ONLY)); + } + } else { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_FLOATING)); } - never_reset_pin_number(i); - // Sets interrupt type and wakeup bits. - gpio_wakeup_enable(i, interrupt_mode); - gpio_intr_enable(i); + gpio_int_type_t intr = GPIO_INTR_DISABLE; + if (high) intr = GPIO_INTR_HIGH_LEVEL; + if (low) intr = GPIO_INTR_LOW_LEVEL; + never_reset_pin_number(pin); + gpio_wakeup_enable(pin, intr); + gpio_set_intr_type(pin, intr); + gpio_intr_enable(pin); } // Wait for any pulls to settle. mp_hal_delay_ms(50); diff --git a/ports/espressif/common-hal/digitalio/DigitalInOut.c b/ports/espressif/common-hal/digitalio/DigitalInOut.c index ed537419405b3..e4272ba1ff5ff 100644 --- a/ports/espressif/common-hal/digitalio/DigitalInOut.c +++ b/ports/espressif/common-hal/digitalio/DigitalInOut.c @@ -11,8 +11,11 @@ #include "hal/gpio_hal.h" static bool _pin_is_input(uint8_t pin_number) { - const uint32_t iomux = READ_PERI_REG(GPIO_PIN_MUX_REG[pin_number]); - return (iomux & FUN_IE) != 0; + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)pin_number, &config) != ESP_OK) { + return false; + } + return config.ie; } void digitalio_digitalinout_preserve_for_deep_sleep(size_t n_dios, digitalio_digitalinout_obj_t *preserve_dios[]) { @@ -113,10 +116,12 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( digitalio_digitalinout_obj_t *self) { - if (GPIO_HAL_GET_HW(GPIO_PORT_0)->pin[self->pin->number].pad_driver == 1) { + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)self->pin->number, &config) != ESP_OK) { + // Should it fail closed or open? return DRIVE_MODE_OPEN_DRAIN; } - return DRIVE_MODE_PUSH_PULL; + return config.od ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; } digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( @@ -134,11 +139,10 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( digitalio_digitalinout_obj_t *self) { - gpio_num_t gpio_num = self->pin->number; - if (REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU)) { - return PULL_UP; - } else if (REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD)) { - return PULL_DOWN; + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)self->pin->number, &config) != ESP_OK) { + // Should it fail closed or open? + return PULL_NONE; } - return PULL_NONE; + return config.pd ? PULL_DOWN : PULL_UP; } diff --git a/ports/espressif/common-hal/microcontroller/Pin.c b/ports/espressif/common-hal/microcontroller/Pin.c index 70912afb545b4..e14a3366691d0 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.c +++ b/ports/espressif/common-hal/microcontroller/Pin.c @@ -370,9 +370,8 @@ void reset_all_pins(void) { gpio_deep_sleep_hold_dis(); #endif - for (uint8_t i = 0; i < GPIO_PIN_COUNT; i++) { - uint32_t iomux_address = GPIO_PIN_MUX_REG[i]; - if (iomux_address == 0 || + for (gpio_num_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) { + if (!GPIO_IS_VALID_GPIO(i) || _never_reset(i) || _skip_reset_once(i) || _preserved_pin(i)) { diff --git a/ports/espressif/common-hal/wifi/__init__.c b/ports/espressif/common-hal/wifi/__init__.c index 1a4c014bfbc5b..0eacd2bab3ec0 100644 --- a/ports/espressif/common-hal/wifi/__init__.c +++ b/ports/espressif/common-hal/wifi/__init__.c @@ -146,8 +146,8 @@ void common_hal_wifi_init(bool user_initiated) { common_hal_wifi_radio_obj.base.type = &wifi_radio_type; if (!wifi_ever_inited) { - ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_netif_init()); wifi_ever_inited = true; } @@ -175,6 +175,7 @@ void common_hal_wifi_init(bool user_initiated) { &self->handler_instance_got_ip)); wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t result = esp_wifi_init(&config); #ifdef CONFIG_ESP32_WIFI_NVS_ENABLED // Generally we don't use this because we store ssid and passwords ourselves in the filesystem. esp_err_t err = nvs_flash_init(); @@ -185,8 +186,10 @@ void common_hal_wifi_init(bool user_initiated) { err = nvs_flash_init(); } ESP_ERROR_CHECK(err); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); + #else + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); #endif - esp_err_t result = esp_wifi_init(&config); if (result == ESP_ERR_NO_MEM) { if (gc_alloc_possible()) { mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Failed to allocate Wifi memory")); From bc44db821442fcb5f5fcf5b8f1cef59d8f0e349b Mon Sep 17 00:00:00 2001 From: Derek Daniels Date: Mon, 15 Sep 2025 14:41:06 -0400 Subject: [PATCH 158/208] [ports/espressif] support for esp32c61 --- ports/espressif/Makefile | 28 +++++++- .../espressif_esp32c61_devkitc_1_n8r2/board.c | 9 +++ .../mpconfigboard.h | 15 ++++ .../mpconfigboard.mk | 13 ++++ .../espressif_esp32c61_devkitc_1_n8r2/pins.c | 48 +++++++++++++ .../sdkconfig | 14 ++++ .../common-hal/analogbufio/BufferedIn.c | 2 +- .../espressif/common-hal/analogio/AnalogIn.c | 2 + .../common-hal/microcontroller/Pin.c | 23 ++++++ .../common-hal/microcontroller/Processor.c | 6 +- .../common-hal/microcontroller/__init__.c | 5 +- .../sdkconfig-esp32c61.defaults | 54 ++++++++++++++ ports/espressif/mpconfigport.h | 2 +- ports/espressif/mpconfigport.mk | 42 +++++++++++ ports/espressif/peripherals/esp32c61/pins.c | 38 ++++++++++ ports/espressif/peripherals/esp32c61/pins.h | 72 +++++++++++++++++++ ports/espressif/peripherals/pins.h | 2 + ports/espressif/supervisor/port.c | 7 +- ports/espressif/tools/build_memory_info.py | 6 ++ 19 files changed, 381 insertions(+), 7 deletions(-) create mode 100644 ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c create mode 100644 ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h create mode 100644 ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk create mode 100644 ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c create mode 100644 ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig create mode 100644 ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults create mode 100644 ports/espressif/peripherals/esp32c61/pins.c create mode 100644 ports/espressif/peripherals/esp32c61/pins.h diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index a080939e220a9..930cdd961820b 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -8,6 +8,8 @@ include ../../py/circuitpy_mkenv.mk ifeq ($(IDF_TARGET),esp32s3) BT_IDF_TARGET = esp32c3 +else ifeq ($(IDF_TARGET),esp32c61) +BT_IDF_TARGET = esp32c6 else BT_IDF_TARGET = $(IDF_TARGET) endif @@ -296,6 +298,23 @@ LDFLAGS += \ -Tesp32c6.rom.wdt.ld +CHIP_COMPONENTS = \ + esp_driver_tsens + +else ifeq ($(IDF_TARGET),esp32c61) +LDFLAGS += \ + -Tesp32c61.rom.phy.ld \ + -Tesp32c61.rom.pp.ld \ + -Tesp32c61.rom.net80211.ld \ + -Tesp32c61.rom.libc.ld \ + -Tesp32c61.rom.newlib.ld \ + -Tesp32c61.rom.version.ld \ + -Tesp32c61.rom.coexist.ld \ + -Tesp32c61.rom.heap.ld \ + -Tesp32c61.rom.systimer.ld \ + -Tesp32c61.rom.wdt.ld + + CHIP_COMPONENTS = \ esp_driver_tsens @@ -360,6 +379,8 @@ else ifeq ($(IDF_TARGET),esp32c3) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C3 else ifeq ($(IDF_TARGET),esp32c6) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C6 +else ifeq ($(IDF_TARGET),esp32c61) +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C61 else ifeq ($(IDF_TARGET),esp32p4) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32P4 else ifeq ($(IDF_TARGET),esp32h2) @@ -698,6 +719,7 @@ ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) BLE_IMPL_esp32c2 := libble BLE_IMPL_esp32c3 := esp32c3 BLE_IMPL_esp32c6 := libble + BLE_IMPL_esp32c61 := libble BLE_IMPL_esp32h2 := libble BLE_IMPL = $(BLE_IMPL_$(IDF_TARGET)) @@ -716,8 +738,8 @@ ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) ifeq ($(BLE_IMPL),libble) BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libbtbb.a - ifeq ($(IDF_TARGET),esp32c6) - BINARY_BLOBS += esp-idf/components/bt/controller/lib_$(IDF_TARGET)/$(IDF_TARGET)-bt-lib/$(IDF_TARGET)/libble_app.a + ifeq ($(BT_IDF_TARGET),esp32c6) + BINARY_BLOBS += esp-idf/components/bt/controller/lib_$(BT_IDF_TARGET)/$(BT_IDF_TARGET)-bt-lib/$(IDF_TARGET)/libble_app.a else BINARY_BLOBS += esp-idf/components/bt/controller/lib_$(IDF_TARGET)/$(IDF_TARGET)-bt-lib/libble_app.a endif @@ -785,6 +807,8 @@ else ifeq ($(IDF_TARGET),esp32c3) BOOTLOADER_OFFSET = 0x0 else ifeq ($(IDF_TARGET),esp32c6) BOOTLOADER_OFFSET = 0x0 +else ifeq ($(IDF_TARGET),esp32c61) +BOOTLOADER_OFFSET = 0x0 else ifeq ($(IDF_TARGET),esp32p4) BOOTLOADER_OFFSET = 0x2000 else ifeq ($(IDF_TARGET),esp32s3) diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c new file mode 100644 index 0000000000000..a3a9eec047145 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h new file mode 100644 index 0000000000000..d901bfb37ba28 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-C61-DevKitC-1-N8R2" +#define MICROPY_HW_MCU_NAME "ESP32C61" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO10) +#define DEFAULT_UART_BUS_TX (&pin_GPIO11) diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk new file mode 100644 index 0000000000000..1092a874a6868 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk @@ -0,0 +1,13 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x00C61001 + +IDF_TARGET = esp32c61 +IDF_TARGET_ARCH = riscv + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c new file mode 100644 index 0000000000000..901e52166576b --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_IO28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_IO29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig new file mode 100644 index 0000000000000..e962866216039 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.c b/ports/espressif/common-hal/analogbufio/BufferedIn.c index aac7ad28daf25..20c5c060574aa 100644 --- a/ports/espressif/common-hal/analogbufio/BufferedIn.c +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.c @@ -33,7 +33,7 @@ #elif defined(CONFIG_IDF_TARGET_ESP32S2) #define ADC_RESULT_BYTE 2 #define ADC_CONV_LIMIT_EN 0 -#elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) +#elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32C61) #define ADC_RESULT_BYTE 4 #define ADC_CONV_LIMIT_EN 0 #elif defined(CONFIG_IDF_TARGET_ESP32S3) diff --git a/ports/espressif/common-hal/analogio/AnalogIn.c b/ports/espressif/common-hal/analogio/AnalogIn.c index b4039b3d32dd8..34cd5b846cf22 100644 --- a/ports/espressif/common-hal/analogio/AnalogIn.c +++ b/ports/espressif/common-hal/analogio/AnalogIn.c @@ -32,6 +32,8 @@ #define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32C6) #define DATA_WIDTH ADC_BITWIDTH_12 +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32P4) #define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32S2) diff --git a/ports/espressif/common-hal/microcontroller/Pin.c b/ports/espressif/common-hal/microcontroller/Pin.c index e14a3366691d0..922cde763e363 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.c +++ b/ports/espressif/common-hal/microcontroller/Pin.c @@ -146,6 +146,29 @@ static const uint64_t pin_mask_reset_forbidden = #endif #endif // ESP32C6 + #if defined(CONFIG_IDF_TARGET_ESP32C61) + // Never ever reset pins used to communicate with SPI flash. + GPIO_SEL_15 | // SPICS0 (flash CS#) + GPIO_SEL_16 | // SPIQ (MISO/SIO1) + GPIO_SEL_17 | // SPIWP (WP#/SIO2) + GPIO_SEL_19 | // SPIHD (HOLD#/SIO3) + GPIO_SEL_20 | // SPICLK (CLK) + GPIO_SEL_21 | // SPID (MOSI/SIO0) + #if CIRCUITPY_ESP_USB_SERIAL_JTAG + // Never ever reset serial/JTAG communication pins. + GPIO_SEL_12 | // USB D- + GPIO_SEL_13 | // USB D+ + #endif + #if defined(CONFIG_SPIRAM) + GPIO_SEL_14 | // SPICS1 (PSRAM CS#); keep if PSRAM in use + #endif + #if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT && CONFIG_ESP_CONSOLE_UART_NUM == 0 + // Never reset debug UART/console pins. + GPIO_SEL_10 | + GPIO_SEL_11 | + #endif + #endif // ESP32C6 + #if defined(CONFIG_IDF_TARGET_ESP32H2) // Never ever reset pins used to communicate with the in-package SPI flash. GPIO_SEL_15 | diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 8a6a14c0236f5..0056465f1c5cd 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -59,7 +59,7 @@ uint32_t common_hal_mcu_processor_get_frequency(void) { // If the requested frequency is not supported by the hardware, return the next lower supported frequency static uint32_t get_valid_cpu_frequency(uint32_t requested_freq_mhz) { - #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) uint32_t valid_cpu_frequencies[] = {20, 40, 80, 160}; #elif defined(CONFIG_IDF_TARGET_ESP32C2) uint32_t valid_cpu_frequencies[] = {20, 40, 80, 120}; @@ -126,6 +126,8 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_0_REG); #elif defined(CONFIG_IDF_TARGET_ESP32C2) uint32_t mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA0_REG); + #elif defined(CONFIG_IDF_TARGET_ESP32C61) + uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS0_REG); #else uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_0_REG); #endif @@ -145,6 +147,8 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_1_REG); #elif defined(CONFIG_IDF_TARGET_ESP32C2) mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA1_REG); + #elif defined(CONFIG_IDF_TARGET_ESP32C61) + mac_address_part = REG_READ(EFUSE_RD_MAC_SYS1_REG); #else mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_1_REG); #endif diff --git a/ports/espressif/common-hal/microcontroller/__init__.c b/ports/espressif/common-hal/microcontroller/__init__.c index 918366b8933c4..d23afce4d999e 100644 --- a/ports/espressif/common-hal/microcontroller/__init__.c +++ b/ports/espressif/common-hal/microcontroller/__init__.c @@ -36,6 +36,9 @@ #elif defined(CONFIG_IDF_TARGET_ESP32C6) #include "soc/lp_aon_reg.h" #include "esp32c6/rom/rtc.h" +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#include "soc/lp_aon_reg.h" +#include "esp32c61/rom/rtc.h" #elif defined(CONFIG_IDF_TARGET_ESP32P4) #include "esp32p4/rom/rtc.h" #elif defined(CONFIG_IDF_TARGET_ESP32S2) @@ -83,7 +86,7 @@ void common_hal_mcu_enable_interrupts(void) { void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { switch (runmode) { case RUNMODE_UF2: - #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) mp_arg_error_invalid(MP_QSTR_run_mode); #else // 0x11F2 is APP_REQUEST_UF2_RESET_HINT & is defined by TinyUF2 diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults new file mode 100644 index 0000000000000..85dde905f3caa --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults @@ -0,0 +1,54 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_NVS_PERSIST=y +# +# Memory Settings +# +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=20 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +# end of Memory Settings + +CONFIG_BT_NIMBLE_EXT_ADV=y +# end of NimBLE Options + +# end of Bluetooth + +# +# Driver Configurations +# +# +# PCNT Configuration +# +CONFIG_PCNT_CTRL_FUNC_IN_IRAM=y +# end of PCNT Configuration + +# end of Driver Configurations + +# +# PHY +# +CONFIG_ESP_PHY_ENABLE_USB=y +# end of PHY + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 +# end of Wi-Fi + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index 712eb67f1f42a..031676cf4d8ae 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -27,7 +27,7 @@ // Nearly all boards have this because it is used to enter the ROM bootloader. #ifndef CIRCUITPY_BOOT_BUTTON - #if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) + #if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C61) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) #elif !defined(CONFIG_IDF_TARGET_ESP32) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index b632c5dfd6fe1..572e0579ef00a 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -17,6 +17,9 @@ CROSS_COMPILE = riscv32-esp-elf- else ifeq ($(IDF_TARGET),esp32c6) IDF_TARGET_ARCH = riscv CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32c61) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- else ifeq ($(IDF_TARGET),esp32h2) IDF_TARGET_ARCH = riscv CROSS_COMPILE = riscv32-esp-elf- @@ -201,6 +204,45 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0 CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 +#### esp32c6 ########################################################## +else ifeq ($(IDF_TARGET),esp32c61) +# Modules +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESPULP = 0 +CIRCUITPY_MEMORYMAP = 0 +CIRCUITPY_RGBMATRIX = 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 + +# No space for this +CIRCUITPY_AUDIOBUSIO = 0 + +# No I80 support from the IDF +CIRCUITPY_PARALLELDISPLAYBUS = 0 + +# No SDMMC +CIRCUITPY_SDIOIO = 0 + +CIRCUITPY_TOUCHIO ?= 1 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +# Features +CIRCUITPY_USB_DEVICE = 0 +CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 + +# No TWAI on chip +CIRCUITPY_CANIO = 0 + +# No RMT on chip +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_RGBMATRIX = 0 + +# No PCNT on chip +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 + #### esp32h2 ########################################################## else ifeq ($(IDF_TARGET),esp32h2) # Modules diff --git a/ports/espressif/peripherals/esp32c61/pins.c b/ports/espressif/peripherals/esp32c61/pins.c new file mode 100644 index 0000000000000..a32e1e8da9856 --- /dev/null +++ b/ports/espressif/peripherals/esp32c61/pins.c @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +const mcu_pin_obj_t pin_GPIO0 = PIN(0, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_1, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_2, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_3, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO6 = PIN(6, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO7 = PIN(7, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO8 = PIN(8, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO9 = PIN(9, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO10 = PIN(10, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO11 = PIN(11, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO15 = PIN(15, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO16 = PIN(16, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO17 = PIN(17, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO18 = PIN(18, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO19 = PIN(19, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO20 = PIN(20, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO21 = PIN(21, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO22 = PIN(22, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO23 = PIN(23, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO24 = PIN(24, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO25 = PIN(25, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO26 = PIN(26, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO27 = PIN(27, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO28 = PIN(28, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO29 = PIN(29, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/esp32c61/pins.h b/ports/espressif/peripherals/esp32c61/pins.h new file mode 100644 index 0000000000000..908c9fe29f0e2 --- /dev/null +++ b/ports/espressif/peripherals/esp32c61/pins.h @@ -0,0 +1,72 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// DO NOT include this file directly. +// Use shared-bindings/microcontroller/Pin.h instead. +// This ensures that all necessary includes are already included. + +#pragma once + +#define GPIO0_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO0; +#define GPIO1_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO1; +#define GPIO2_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO2; +#define GPIO3_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO3; +#define GPIO4_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO4; +#define GPIO5_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO5; +#define GPIO6_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO6; +#define GPIO7_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO7; +#define GPIO8_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO8; +#define GPIO9_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO9; +#define GPIO10_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO10; +#define GPIO11_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO11; +#define GPIO12_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO12; +#define GPIO13_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO13; +#define GPIO14_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO14; +#define GPIO15_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO15; +#define GPIO16_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO16; +#define GPIO17_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO17; +#define GPIO18_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO18; +#define GPIO19_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO19; +#define GPIO20_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO20; +#define GPIO21_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO21; +#define GPIO22_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO22; +#define GPIO23_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO23; +#define GPIO24_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO24; +#define GPIO25_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO25; +#define GPIO26_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO26; +#define GPIO27_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO27; +#define GPIO28_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO28; +#define GPIO29_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO29; diff --git a/ports/espressif/peripherals/pins.h b/ports/espressif/peripherals/pins.h index f185cee92c437..bbe42be1bcae2 100644 --- a/ports/espressif/peripherals/pins.h +++ b/ports/espressif/peripherals/pins.h @@ -52,6 +52,8 @@ extern const mp_obj_type_t mcu_pin_type; #include "esp32c3/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32C6) #include "esp32c6/pins.h" +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#include "esp32c61/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32P4) #include "esp32p4/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32H2) diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index 48ae29ab4f927..72c92c98baea2 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -216,6 +216,11 @@ static void _never_reset_spi_ram_flash(void) { never_reset_pin_number(bootloader_flash_get_wp_pin()); } #endif // CONFIG_IDF_TARGET_ESP32 + #if defined(CONFIG_IDF_TARGET_ESP32C61) + #if defined(CONFIG_SPIRAM) + common_hal_never_reset_pin(&pin_GPIO14); + #endif + #endif } safe_mode_t port_init(void) { @@ -271,7 +276,7 @@ safe_mode_t port_init(void) { common_hal_never_reset_pin(&pin_GPIO40); common_hal_never_reset_pin(&pin_GPIO41); common_hal_never_reset_pin(&pin_GPIO42); - #elif defined(CONFIG_IDF_TARGET_ESP32P4) + #elif defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32C61) common_hal_never_reset_pin(&pin_GPIO3); common_hal_never_reset_pin(&pin_GPIO4); common_hal_never_reset_pin(&pin_GPIO5); diff --git a/ports/espressif/tools/build_memory_info.py b/ports/espressif/tools/build_memory_info.py index 9a3c55501388e..cd9cc91427116 100644 --- a/ports/espressif/tools/build_memory_info.py +++ b/ports/espressif/tools/build_memory_info.py @@ -61,6 +61,12 @@ ("LP SRAM", (0x5000_0000,), 16 * 1024), ("HP SRAM", (0x4080_0000,), 512 * 1024), ], + "esp32c61": [ + # Name, Start, Length + ("LP SRAM", (0x5000_0000,), 16 * 1024), + ("HP SRAM", (0x4080_0000,), 320 * 1024), + ("PSRAM", (0x4200_0000,), 2 * 1024 * 1024), + ], "esp32h2": [ # Name, Start, Length ("LP SRAM", (0x5000_0000,), 4 * 1024), From cdd423b01a5d7b02fd5eea19bf871fb38c28195e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 17 Sep 2025 12:02:23 -0700 Subject: [PATCH 159/208] Make string0 use configurable --- ports/espressif/mpconfigport.mk | 2 ++ py/circuitpy_defns.mk | 4 ++++ py/circuitpy_mpconfig.mk | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index 572e0579ef00a..f133e86c6e068 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -59,6 +59,8 @@ CIRCUITPY_PORT_SERIAL = 1 CIRCUITPY_LIB_TLSF = 0 +CIRCUITPY_LIBC_STRING0 = 0 + # These modules are implemented in ports//common-hal: CIRCUITPY__EVE ?= 1 CIRCUITPY_ALARM ?= 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index f3d25f6270cef..f4ac2350ffbf1 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -1003,6 +1003,10 @@ SRC_CIRCUITPY_COMMON = \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c +ifeq ($(CIRCUITPY_LIBC_STRING0),1) +SRC_CIRCUITPY_COMMON += shared/libc/string0.c +endif + ifeq ($(CIRCUITPY_QRIO),1) SRC_CIRCUITPY_COMMON += lib/quirc/lib/decode.c lib/quirc/lib/identify.c lib/quirc/lib/quirc.c lib/quirc/lib/version_db.c $(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-type-limits -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 76ee8a1d72bce..09ef4361427da 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -66,6 +66,11 @@ CIRCUITPY_MESSAGE_COMPRESSION_LEVEL ?= 9 # implementation of TLSF, which can be used instead by setting CIRCUITPY_LIB_TLSF=0. CIRCUITPY_LIB_TLSF ?= 1 +# By default, use our copy of string0 (memcpy and friends) because it is optimized. Some vendor SDKs +# or ROMs may provide their own implementation of string0, which can be used instead by setting +# CIRCUITPY_LIBC_STRING0=0. +CIRCUITPY_LIBC_STRING0 ?= 1 + # Reduce the size of in-flash properties. Requires support in the .ld linker # file, so not enabled by default. CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 0 From 6ebd5bbfa31965b14a78d95b14ede21c362d31be Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 23 Sep 2025 11:16:15 -0700 Subject: [PATCH 160/208] Fix PID check and C3 build --- ports/espressif/Makefile | 1 + tools/ci_check_duplicate_usb_vid_pid.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 930cdd961820b..0f3ff1ca7083a 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -277,6 +277,7 @@ CHIP_COMPONENTS = \ else ifeq ($(IDF_TARGET),esp32c3) LDFLAGS += \ -Tesp32c3.rom.newlib.ld \ + -Tesp32c3.rom.libc.ld \ -Tesp32c3.rom.version.ld \ -Tesp32c3.rom.eco3_bt_funcs.ld \ -Tesp32c3.rom.eco3.ld \ diff --git a/tools/ci_check_duplicate_usb_vid_pid.py b/tools/ci_check_duplicate_usb_vid_pid.py index 5361914af199b..38cce0f28be94 100644 --- a/tools/ci_check_duplicate_usb_vid_pid.py +++ b/tools/ci_check_duplicate_usb_vid_pid.py @@ -104,7 +104,7 @@ def check_vid_pid(files, clusterlist): """ usb_pattern = re.compile( - r"^CIRCUITPY_USB_DEVICE\s*=\s*0$|^IDF_TARGET = (esp32|esp32c2|esp32c3|esp32c6|esp32h2|esp32p4)$|^MCU_SERIES = MG24$", + r"^CIRCUITPY_USB_DEVICE\s*=\s*0$|^IDF_TARGET = (esp32|esp32c2|esp32c3|esp32c5|esp32c6|esp32c61|esp32h2|esp32p4)$|^MCU_SERIES = MG24$", flags=re.M, ) From 680fb207d141afe784ca0976ee27dcaa51e3b566 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 23 Sep 2025 15:31:15 -0700 Subject: [PATCH 161/208] Limit cryptography version to IDF limit --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 261a5cc2c7fe8..fb931079c524e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -25,7 +25,7 @@ intelhex # for building & testing natmods pyelftools -cryptography +cryptography<45 # for web workflow minify minify_html From 8190b409d20cfa8a10b06299d9b45908aa173d51 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 23 Sep 2025 16:15:32 -0700 Subject: [PATCH 162/208] Make room of IDF in S2 RTC slow memory --- ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults index 5c748bd0e6f02..101f90f9fa4fe 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults @@ -55,7 +55,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_FSM=y CONFIG_ULP_COPROC_TYPE_RISCV=y # Note: enabling both ULPs simultaneously only works due to a modification of adafruit/esp-idf # (see adafruit/esp-idf/pull/16) until espressif/esp-idf/issues/12999 is fixed. -CONFIG_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ULP_COPROC_RESERVE_MEM=8144 # end of Ultra Low Power (ULP) Co-processor # From 2fd8589e2876adffa69f647ace904f3818e4e39e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 24 Sep 2025 12:04:59 -0700 Subject: [PATCH 163/208] Fix C2, H2 and S3 builds --- ports/espressif/Makefile | 8 ++++++-- ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 0f3ff1ca7083a..b759fe3c0052a 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -205,7 +205,6 @@ CFLAGS += $(INC) -Werror -Wall -std=gnu11 -Wl,--gc-sections $(BASE_CFLAGS) $(C_D # Most current ESPs have nano versions of newlib in ROM so we use them. ifneq ($(IDF_TARGET),esp32c6) CFLAGS += --specs=nano.specs - LDFLAGS += -T$(IDF_TARGET).rom.newlib-nano.ld else LDFLAGS += -T$(IDF_TARGET).rom.newlib-normal.ld endif @@ -264,7 +263,9 @@ else ifeq ($(IDF_TARGET),esp32c2) LDFLAGS += \ -Tesp32c2.rom.ble.ld \ -Tesp32c2.rom.heap.ld \ + -Tesp32c2.rom.libc.ld \ -Tesp32c2.rom.newlib.ld \ + -Tesp32c2.rom.newlib-nano.ld \ -Tesp32c2.rom.version.ld \ -Tesp32c2.rom.systimer.ld \ -Tesp32c2.rom.wdt.ld @@ -321,6 +322,7 @@ CHIP_COMPONENTS = \ else ifeq ($(IDF_TARGET),esp32p4) LDFLAGS += \ + -Tesp32p4.rom.libc.ld \ -Tesp32p4.rom.newlib.ld \ -Tesp32p4.rom.systimer.ld \ -Tesp32p4.rom.wdt.ld @@ -332,6 +334,7 @@ CHIP_COMPONENTS = \ else ifeq ($(IDF_TARGET),esp32h2) LDFLAGS += \ -Tesp32h2.rom.heap.ld \ + -Tesp32h2.rom.libc.ld \ -Tesp32h2.rom.newlib.ld \ -Tesp32h2.rom.systimer.ld \ -Tesp32h2.rom.wdt.ld @@ -352,6 +355,7 @@ CHIP_COMPONENTS = \ else ifeq ($(IDF_TARGET),esp32s3) LDFLAGS += \ + -Tesp32s3.rom.libc.ld \ -Tesp32s3.rom.newlib.ld \ -Tesp32s3.rom.version.ld \ -Tesp32s3.rom.systimer.ld \ @@ -712,7 +716,7 @@ ifneq ($(NEEDS_COEX),0) ESP_IDF_COMPONENTS_LINK += esp_coex endif ifneq ($(CIRCUITPY_WIFI),0) - ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy + ESP_IDF_COMPONENTS_LINK += esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy endif ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) BLE_IMPL_esp32 := esp32 diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults index fe3c3e0a2da88..2553c648018bd 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults @@ -95,7 +95,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_FSM=y CONFIG_ULP_COPROC_TYPE_RISCV=y # Note: enabling both ULPs simultaneously only works due to a modification of adafruit/esp-idf # (see adafruit/esp-idf/pull/16) until espressif/esp-idf/issues/12999 is fixed. -CONFIG_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ULP_COPROC_RESERVE_MEM=8144 # end of Ultra Low Power (ULP) Co-processor # end of Component config From 4ea6bb7b3b929d8fb69391072fbe6f958cd8abca Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 24 Sep 2025 16:21:56 -0700 Subject: [PATCH 164/208] Tweak coex inclusion --- ports/espressif/Makefile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index b759fe3c0052a..ed744da878af2 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -709,14 +709,13 @@ BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/librtc.a endif ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log newlib nvs_flash pthread soc spi_flash vfs esp_vfs_console -NEEDS_COEX = $(CIRCUITPY_BLEIO_NATIVE) + $(CIRCUITPY_WIFI) -ifneq ($(NEEDS_COEX),0) - # esp_system_include_startup_funcs requires coexist as well BT regardless of wifi - BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a - ESP_IDF_COMPONENTS_LINK += esp_coex -endif ifneq ($(CIRCUITPY_WIFI),0) ESP_IDF_COMPONENTS_LINK += esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy + ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) + # esp_system_include_startup_funcs requires coexist as well BT regardless of wifi + BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a + ESP_IDF_COMPONENTS_LINK += esp_coex + endif endif ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) BLE_IMPL_esp32 := esp32 From 40620146f4d8a8dd7eb82e5b82ea1b8ed46f798b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 25 Sep 2025 16:37:39 -0700 Subject: [PATCH 165/208] Tweak coex inclusion (again). The wrapper is always needed with wifi. --- ports/espressif/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index ed744da878af2..4fbcd62bdc367 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -710,11 +710,9 @@ endif ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log newlib nvs_flash pthread soc spi_flash vfs esp_vfs_console ifneq ($(CIRCUITPY_WIFI),0) - ESP_IDF_COMPONENTS_LINK += esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy + ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) - # esp_system_include_startup_funcs requires coexist as well BT regardless of wifi BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a - ESP_IDF_COMPONENTS_LINK += esp_coex endif endif ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) From fec20467062c723e31d90bf308b4b0778a26fc0c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 26 Sep 2025 10:32:32 -0700 Subject: [PATCH 166/208] Formatting --- ports/espressif/common-hal/alarm/pin/PinAlarm.c | 8 ++++++-- ports/espressif/tools/build_memory_info.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index 2b09c630925c0..97ad3b2a94255 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -384,8 +384,12 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_FLOATING)); } gpio_int_type_t intr = GPIO_INTR_DISABLE; - if (high) intr = GPIO_INTR_HIGH_LEVEL; - if (low) intr = GPIO_INTR_LOW_LEVEL; + if (high) { + intr = GPIO_INTR_HIGH_LEVEL; + } + if (low) { + intr = GPIO_INTR_LOW_LEVEL; + } never_reset_pin_number(pin); gpio_wakeup_enable(pin, intr); gpio_set_intr_type(pin, intr); diff --git a/ports/espressif/tools/build_memory_info.py b/ports/espressif/tools/build_memory_info.py index cd9cc91427116..0cf609c4d63f4 100644 --- a/ports/espressif/tools/build_memory_info.py +++ b/ports/espressif/tools/build_memory_info.py @@ -65,7 +65,7 @@ # Name, Start, Length ("LP SRAM", (0x5000_0000,), 16 * 1024), ("HP SRAM", (0x4080_0000,), 320 * 1024), - ("PSRAM", (0x4200_0000,), 2 * 1024 * 1024), + ("PSRAM", (0x4200_0000,), 2 * 1024 * 1024), ], "esp32h2": [ # Name, Start, Length From c493f1b48054c74f99811c71686ecca0481db18e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 26 Sep 2025 11:01:15 -0700 Subject: [PATCH 167/208] Always link coex with wifi. Shrink 2M C3 --- ports/espressif/Makefile | 4 +--- ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 4fbcd62bdc367..b6ddc27e4084c 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -699,6 +699,7 @@ ifneq ($(IDF_TARGET),esp32p4) endif ifneq ($(CIRCUITPY_WIFI),0) BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, $(BINARY_WIFI_BLOBS)) + BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a ifneq ($(IDF_TARGET),esp32c2) BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, libmesh.a libwapi.a) endif @@ -711,9 +712,6 @@ endif ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log newlib nvs_flash pthread soc spi_flash vfs esp_vfs_console ifneq ($(CIRCUITPY_WIFI),0) ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy - ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) - BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a - endif endif ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) BLE_IMPL_esp32 := esp32 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig index e962866216039..15b64d0ce2ebe 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig @@ -9,6 +9,11 @@ # # end of LWIP +# +# Wireless Coexistence +# +# CONFIG_ESP_COEX_SW_COEXIST_ENABLE is not set +# end of Wireless Coexistence # end of Component config # end of Espressif IoT Development Framework Configuration From b0f3a238f820a15e8541aced8c27edcae294395c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 26 Sep 2025 15:52:06 -0700 Subject: [PATCH 168/208] Disable memory speed optimization on 2m board. Also disable dynamic log level on opt builds --- .../boards/ai_thinker_esp32-c3s-2m/sdkconfig | 7 +++++++ .../esp-idf-config/sdkconfig-opt.defaults | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig index 15b64d0ce2ebe..5fd531f274a6a 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig @@ -14,6 +14,13 @@ # # CONFIG_ESP_COEX_SW_COEXIST_ENABLE is not set # end of Wireless Coexistence + +# +# LibC +# +# CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS is not set +# end of LibC + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults index 16f5b990386a1..0da23e8122762 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults @@ -38,6 +38,24 @@ CONFIG_ESP_CONSOLE_SECONDARY_NONE=y CONFIG_LOG_DEFAULT_LEVEL_NONE=y # end of Log output +# +# Log +# +# +# Log Level +# +# +# Level Settings +# +# CONFIG_LOG_DYNAMIC_LEVEL_CONTROL is not set +CONFIG_LOG_TAG_LEVEL_IMPL_NONE=y +# CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST is not set +# end of Level Settings + +# end of Log Level + +# end of Log + # end of Component config # end of Espressif IoT Development Framework Configuration From 9dbe0d1aa886114eb334b5ecbd3b93f091782bf6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 6 Oct 2025 11:49:39 -0700 Subject: [PATCH 169/208] Don't duplicate USB callbacks. --- lib/tinyusb | 2 +- ports/espressif/supervisor/usb.c | 25 ----------------------- ports/espressif/tools/decode_backtrace.py | 2 +- supervisor/shared/usb/usb_device.c | 10 +++++++++ 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/lib/tinyusb b/lib/tinyusb index 8304587d77745..c1bf19ed6cf1e 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 8304587d7774526a03c6881d11e6d6208fe759be +Subproject commit c1bf19ed6cf1eaa791f221c1bc5ce4b3d069f76d diff --git a/ports/espressif/supervisor/usb.c b/ports/espressif/supervisor/usb.c index 612abaa808ae2..274542ef22a7d 100644 --- a/ports/espressif/supervisor/usb.c +++ b/ports/espressif/supervisor/usb.c @@ -54,31 +54,6 @@ static void usb_device_task(void *param) { vTaskDelay(1); } } - -/** - * Callback invoked when received an "wanted" char. - * @param itf Interface index (for multiple cdc interfaces) - * @param wanted_char The wanted char (set previously) - */ -void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void)itf; // not used - // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. - // So, we must notify the other task when a CTRL-C is received. - port_wake_main_task(); - // Workaround for using shared/runtime/interrupt_char.c - // Compare mp_interrupt_char with wanted_char and ignore if not matched - if (mp_interrupt_char == wanted_char) { - tud_cdc_read_flush(); // flush read fifo - mp_sched_keyboard_interrupt(); - } -} - -void tud_cdc_rx_cb(uint8_t itf) { - (void)itf; - // Workaround for "press any key to enter REPL" response being delayed on espressif. - // Wake main task when any key is pressed. - port_wake_main_task(); -} #endif // CIRCUITPY_USB_DEVICE void init_usb_hardware(void) { diff --git a/ports/espressif/tools/decode_backtrace.py b/ports/espressif/tools/decode_backtrace.py index 1733c69b5bb57..d597741a59676 100644 --- a/ports/espressif/tools/decode_backtrace.py +++ b/ports/espressif/tools/decode_backtrace.py @@ -24,7 +24,7 @@ addresses = addresses[len("Backtrace:") :] addresses = addresses.strip().split() addresses = [address.split(":")[0] for address in addresses] - if addresses.startswith("Stack memory:"): + elif addresses.startswith("Stack memory:"): addresses = [] extra_lines = sys.stdin.readlines() for line in extra_lines: diff --git a/supervisor/shared/usb/usb_device.c b/supervisor/shared/usb/usb_device.c index ec08b8bf4d7e2..16ae137eddefb 100644 --- a/supervisor/shared/usb/usb_device.c +++ b/supervisor/shared/usb/usb_device.c @@ -166,6 +166,9 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ * @param wanted_char The wanted char (set previously) */ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { + // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB on ESP. + // So, we must notify the other task when a CTRL-C is received. + port_wake_main_task(); // Workaround for using shared/runtime/interrupt_char.c // Compare mp_interrupt_char with wanted_char and ignore if not matched if (mp_interrupt_char == wanted_char) { @@ -177,7 +180,14 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { if (usb_cdc_console_enabled() && mp_interrupt_char != -1 && itf == 0 && duration_ms > 0) { mp_sched_keyboard_interrupt(); + port_wake_main_task(); } } +void tud_cdc_rx_cb(uint8_t itf) { + (void)itf; + // Workaround for "press any key to enter REPL" response being delayed on espressif. + // Wake main task when any key is pressed. + port_wake_main_task(); +} #endif From 802380d381f44583355e6fbc292a2a30e0140a7b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 6 Oct 2025 19:01:50 -0400 Subject: [PATCH 170/208] py/misc.h: prevent clang warning --- py/misc.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/py/misc.h b/py/misc.h index eb7fc54be6fec..555e58dd14fc9 100644 --- a/py/misc.h +++ b/py/misc.h @@ -54,7 +54,14 @@ typedef unsigned int uint; #define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) // Static assertion macro +#if __cplusplus +#define MP_STATIC_ASSERT(cond) static_assert((cond), #cond) +#elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L +#define MP_STATIC_ASSERT(cond) _Static_assert((cond), #cond) +#else #define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)])) +#endif + // In C++ things like comparing extern const pointers are not constant-expressions so cannot be used // in MP_STATIC_ASSERT. Note that not all possible compiler versions will reject this. Some gcc versions // do, others only with -Werror=vla, msvc always does. @@ -63,7 +70,10 @@ typedef unsigned int uint; #if defined(_MSC_VER) || defined(__cplusplus) #define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)1) #else -#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) MP_STATIC_ASSERT(cond) +#if __clang__ +#pragma GCC diagnostic ignored "-Wgnu-folding-constant" +#endif +#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)sizeof(char[1 - 2 * !(cond)])) #endif // Round-up integer division From 2e1c6169c1e44d8859f2f0d3b9adb62aa3a84134 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 6 Oct 2025 20:40:21 -0400 Subject: [PATCH 171/208] py/misc.h: test for __cplusplus and __clang__ more carefully --- py/misc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py/misc.h b/py/misc.h index 555e58dd14fc9..22f32147124fc 100644 --- a/py/misc.h +++ b/py/misc.h @@ -54,7 +54,7 @@ typedef unsigned int uint; #define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) // Static assertion macro -#if __cplusplus +#if defined(__cplusplus) #define MP_STATIC_ASSERT(cond) static_assert((cond), #cond) #elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L #define MP_STATIC_ASSERT(cond) _Static_assert((cond), #cond) @@ -70,7 +70,7 @@ typedef unsigned int uint; #if defined(_MSC_VER) || defined(__cplusplus) #define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)1) #else -#if __clang__ +#if defined(__clang__) #pragma GCC diagnostic ignored "-Wgnu-folding-constant" #endif #define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)sizeof(char[1 - 2 * !(cond)])) From d5d6a8ef97fed4850a76c5bc0247a212c7304400 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 7 Oct 2025 11:04:57 -0400 Subject: [PATCH 172/208] use MP_STATIC_ASSERT_NONCONSTEXPR in ports/analog --- ports/analog/common-hal/digitalio/DigitalInOut.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/analog/common-hal/digitalio/DigitalInOut.c b/ports/analog/common-hal/digitalio/DigitalInOut.c index 7d4048d77e70e..93e2242fbb6f6 100644 --- a/ports/analog/common-hal/digitalio/DigitalInOut.c +++ b/ports/analog/common-hal/digitalio/DigitalInOut.c @@ -107,7 +107,7 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( if (self->pin->port < 4) { // Check that I/O mode is enabled and we don't have in AND out on at the same time - MP_STATIC_ASSERT(!((port->en0 & mask) && (port->inen & mask) && (port->outen & mask))); + MP_STATIC_ASSERT_NONCONSTEXPR(!((port->en0 & mask) && (port->inen & mask) && (port->outen & mask))); if ((port->en0 & mask) && (port->outen & mask)) { return DIRECTION_OUTPUT; From e2cbc2db3d4a3be0e9600e935339081be212f9f0 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 7 Oct 2025 16:45:51 -0400 Subject: [PATCH 173/208] Fix filesystem writability from USB --- extmod/vfs.h | 2 ++ extmod/vfs_fat.c | 11 ++++------- extmod/vfs_fat_diskio.c | 6 +++++- main.c | 18 +++++++++++------- supervisor/filesystem.h | 1 + supervisor/shared/filesystem.c | 14 ++++++++++++-- supervisor/shared/usb/usb_msc_flash.c | 2 +- 7 files changed, 36 insertions(+), 18 deletions(-) diff --git a/extmod/vfs.h b/extmod/vfs.h index 67d5d9239a33e..699232e56cd87 100644 --- a/extmod/vfs.h +++ b/extmod/vfs.h @@ -52,6 +52,8 @@ #define MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED (0x0020) // Bit set when something has claimed the right to mutate the blockdev. #define MP_BLOCKDEV_FLAG_LOCKED (0x0040) +// Ignore write protections. Used to override other flags temporarily. +#define MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION (0x0080) // constants for block protocol ioctl #define MP_BLOCKDEV_IOCTL_INIT (1) diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 5011a820af864..6267452cd32c7 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -427,13 +427,10 @@ static MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_statvfs_obj, fat_vfs_statvfs); static mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs) { fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); - // Read-only device indicated by writeblocks[0] == MP_OBJ_NULL. - // User can specify read-only device by: - // 1. readonly=True keyword argument - // 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already) - if (mp_obj_is_true(readonly)) { - self->blockdev.writeblocks[0] = MP_OBJ_NULL; - } + // CIRCUITPY-CHANGE: Use MP_BLOCKDEV_FLAG_USB_WRITABLE instead of writeblocks[0] =/!= MP_OBJ_NULL + // to specify read-write. + // If readonly to Python, it's writable by USB and vice versa. + filesystem_set_writable_by_usb(self, mp_obj_is_true(readonly)); // check if we need to make the filesystem FRESULT res = (self->blockdev.flags & MP_BLOCKDEV_FLAG_NO_FILESYSTEM) ? FR_NO_FILESYSTEM : FR_OK; diff --git a/extmod/vfs_fat_diskio.c b/extmod/vfs_fat_diskio.c index 6f500104d1e86..591da07eb5630 100644 --- a/extmod/vfs_fat_diskio.c +++ b/extmod/vfs_fat_diskio.c @@ -43,6 +43,9 @@ #include "lib/oofatfs/diskio.h" #include "extmod/vfs_fat.h" +// CIRCUITPY-CHANGE +#include "supervisor/filesystem.h" + typedef void *bdev_t; static fs_user_mount_t *disk_get_device(void *bdev) { return (fs_user_mount_t *)bdev; @@ -153,7 +156,8 @@ DRESULT disk_ioctl( if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) { // error initialising stat = STA_NOINIT; - } else if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL) { + // CIRCUITPY-CHANGE: writability from Python check + } else if (!filesystem_is_writable_by_python(vfs)) { stat = STA_PROTECT; } else { stat = 0; diff --git a/main.c b/main.c index d7f3c7aaf1bce..91687ff2f8bc7 100644 --- a/main.c +++ b/main.c @@ -863,6 +863,14 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { boot_output = &boot_text; #endif + // Get the base filesystem. + fs_user_mount_t *vfs = filesystem_circuitpy(); + FATFS *fs = &vfs->fatfs; + + // Allow boot.py access to CIRCUITPY, and allow writes to boot_out.txt. + // We can't use the regular flags for this, because they might get modified inside boot.py. + filesystem_set_ignore_write_protection(vfs, true); + // Write version info mp_printf(&mp_plat_print, "%s\nBoard ID:%s\n", MICROPY_FULL_VERSION_INFO, CIRCUITPY_BOARD_ID); #if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH > 0 @@ -881,10 +889,6 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { #ifdef CIRCUITPY_BOOT_OUTPUT_FILE - // Get the base filesystem. - fs_user_mount_t *vfs = filesystem_circuitpy(); - FATFS *fs = &vfs->fatfs; - boot_output = NULL; #if CIRCUITPY_STATUS_BAR supervisor_status_bar_resume(); @@ -906,9 +910,6 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // in case power is momentary or will fail shortly due to, say a low, battery. mp_hal_delay_ms(1000); - // USB isn't up, so we can write the file. - // operating at the oofatfs (f_open) layer means the usb concurrent write permission - // is not even checked! f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS); UINT chars_written; f_write(&boot_output_file, boot_text.buf, boot_text.len, &chars_written); @@ -916,6 +917,9 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { filesystem_flush(); } #endif + + // Back to regular filesystem protections. + filesystem_set_ignore_write_protection(vfs, false); } cleanup_after_vm(_exec_result.exception); diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h index a0445b0510da9..30cd83d443815 100644 --- a/supervisor/filesystem.h +++ b/supervisor/filesystem.h @@ -21,6 +21,7 @@ void filesystem_set_internal_writable_by_usb(bool usb_writable); void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection); void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable); void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection); +void filesystem_set_ignore_write_protection(fs_user_mount_t *vfs, bool ignore_write_protection); // Whether user code can modify the filesystem. It doesn't depend on the state // of USB. Don't use this for a workflow. In workflows, grab the shared file diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 24c7f9bffc552..025c9ddbd6de3 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -248,12 +248,14 @@ void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) { bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) { return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || - ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0); + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION) != 0); } bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) { return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || - ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0); + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION) != 0); } void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) { @@ -268,6 +270,14 @@ void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concu } } +void filesystem_set_ignore_write_protection(fs_user_mount_t *vfs, bool ignore_write_protection) { + if (ignore_write_protection) { + vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; + } else { + vfs->blockdev.flags &= ~MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; + } +} + bool filesystem_present(void) { return _circuitpy_vfs.len > 0; } diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index e4e4801de9c88..febede876bbf5 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -249,7 +249,7 @@ bool tud_msc_is_writable_cb(uint8_t lun) { if (vfs == NULL) { return false; } - if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL || !filesystem_is_writable_by_usb(vfs)) { + if (!filesystem_is_writable_by_usb(vfs)) { return false; } // Lock the blockdev once we say we're writable. From a6a6ebe5892343e59056b0178c3369cb1ac4505d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 7 Oct 2025 17:03:16 -0700 Subject: [PATCH 174/208] Fix C6 by disabling hardware SHA --- ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults index 85dde905f3caa..63f42cac95244 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults @@ -49,6 +49,12 @@ CONFIG_ESP_PHY_ENABLE_USB=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 # end of Wi-Fi +# +# mbedTLS +# +# CONFIG_MBEDTLS_HARDWARE_SHA is not set +# end of mbedTLS + # end of Component config # end of Espressif IoT Development Framework Configuration From a55305eae9aebfecff91410951eecafbe1f505f9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 9 Oct 2025 12:32:08 -0400 Subject: [PATCH 175/208] new location of importlib Traversable --- tools/board_stubs/circuitpython_setboard/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/board_stubs/circuitpython_setboard/__init__.py b/tools/board_stubs/circuitpython_setboard/__init__.py index 3a73beb3119df..69a405405b800 100644 --- a/tools/board_stubs/circuitpython_setboard/__init__.py +++ b/tools/board_stubs/circuitpython_setboard/__init__.py @@ -12,7 +12,12 @@ import shutil from collections import defaultdict from importlib import resources -from importlib.abc import Traversable + +try: + from importlib.resources.abc import Traversable +except ModuleNotFoundError: + # 3.10 and earlier. + from importlib.abc import Traversable def get_definitions_or_exit(board: str) -> Traversable: From 6a1a59b84d8d3d8d2a766d898e88d0d87c11cf18 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 9 Oct 2025 11:48:13 -0500 Subject: [PATCH 176/208] docs: add TilePaletteMapper to pixel_shader allowed types. --- shared-bindings/displayio/TileGrid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index eddf3f66c4ec0..560fb66a67553 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -49,7 +49,7 @@ void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader) { //| self, //| bitmap: Union[Bitmap, OnDiskBitmap], //| *, -//| pixel_shader: Union[ColorConverter, Palette], +//| pixel_shader: Union[ColorConverter, Palette, tilepalettemapper.TilePaletteMapper], //| width: int = 1, //| height: int = 1, //| tile_width: Optional[int] = None, @@ -68,7 +68,7 @@ void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader) { //| tile_width and tile_height match the height of the bitmap by default. //| //| :param Bitmap,OnDiskBitmap bitmap: The bitmap storing one or more tiles. -//| :param ColorConverter,Palette pixel_shader: The pixel shader that produces colors from values +//| :param ColorConverter,Palette,tilepalettemapper.TilePaletteMapper pixel_shader: The pixel shader that produces colors from values //| :param int width: Width of the grid in tiles. //| :param int height: Height of the grid in tiles. //| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. @@ -330,7 +330,7 @@ static mp_obj_t displayio_tilegrid_obj_contains(mp_obj_t self_in, mp_obj_t touch } MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_contains_obj, displayio_tilegrid_obj_contains); -//| pixel_shader: Union[ColorConverter, Palette] +//| pixel_shader: Union[ColorConverter, Palette, tilepalettemapper.TilePaletteMapper] //| """The pixel shader of the tilegrid.""" static mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); From 611b887a8113c71a504a1893ac8b07f64f55c058 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 15 Oct 2025 11:09:57 -0400 Subject: [PATCH 177/208] Fix SPI DMA on SAMD --- ports/atmel-samd/audio_dma.c | 18 ++++++------- .../atmel-samd/common-hal/audiobusio/PDMIn.c | 2 +- ports/atmel-samd/common-hal/busio/SPI.c | 27 ++++++++++--------- .../imagecapture/ParallelImageCapture.c | 3 ++- .../common-hal/spitarget/SPITarget.c | 10 +++---- .../common-hal/spitarget/SPITarget.h | 2 +- ports/atmel-samd/peripherals | 2 +- 7 files changed, 34 insertions(+), 30 deletions(-) diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index e25b74d9a2893..e39804015063b 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -39,14 +39,14 @@ uint8_t find_sync_event_channel_raise(void) { } void audio_dma_disable_channel(uint8_t channel) { - if (channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (channel == NO_DMA_CHANNEL) { return; } dma_disable_channel(channel); } void audio_dma_enable_channel(uint8_t channel) { - if (channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (channel == NO_DMA_CHANNEL) { return; } dma_enable_channel(channel); @@ -171,8 +171,8 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, bool output_signed, uint32_t output_register_address, uint8_t dma_trigger_source) { - uint8_t dma_channel = dma_allocate_channel(true); - if (dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + uint8_t dma_channel = dma_allocate_audio_channel(); + if (dma_channel == NO_DMA_CHANNEL) { return AUDIO_DMA_DMA_BUSY; } @@ -298,14 +298,14 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, void audio_dma_stop(audio_dma_t *dma) { uint8_t channel = dma->dma_channel; - if (channel < AUDIO_DMA_CHANNEL_COUNT) { + if (channel != NO_DMA_CHANNEL) { audio_dma_disable_channel(channel); disable_event_channel(dma->event_channel); MP_STATE_PORT(playing_audio)[channel] = NULL; audio_dma_state[channel] = NULL; dma_free_channel(dma->dma_channel); } - dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; + dma->dma_channel = NO_DMA_CHANNEL; dma->playing_in_progress = false; } @@ -318,7 +318,7 @@ void audio_dma_resume(audio_dma_t *dma) { } bool audio_dma_get_paused(audio_dma_t *dma) { - if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->dma_channel == NO_DMA_CHANNEL) { return false; } uint32_t status = dma_transfer_status(dma->dma_channel); @@ -327,7 +327,7 @@ bool audio_dma_get_paused(audio_dma_t *dma) { } void audio_dma_init(audio_dma_t *dma) { - dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; + dma->dma_channel = NO_DMA_CHANNEL; } void audio_dma_reset(void) { @@ -341,7 +341,7 @@ void audio_dma_reset(void) { } bool audio_dma_get_playing(audio_dma_t *dma) { - if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->dma_channel == NO_DMA_CHANNEL) { return false; } return dma->playing_in_progress; diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index a1a67d0408247..f409563f5ed69 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -364,7 +364,7 @@ static uint16_t filter_sample(uint32_t pdm_samples[4]) { // output_buffer_length is the number of slots, not the number of bytes. uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *self, uint16_t *output_buffer, uint32_t output_buffer_length) { - uint8_t dma_channel = dma_allocate_channel(true); + uint8_t dma_channel = dma_allocate_audio_channel(); pdmin_event_channel = find_sync_event_channel_raise(); pdmin_dma_block_done = false; diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 5d7633be7f8d3..5dd7bedebc394 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -21,7 +21,17 @@ #include "samd/dma.h" #include "samd/sercom.h" -void setup_pin(const mcu_pin_obj_t *pin, uint32_t pinmux); + +static void setup_pin(const mcu_pin_obj_t *pin, uint32_t pinmux, const enum gpio_direction direction) { + gpio_set_pin_direction(pin->number, direction); + gpio_set_pin_pull_mode(pin->number, GPIO_PULL_OFF); + gpio_set_pin_function(pin->number, pinmux); + if (direction == GPIO_DIRECTION_OUT) { + // Use strong drive strength for SPI outputs. + hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin->number), GPIO_PIN(pin->number)); + } + claim_pin(pin); +} void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, @@ -128,6 +138,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Pads must be set after spi_m_sync_init(), which uses default values from // the prototypical SERCOM. + // Set to SPI host mode and choose pads. hri_sercomspi_write_CTRLA_MODE_bf(sercom, 3); hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); hri_sercomspi_write_CTRLA_DIPO_bf(sercom, miso_pad); @@ -141,20 +152,20 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_OSError(MP_EIO); } - setup_pin(clock, clock_pinmux); + setup_pin(clock, clock_pinmux, GPIO_DIRECTION_OUT); self->clock_pin = clock->number; if (mosi_none) { self->MOSI_pin = NO_PIN; } else { - setup_pin(mosi, mosi_pinmux); + setup_pin(mosi, mosi_pinmux, GPIO_DIRECTION_OUT); self->MOSI_pin = mosi->number; } if (miso_none) { self->MISO_pin = NO_PIN; } else { - setup_pin(miso, miso_pinmux); + setup_pin(miso, miso_pinmux, GPIO_DIRECTION_IN); self->MISO_pin = miso->number; } @@ -317,11 +328,3 @@ uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { void *hw = self->spi_desc.dev.prvt; return hri_sercomspi_get_CTRLA_CPOL_bit(hw); } - -void setup_pin(const mcu_pin_obj_t *pin, uint32_t pinmux) { - gpio_set_pin_direction(pin->number, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(pin->number, GPIO_PULL_OFF); - gpio_set_pin_function(pin->number, pinmux); - claim_pin(pin); - hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin->number), GPIO_PIN(pin->number)); -} diff --git a/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c b/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c index a6d8fef0f394b..56eb82678ec01 100644 --- a/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +++ b/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c @@ -135,7 +135,8 @@ void common_hal_imagecapture_parallelimagecapture_singleshot_capture(imagecaptur mp_buffer_info_t bufinfo; mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_RW); - uint8_t dma_channel = dma_allocate_channel(true); + // Allocate a permanent channel (not really audio). + uint8_t dma_channel = dma_allocate_audio_channel(); uint32_t *dest = bufinfo.buf; size_t count = bufinfo.len / 4; // PCC receives 4 bytes (2 pixels) at a time diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.c b/ports/atmel-samd/common-hal/spitarget/SPITarget.c index b9062911cc353..e5011b141fc12 100644 --- a/ports/atmel-samd/common-hal/spitarget/SPITarget.c +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.c @@ -192,7 +192,7 @@ void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t * self->miso_packet = miso_packet; Sercom *sercom = self->spi_desc.dev.prvt; - self->running_dma = shared_dma_transfer_start(sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + shared_dma_transfer_start(&self->running_dma, sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); // There is an issue where if an unexpected SPI transfer is received before the user calls "end" for the in-progress, expected // transfer, the SERCOM has an error and gets confused. This can be detected from INTFLAG.ERROR. I think the code in @@ -200,7 +200,7 @@ void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t * // s->SPI.DATA.reg) is supposed to fix this, but experimentation seems to show that it does not in fact fix anything. Anyways, if // the ERROR bit is set, let's just reset the peripheral and then setup the transfer again -- that seems to work. if (hri_sercomspi_get_INTFLAG_ERROR_bit(sercom)) { - shared_dma_transfer_close(self->running_dma); + shared_dma_transfer_close(&self->running_dma); // disable the sercom spi_m_sync_disable(&self->spi_desc); @@ -223,19 +223,19 @@ void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t * spi_m_sync_enable(&self->spi_desc); hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); - self->running_dma = shared_dma_transfer_start(sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + shared_dma_transfer_start(&self->running_dma, sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); } } bool common_hal_spitarget_spi_target_transfer_is_finished(spitarget_spi_target_obj_t *self) { - return self->running_dma.failure == 1 || shared_dma_transfer_finished(self->running_dma); + return self->running_dma.failure == 1 || shared_dma_transfer_finished(&self->running_dma); } int common_hal_spitarget_spi_target_transfer_close(spitarget_spi_target_obj_t *self) { if (self->running_dma.failure == 1) { return 0; } - int res = shared_dma_transfer_close(self->running_dma); + int res = shared_dma_transfer_close(&self->running_dma); self->running_dma.failure = 1; self->mosi_packet = NULL; diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.h b/ports/atmel-samd/common-hal/spitarget/SPITarget.h index 50f2bcb33094b..9fff23c174370 100644 --- a/ports/atmel-samd/common-hal/spitarget/SPITarget.h +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.h @@ -18,7 +18,7 @@ typedef struct { uint8_t *mosi_packet; const uint8_t *miso_packet; - dma_descr_t running_dma; + dma_transfer_t running_dma; } spitarget_spi_target_obj_t; #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_TARGET_H diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index d3210221bbd01..a1f1504d41438 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit d3210221bbd018ae9d0183ea4640c42cf4bce672 +Subproject commit a1f1504d414387fc3ff48dc2ba98fd7af4461a63 From c8377c75533cb25f18b74f605e24adeaca3059fa Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 16 Oct 2025 13:50:05 -0400 Subject: [PATCH 178/208] incorporate https://github.com/adafruit/samd-peripherals/pull/47 --- ports/atmel-samd/peripherals | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index a1f1504d41438..863e615ff98c3 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit a1f1504d414387fc3ff48dc2ba98fd7af4461a63 +Subproject commit 863e615ff98c3a8aa904e87a157553559c933b81 From a2d9e9e68b482d04c045cb53455e565a8b4292e7 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 16 Oct 2025 14:38:43 -0400 Subject: [PATCH 179/208] Restore atmel-samd SD card USB presentation --- ports/atmel-samd/mpconfigport.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index e953ea0fc50d4..087e0bc7d6820 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -11,9 +11,6 @@ // Definitions that control circuitpy_mpconfig.h: -// On SAMD, presenting the SD card as a second LUN causes USB disconnect. This needs to be fixed eventually. -#define CIRCUITPY_SDCARD_USB (0) - //////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef SAMD21 From 5df18c37b93fa7853494a8cfc1483488ca04eefd Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 16 Oct 2025 12:01:06 -0700 Subject: [PATCH 180/208] Clean up two leftovers from debugging --- ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv | 3 ++- ports/espressif/tools/decode_backtrace.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv index 44121812ea2bf..6d78fe8af5916 100644 --- a/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-8MB-no-uf2.csv @@ -3,5 +3,6 @@ # partition_table, data, table, 0x8000, 4K nvs, data, nvs, 0x9000, 20K otadata, data, ota, 0xe000, 8K -ota_0, app, ota_0, 0x10000, 4096K +ota_0, app, ota_0, 0x10000, 2048K +ota_1, app, ota_1, 0x210000, 2048K user_fs, data, fat, 0x410000, 4032K diff --git a/ports/espressif/tools/decode_backtrace.py b/ports/espressif/tools/decode_backtrace.py index d597741a59676..16cef9e0822cc 100644 --- a/ports/espressif/tools/decode_backtrace.py +++ b/ports/espressif/tools/decode_backtrace.py @@ -14,7 +14,9 @@ elfs = [ f"build-{board}/firmware.elf", - "/home/tannewt/Downloads/esp-rom-elfs-20241011/esp32c6_rev0_rom.elf", + # Add additional ELF files here such as the ROM ELF files from: + # https://github.com/espressif/esp-rom-elfs/releases + # "/home/tannewt/Downloads/esp-rom-elfs-20241011/esp32c6_rev0_rom.elf", ] while True: From 1786e9abc96ae007aa4d31a25c6238d790168f4a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 17 Oct 2025 13:37:16 -0400 Subject: [PATCH 181/208] restrict Python cryptography version --- requirements-dev.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 261a5cc2c7fe8..0e8426d5174d4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -25,7 +25,8 @@ intelhex # for building & testing natmods pyelftools -cryptography +# newer versions break ESP-IDF now +cryptography<45 # for web workflow minify minify_html From f8cb53c367cf4b3bfe348112848d5ec358a033cf Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 17 Oct 2025 11:27:06 -0700 Subject: [PATCH 182/208] Fix overriding delay without an OS --- shared-module/max3421e/Max3421E.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/max3421e/Max3421E.c b/shared-module/max3421e/Max3421E.c index 4946e4e7d8dfa..3448cdd4c7596 100644 --- a/shared-module/max3421e/Max3421E.c +++ b/shared-module/max3421e/Max3421E.c @@ -83,7 +83,7 @@ void common_hal_max3421e_max3421e_deinit(max3421e_max3421e_obj_t *self) { // anyway. Don't run background tasks because this function is used by // tuh_task() which is run as a background task. #if CFG_TUSB_OS == OPT_OS_NONE -void osal_task_delay(uint32_t msec) { +void tusb_time_delay_ms_api(uint32_t msec) { uint32_t end_time = common_hal_time_monotonic_ms() + msec; while (common_hal_time_monotonic_ms() < end_time) { if (tuh_callback.prev != NULL) { From 61e80a61b055124678d3e1de214d29951b9270bc Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 22 Oct 2025 19:46:00 -0400 Subject: [PATCH 183/208] pin changes --- .../atmel-samd/boards/microchip_curiosity_circuitpython/pins.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c index f3069930c6b0b..fd8213a573a14 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c @@ -44,6 +44,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_LCD_LEDA), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB30) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB31) }, @@ -59,9 +60,11 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB00) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT), MP_ROM_PTR(&pin_PB00) }, { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_IMU_ADDR), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB02) }, From b076e08283ac8b72d833b1dae8527dc186ddfd53 Mon Sep 17 00:00:00 2001 From: natheihei Date: Fri, 24 Oct 2025 21:47:10 -0700 Subject: [PATCH 184/208] board: add board waveshare_esp32_s3_touch_lcd_1_47 --- .../waveshare_esp32_s3_touch_lcd_1_47/board.c | 145 ++++++++++++++++++ .../mpconfigboard.h | 22 +++ .../mpconfigboard.mk | 14 ++ .../waveshare_esp32_s3_touch_lcd_1_47/pins.c | 58 +++++++ .../sdkconfig | 14 ++ 5 files changed, 253 insertions(+) create mode 100644 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c create mode 100644 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h create mode 100644 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk create mode 100644 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c create mode 100644 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c new file mode 100644 index 0000000000000..4c037ce8df057 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c @@ -0,0 +1,145 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// Driver is JD9853 +// 172 X 320 Pixels RGB 18-bit +// Init sequence converted from Arduino example + +uint8_t display_init_sequence[] = { + // Command: 0x11 (SLPOUT: Sleep Out) + // Description: Exits sleep mode. A 120ms delay is added for the power supply and clock circuits to stabilize. + 0x11, 0 | DELAY, 120, + + 0xDF, 2, 0x98, 0x53, + 0xB2, 1, 0x23, + + 0xB7, 4, 0x00, 0x47, 0x00, 0x6F, + 0xBB, 6, 0x1C, 0x1A, 0x55, 0x73, 0x63, 0xF0, + 0xC0, 2, 0x44, 0xA4, + 0xC1, 1, 0x16, + 0xC3, 8, 0x7D, 0x07, 0x14, 0x06, 0xCF, 0x71, 0x72, 0x77, + 0xC4, 12, 0x00, 0x00, 0xA0, 0x79, 0x0B, 0x0A, 0x16, 0x79, 0x0B, 0x0A, 0x16, 0x82, + + 0xC8, 32, 0x3F, 0x32, 0x29, 0x29, 0x27, 0x2B, 0x27, 0x28, 0x28, 0x26, 0x25, 0x17, 0x12, 0x0D, 0x04, 0x00, + 0x3F, 0x32, 0x29, 0x29, 0x27, 0x2B, 0x27, 0x28, 0x28, 0x26, 0x25, 0x17, 0x12, 0x0D, 0x04, 0x00, + + 0xD0, 5, 0x04, 0x06, 0x6B, 0x0F, 0x00, + 0xD7, 2, 0x00, 0x30, + 0xE6, 1, 0x14, + 0xDE, 1, 0x01, + + 0xB7, 5, 0x03, 0x13, 0xEF, 0x35, 0x35, + 0xC1, 3, 0x14, 0x15, 0xC0, + 0xC2, 2, 0x06, 0x3A, + 0xC4, 2, 0x72, 0x12, + 0xBE, 1, 0x00, + 0xDE, 1, 0x02, + + 0xE5, 3, 0x00, 0x02, 0x00, + 0xE5, 3, 0x01, 0x02, 0x00, + + 0xDE, 1, 0x00, + + // Command: 0x35 (TEON: Tearing Effect Line ON) + // Description: Turns on the Tearing Effect output signal. + 0x35, 1, 0x00, + + // Command: 0x3A (COLMOD: Pixel Format Set) + // Description: Sets the pixel format for the MCU interface. + 0x3A, 1, 0x05, + + // Command: 0x2A (CASET: Column Address Set) + // Description: Defines the accessible column range in frame memory. + 0x2A, 4, 0x00, 0x22, 0x00, 0xCD, + + // Command: 0x2B (PASET: Page Address Set) + // Description: Defines the accessible page (row) range. + 0x2B, 4, 0x00, 0x00, 0x01, 0x3F, + + 0xDE, 1, 0x02, + 0xE5, 3, 0x00, 0x02, 0x00, + 0xDE, 1, 0x00, + + // Command: 0x36 (MADCTL: Memory Access Control) + // Description: Sets the read/write scanning direction of the frame memory. + 0x36, 1, 0x00, + + // Command: 0x21 (INVON: Display Inversion ON) + // 0x21, 0 | DELAY, 10, + + // Command: 0x29 (DISPON: Display ON) + // Description: Turns the display on by enabling output from the frame memory. + 0x29, 0, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + &pin_GPIO45, // DC + &pin_GPIO21, // CS + &pin_GPIO40, // RST + 80000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 172, // width (after rotation) + 320, // height (after rotation) + 34, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO46, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h new file mode 100644 index 0000000000000..0dc2ad4a6616b --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3 Touch LCD 1.47" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.rx = &pin_GPIO44, .tx = &pin_GPIO43}} + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO41, .sda = &pin_GPIO42}} /* for Touchscreen */ + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO38, .mosi = &pin_GPIO39}, /* for LCD display */ \ + {.clock = &pin_GPIO16, .mosi = &pin_GPIO15, .miso = &pin_GPIO17} /* for SD Card */} diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk new file mode 100644 index 0000000000000..b337b21149537 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x8325 +USB_PRODUCT = "ESP32-S3-Touch-LCD-1.47" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c new file mode 100644 index 0000000000000..32c7d0dd21d7e --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c @@ -0,0 +1,58 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(touch_i2c, i2c, 0) +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // GPIO + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GPIO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GPIO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GPIO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GPIO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GPIO11), MP_ROM_PTR(&pin_GPIO11) }, + + // I2C (occupied by Touch I2C) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_D0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_D1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_D2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SD_D3), MP_ROM_PTR(&pin_GPIO14) }, + // CLK, CMD, D0 is also included in the SPI object as its MISO pin, MOSI pin, and SCK pin respectively + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + + // AXS5106L Touch + { MP_ROM_QSTR(MP_QSTR_TOUCH_I2C), MP_ROM_PTR(&board_touch_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_IRQ), MP_ROM_PTR(&pin_GPIO48) }, + + // JD9853 LCD Display + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig new file mode 100644 index 0000000000000..e962866216039 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration From cb458bf1b469870d9882650679806b0461905431 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Sun, 26 Oct 2025 23:14:34 -0400 Subject: [PATCH 185/208] Add Waveshare ESP32S3 Touch LCD 2.8inch display board --- .../waveshare_esp32_s3_touch_lcd_2_8/board.c | 77 +++++++++++++ .../mpconfigboard.h | 19 +++ .../mpconfigboard.mk | 14 +++ .../waveshare_esp32_s3_touch_lcd_2_8/pins.c | 109 ++++++++++++++++++ .../sdkconfig | 0 5 files changed, 219 insertions(+) create mode 100755 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c create mode 100755 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h create mode 100755 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk create mode 100755 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c create mode 100755 ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/sdkconfig diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c new file mode 100755 index 0000000000000..deb764b80a5f7 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c @@ -0,0 +1,77 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, DELAY | 1, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x21, DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0x60, // _MADCTL + 0x29, DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + &pin_GPIO41, // DC + &pin_GPIO42, // CS + &pin_GPIO39, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO5, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h new file mode 100755 index 0000000000000..3e0db8bf494d5 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Neradoc +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3 Touch LCD 2.8" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO3, .sda = &pin_GPIO1}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO40, .mosi = &pin_GPIO45, .miso = &pin_GPIO46}} + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk new file mode 100755 index 0000000000000..dc845ad13990d --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x825F +USB_MANUFACTURER = "Waveshare Electronics" +USB_PRODUCT = "ESP32-S3 Touch LCD 2.8" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m \ No newline at end of file diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c new file mode 100755 index 0000000000000..00ff3557088a1 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c @@ -0,0 +1,109 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // LCD (SPI0) + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO5) }, // PWM-capable + + // microSD (SPI1) + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, + + // Touch panel (I2C0) + { MP_ROM_QSTR(MP_QSTR_TP_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TP_SDA), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TP_RST), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_TP_INT), MP_ROM_PTR(&pin_GPIO4) }, + + // IMU (I2C1) + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO13) }, + + // I2S Audio + { MP_ROM_QSTR(MP_QSTR_I2S_BCK), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO38) }, + + // Battery management + { MP_ROM_QSTR(MP_QSTR_BAT_CONTROL), MP_ROM_PTR(&pin_GPIO7) }, // control pin + { MP_ROM_QSTR(MP_QSTR_BAT_PWR), MP_ROM_PTR(&pin_GPIO6) }, // Board name + { MP_ROM_QSTR(MP_QSTR_KEY_BAT), MP_ROM_PTR(&pin_GPIO6) }, // Schematics name + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO8) }, // VBAT sense (ADC) + + // UART header + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, // User accessible + + // I2C header + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO11) }, + + // Boot/User button + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, // Optional Alias + + // Primary bus pins + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO40) }, // Primary SPI (LCD) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, // Primary I2C (TP) + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO1) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // Fallback mapping for all GPIO pins + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/sdkconfig new file mode 100755 index 0000000000000..e69de29bb2d1d From b406116b87442c66c30b4c708e404841742b555d Mon Sep 17 00:00:00 2001 From: Ross Satchell Date: Mon, 27 Oct 2025 11:32:32 -0700 Subject: [PATCH 186/208] Update pins.c Changed LED_LEDA to LCD_BL Changed CAN _STANDBY to CAN_STDBY --- .../boards/microchip_curiosity_circuitpython/pins.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c index fd8213a573a14..49c7f7565e26e 100644 --- a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c @@ -44,7 +44,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_LCD_LEDA), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_PA06) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB30) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB31) }, @@ -78,7 +78,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STANDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STDBY), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From 064574d21bec47cf8d5c278f6b18965fee0f556a Mon Sep 17 00:00:00 2001 From: Gustavo Date: Mon, 27 Oct 2025 15:23:31 -0400 Subject: [PATCH 187/208] Fix trailing-whitespace and end-of-files --- .../boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk | 2 +- ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk index dc845ad13990d..421a58976002a 100755 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk @@ -11,4 +11,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 16MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi -CIRCUITPY_ESP_PSRAM_FREQ = 80m \ No newline at end of file +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c index 00ff3557088a1..24891099ab170 100755 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c @@ -90,7 +90,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, // User accessible { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, From 5028d2ce369afb9a083086be6086df3dbb657d87 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Tue, 28 Oct 2025 18:33:56 -0400 Subject: [PATCH 188/208] Remove fallback pin aliases; keep only user-accessible pins --- .../waveshare_esp32_s3_touch_lcd_2_8/pins.c | 47 +++++-------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c index 24891099ab170..0bfb3e940b4de 100755 --- a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c @@ -49,8 +49,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO8) }, // VBAT sense (ADC) // UART header - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, // User accessible + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, // I2C header { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO10) }, @@ -58,7 +58,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { // Boot/User button { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, // Optional Alias + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, // Primary bus pins { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO40) }, // Primary SPI (LCD) @@ -73,37 +73,14 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, - // Fallback mapping for all GPIO pins - { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, // User accessible - { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, - { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, - { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + // User accessible + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From 5a4662c1e58164d9929351037acf566b998c2f55 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Thu, 30 Oct 2025 16:00:42 -0500 Subject: [PATCH 189/208] Add terminalio.Terminal example usage to docstring. Move init function docstring so it appears above the rest of the docs next to the function signature. --- shared-bindings/terminalio/Terminal.c | 53 +++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index f8394dcc17d52..199128e56e925 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -21,7 +21,10 @@ #endif //| class Terminal: -//| """Display a character stream with a TileGrid +//| """Terminal manages tile indices and cursor position based on VT100 commands. The ``font`` should be +//| a `fontio.BuiltinFont` and the ``scroll_area`` TileGrid's bitmap should match the font's bitmap. +//| +//| Display a character stream with a TileGrid //| //| ASCII control: //| @@ -75,6 +78,52 @@ //| +--------+------------+------------+ //| | White | 37 | 47 | //| +--------+------------+------------+ +//| +//| Example Usage: +//| +//| .. code-block:: python +//| +//| import time +//| import displayio +//| import supervisor +//| from displayio import Group, TileGrid +//| from terminalio import FONT, Terminal +//| +//| main_group = Group() +//| display = supervisor.runtime.display +//| font_bb = FONT.get_bounding_box() +//| screen_size = (display.width // font_bb[0], display.height // font_bb[1]) +//| char_size = FONT.get_bounding_box() +//| +//| palette = displayio.Palette(2) +//| palette[0] = 0x000000 +//| palette[1] = 0xffffff +//| +//| tilegrid = TileGrid( +//| bitmap=FONT.bitmap, width=screen_size[0], height=screen_size[1], +//| tile_width=char_size[0], tile_height=char_size[1], pixel_shader=palette) +//| +//| terminal = Terminal(tilegrid, FONT) +//| +//| main_group.append(tilegrid) +//| display.root_group = main_group +//| +//| message = "Hello World\\n" +//| terminal.write(message) +//| +//| print(terminal.cursor_x, terminal.cursor_y) +//| move_cursor = chr(27) + "[10;10H" +//| terminal.write(f"Moving the cursor\\n{move_cursor} To here") +//| +//| cursor_home = chr(27) + f"[{screen_size[1]};0H" +//| terminal.write(cursor_home) +//| i = 1 +//| while True: +//| terminal.write(f"Writing again {i}\\n") +//| i = i + 1 +//| time.sleep(1) +//| +//| //| """ //| //| def __init__( @@ -84,8 +133,6 @@ //| *, //| status_bar: Optional[displayio.TileGrid] = None, //| ) -> None: -//| """Terminal manages tile indices and cursor position based on VT100 commands. The font should be -//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap.""" //| ... //| From 6b458a907eef7f78e7a75ac342e43171f8b4e7b6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 30 Oct 2025 18:23:59 -0400 Subject: [PATCH 190/208] finalisers for SPI; clean up sdcardio; reset all pins after finalisers; avoid USB SD races --- main.c | 15 ++++++ ports/analog/common-hal/busio/SPI.c | 10 +++- ports/analog/supervisor/port.c | 1 - ports/atmel-samd/common-hal/busio/SPI.c | 10 +++- ports/atmel-samd/supervisor/port.c | 2 - ports/broadcom/common-hal/busio/SPI.c | 36 +++++-------- ports/broadcom/common-hal/busio/SPI.h | 2 - ports/broadcom/supervisor/port.c | 3 -- ports/cxd56/common-hal/busio/SPI.c | 6 ++- ports/cxd56/supervisor/port.c | 2 - ports/espressif/common-hal/busio/I2C.c | 5 ++ ports/espressif/common-hal/busio/SPI.c | 43 ++++++++------- ports/espressif/common-hal/busio/SPI.h | 2 - ports/espressif/supervisor/port.c | 5 +- ports/litex/common-hal/microcontroller/Pin.c | 4 ++ ports/litex/supervisor/port.c | 1 - ports/mimxrt10xx/common-hal/busio/SPI.c | 26 ++++----- ports/mimxrt10xx/common-hal/busio/SPI.h | 2 - ports/mimxrt10xx/supervisor/port.c | 6 --- ports/nordic/common-hal/busio/SPI.c | 18 +++---- ports/nordic/common-hal/busio/SPI.h | 2 - ports/nordic/supervisor/port.c | 3 -- ports/raspberrypi/common-hal/busio/SPI.c | 21 ++++---- ports/raspberrypi/common-hal/busio/SPI.h | 2 - ports/raspberrypi/supervisor/port.c | 3 -- ports/renode/common-hal/busio/SPI.c | 3 ++ ports/silabs/common-hal/busio/SPI.c | 19 ++++--- ports/silabs/supervisor/port.c | 3 -- ports/stm/common-hal/busio/SPI.c | 19 +++---- ports/stm/supervisor/port.c | 3 -- py/mpstate.h | 3 ++ shared-bindings/busio/SPI.c | 3 +- shared-bindings/busio/SPI.h | 4 ++ shared-bindings/sdcardio/SDCard.c | 22 ++++++-- shared-bindings/sdcardio/SDCard.h | 2 + shared-module/displayio/__init__.c | 4 ++ shared-module/sdcardio/SDCard.c | 56 +++++++++++++------- shared-module/sdcardio/SDCard.h | 5 +- shared-module/sdcardio/__init__.c | 18 +++---- supervisor/shared/usb/usb_msc_flash.c | 20 ++++--- 40 files changed, 228 insertions(+), 186 deletions(-) diff --git a/main.c b/main.c index 91687ff2f8bc7..f4f67b0434787 100644 --- a/main.c +++ b/main.c @@ -43,6 +43,7 @@ #include "supervisor/shared/external_flash/external_flash.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/Runtime.h" @@ -124,6 +125,7 @@ static void reset_devices(void) { static uint8_t *_heap; static uint8_t *_pystack; +static volatile bool _vm_is_running = false; static const char line_clear[] = "\x1b[2K\x1b[0G"; @@ -207,9 +209,12 @@ static void start_mp(safe_mode_t safe_mode) { // Always return to root common_hal_os_chdir("/"); + + _vm_is_running = true; } static void stop_mp(void) { + _vm_is_running = false; #if MICROPY_VFS // Unmount all heap allocated vfs mounts. @@ -409,8 +414,13 @@ static void cleanup_after_vm(mp_obj_t exception) { // Free the heap last because other modules may reference heap memory and need to shut down. filesystem_flush(); + + // Runs finalisers while shutting down the heap. stop_mp(); + // Don't reset pins until finalisers have run. + reset_all_pins(); + // Let the workflows know we've reset in case they want to restart. supervisor_workflow_reset(); } @@ -513,6 +523,7 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s // Finished executing python code. Cleanup includes filesystem flush and a board reset. + _vm_is_running = false; cleanup_after_vm(_exec_result.exception); _exec_result.exception = NULL; @@ -1201,6 +1212,10 @@ void NORETURN nlr_jump_fail(void *val) { } } +bool vm_is_running(void) { + return _vm_is_running; +} + #ifndef NDEBUG static void NORETURN __fatal_error(const char *msg) { #if CIRCUITPY_DEBUG == 0 diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index b4a519c37a72d..a9bf4aad8df48 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -61,6 +61,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Check for NULL Pointer assert(self); + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + // Assign SPI ID based on pins int spi_id = pinsToSpi(mosi, miso, sck); if (spi_id == -1) { @@ -127,6 +130,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->sck == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + // Deinit SPI obj void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { @@ -138,8 +145,9 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { self->mosi = NULL; self->miso = NULL; - self->sck = NULL; self->nss = NULL; + + common_hal_busio_spi_mark_deinit(self); } // Configures the SPI bus. The SPI object must be locked. diff --git a/ports/analog/supervisor/port.c b/ports/analog/supervisor/port.c index 40e8e1d605038..86d96bc251ba2 100644 --- a/ports/analog/supervisor/port.c +++ b/ports/analog/supervisor/port.c @@ -166,7 +166,6 @@ void reset_cpu(void) { // Reset MCU state void reset_port(void) { - reset_all_pins(); } // Reset to the bootloader diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 5dd7bedebc394..fe53580afdf23 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -53,7 +53,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } // Ensure the object starts in its deinit state. - self->clock_pin = NO_PIN; + common_hal_busio_spi_mark_deinit(self); // Special case for SAMR21 boards. (feather_radiofruit_zigbee) #if defined(PIN_PC19F_SERCOM4_PAD0) @@ -184,18 +184,24 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock_pin == NO_PIN; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock_pin = NO_PIN; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } allow_reset_sercom(self->spi_desc.dev.prvt); + // Mark as deinit early in case we are used in an interrupt. + common_hal_busio_spi_mark_deinit(self); + spi_m_sync_disable(&self->spi_desc); spi_m_sync_deinit(&self->spi_desc); reset_pin_number(self->clock_pin); reset_pin_number(self->MOSI_pin); reset_pin_number(self->MISO_pin); - self->clock_pin = NO_PIN; } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 03c2c2543a7a7..9654a791dbb32 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -411,8 +411,6 @@ void reset_port(void) { reset_ticks(); } - reset_all_pins(); - // Output clocks for debugging. // not supported by SAMD51G; uncomment for SAMD51J or update for 51G // #ifdef SAM_D5X_E5X diff --git a/ports/broadcom/common-hal/busio/SPI.c b/ports/broadcom/common-hal/busio/SPI.c index 2396a9b921ee2..01d61ba9d1d0d 100644 --- a/ports/broadcom/common-hal/busio/SPI.c +++ b/ports/broadcom/common-hal/busio/SPI.c @@ -33,28 +33,6 @@ static SPI1_Type *aux_spi[NUM_SPI] = {NULL, SPI1, SPI2}; static bool never_reset_spi[NUM_SPI]; static bool spi_in_use[NUM_SPI]; -void reset_spi(void) { - for (size_t i = 0; i < NUM_SPI; i++) { - if (never_reset_spi[i]) { - continue; - } - - if (i == 1 || i == 2) { - if (i == 1) { - AUX->ENABLES_b.SPI_1 = false; - } else { - AUX->ENABLES_b.SPI_2 = false; - } - aux_spi[i]->CNTL0 = 0; - } else { - // Set CS back to default. All 0 except read enable. - spi[i]->CS = SPI0_CS_REN_Msk; - } - - spi_in_use[i] = false; - } -} - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -67,6 +45,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError(MP_ERROR_TEXT("Half duplex SPI is not implemented")); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + // BCM_VERSION != 2711 have 3 SPI but as listed in peripherals/gen/pins.c two are on // index 0, once one index 0 SPI is found the other will throw an invalid_pins error. for (size_t i = 0; i < NUM_SPI; i++) { @@ -129,6 +110,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -138,7 +123,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { common_hal_reset_pin(self->clock); common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); - self->clock = NULL; + spi_in_use[self->index] = false; if (self->index == 1 || @@ -149,7 +134,12 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } else if (self->index == 2) { AUX->ENABLES_b.SPI_2 = false; } + } else { + // Set CS back to default. All 0 except read enable. + spi[self->index]->CS = SPI0_CS_REN_Msk; } + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/broadcom/common-hal/busio/SPI.h b/ports/broadcom/common-hal/busio/SPI.h index aec91263677c0..3d52b6b0a4488 100644 --- a/ports/broadcom/common-hal/busio/SPI.h +++ b/ports/broadcom/common-hal/busio/SPI.h @@ -23,5 +23,3 @@ typedef struct { uint8_t bits; uint8_t index; } busio_spi_obj_t; - -void reset_spi(void); diff --git a/ports/broadcom/supervisor/port.c b/ports/broadcom/supervisor/port.c index 83dd50f1b8b52..a0f0be30dd758 100644 --- a/ports/broadcom/supervisor/port.c +++ b/ports/broadcom/supervisor/port.c @@ -67,7 +67,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO reset_i2c(); - reset_spi(); reset_uart(); #endif @@ -85,8 +84,6 @@ void reset_port(void) { #if CIRCUITPY_AUDIOCORE audio_dma_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/cxd56/common-hal/busio/SPI.c b/ports/cxd56/common-hal/busio/SPI.c index 8eedb624201dd..6c49e0f275066 100644 --- a/ports/cxd56/common-hal/busio/SPI.c +++ b/ports/cxd56/common-hal/busio/SPI.c @@ -54,7 +54,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { return; } - self->spi_dev = NULL; + common_hal_busio_spi_mark_deinit(self); reset_pin_number(self->clock_pin->number); reset_pin_number(self->mosi_pin->number); @@ -65,6 +65,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->spi_dev == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->spi_dev = NULL; +} + bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { uint8_t mode; diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c index 75abcbf6d93e0..3dc54df96fbb5 100644 --- a/ports/cxd56/supervisor/port.c +++ b/ports/cxd56/supervisor/port.c @@ -66,8 +66,6 @@ void reset_port(void) { #if CIRCUITPY_RTC rtc_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/espressif/common-hal/busio/I2C.c b/ports/espressif/common-hal/busio/I2C.c index 98c453ba3c086..9ef3877ea92ed 100644 --- a/ports/espressif/common-hal/busio/I2C.c +++ b/ports/espressif/common-hal/busio/I2C.c @@ -128,6 +128,11 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { i2c_del_master_bus(self->handle); self->handle = NULL; + // Release the mutex before we delete it. Otherwise FreeRTOS gets unhappy. + xSemaphoreGive(self->xSemaphore); + vSemaphoreDelete(self->xSemaphore); + self->xSemaphore = NULL; + common_hal_reset_pin(self->sda_pin); common_hal_reset_pin(self->scl_pin); common_hal_busio_i2c_mark_deinit(self); diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 6439ca4112993..3db4c770190de 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -18,24 +18,11 @@ static bool spi_never_reset[SOC_SPI_PERIPH_NUM]; static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM]; -static StaticSemaphore_t spi_mutex[SOC_SPI_PERIPH_NUM]; static bool spi_bus_is_free(spi_host_device_t host_id) { return spi_bus_get_attr(host_id) == NULL; } -void spi_reset(void) { - for (spi_host_device_t host_id = SPI2_HOST; host_id < SOC_SPI_PERIPH_NUM; host_id++) { - if (spi_never_reset[host_id]) { - continue; - } - if (!spi_bus_is_free(host_id)) { - spi_bus_remove_device(spi_handle[host_id]); - spi_bus_free(host_id); - } - } -} - static void set_spi_config(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { // 128 is a 50% duty cycle. @@ -61,6 +48,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + const spi_bus_config_t bus_config = { .mosi_io_num = mosi != NULL ? mosi->number : -1, .miso_io_num = miso != NULL ? miso->number : -1, @@ -83,6 +73,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_ValueError(MP_ERROR_TEXT("All SPI peripherals are in use")); } + self->mutex = xSemaphoreCreateMutex(); + if (self->mutex == NULL) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to create lock")); + } + esp_err_t result = spi_bus_initialize(self->host_id, &bus_config, SPI_DMA_CH_AUTO); if (result == ESP_ERR_NO_MEM) { mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("ESP-IDF memory allocation failed")); @@ -90,6 +85,12 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, raise_ValueError_invalid_pins(); } + self->mutex = xSemaphoreCreateMutex(); + if (self->mutex == NULL) { + spi_bus_free(self->host_id); + mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to create lock")); + } + set_spi_config(self, 250000, 0, 0, 8); self->MOSI = mosi; @@ -103,8 +104,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, claim_pin(miso); } claim_pin(clock); - - self->mutex = xSemaphoreCreateMutexStatic(&spi_mutex[self->host_id]); } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { @@ -122,6 +121,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -132,9 +135,9 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { RUN_BACKGROUND_TASKS; } - // Mark us as deinit early in case we are used in an interrupt. + // Mark as deinit early in case we are used in an interrupt. common_hal_reset_pin(self->clock); - self->clock = NULL; + common_hal_busio_spi_mark_deinit(self); spi_never_reset[self->host_id] = false; spi_bus_remove_device(spi_handle[self->host_id]); @@ -170,11 +173,13 @@ bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { } bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { - return self->mutex != NULL && xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle(); + return (self->mutex != NULL) && (xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle()); } void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { - xSemaphoreGive(self->mutex); + if (self->mutex != NULL) { + xSemaphoreGive(self->mutex); + } } bool common_hal_busio_spi_write(busio_spi_obj_t *self, diff --git a/ports/espressif/common-hal/busio/SPI.h b/ports/espressif/common-hal/busio/SPI.h index 820f29333c756..ac2f404042b2f 100644 --- a/ports/espressif/common-hal/busio/SPI.h +++ b/ports/espressif/common-hal/busio/SPI.h @@ -25,5 +25,3 @@ typedef struct { SemaphoreHandle_t mutex; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index 72c92c98baea2..b67fae426b73f 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -356,14 +356,11 @@ void reset_port(void) { ssl_reset(); #endif - reset_all_pins(); - #if CIRCUITPY_ANALOGIO analogout_reset(); #endif #if CIRCUITPY_BUSIO - spi_reset(); uart_reset(); #endif @@ -417,7 +414,7 @@ void reset_to_bootloader(void) { } void reset_cpu(void) { - #if CIRCUITPY_DEBUG + #if CIRCUITPY_DEBUG || 1 esp_backtrace_print(100); #endif esp_restart(); diff --git a/ports/litex/common-hal/microcontroller/Pin.c b/ports/litex/common-hal/microcontroller/Pin.c index dea848f1ec3f3..bb3636c5b3faa 100644 --- a/ports/litex/common-hal/microcontroller/Pin.c +++ b/ports/litex/common-hal/microcontroller/Pin.c @@ -11,6 +11,10 @@ static uint8_t claimed_pins[1]; +void reset_all_pins(void) { + // TODO +} + // Mark pin as free and return it to a quiescent state. void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { if (pin_port == 0x0F) { diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c index 98fce16152e0b..7f9aab7f7ffb4 100644 --- a/ports/litex/supervisor/port.c +++ b/ports/litex/supervisor/port.c @@ -59,7 +59,6 @@ extern uint32_t _heap_start; extern uint32_t _estack; void reset_port(void) { - // reset_all_pins(); // i2c_reset(); // spi_reset(); // uart_reset(); diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 732b23d8c9b3b..9b988e0d15ef8 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -53,22 +53,6 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) { | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); } -void spi_reset(void) { - for (uint i = 0; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) { - if (!never_reset_spi[i]) { - reserved_spi[i] = false; - #if IMXRT11XX - // Skip resetting SPIs that aren't clocked. Doing so generates a bus fault. - if ((CCM->LPCG[s_lpspiClocks[i + 1]].STATUS0 & CCM_LPCG_STATUS0_ON_MASK) == ((uint32_t)kCLOCK_Off & CCM_LPCG_STATUS0_ON_MASK)) { - continue; - } - #endif - - LPSPI_Deinit(mcu_spi_banks[i]); - } - } -} - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -82,6 +66,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + for (uint i = 0; i < sck_count; i++) { if (mcu_spi_sck_list[i].pin != clock) { continue; @@ -214,6 +201,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -226,9 +217,10 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { common_hal_reset_pin(self->mosi->pin); common_hal_reset_pin(self->miso->pin); - self->clock = NULL; self->mosi = NULL; self->miso = NULL; + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.h b/ports/mimxrt10xx/common-hal/busio/SPI.h index 67801078261c1..d86489428ec78 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.h +++ b/ports/mimxrt10xx/common-hal/busio/SPI.h @@ -21,5 +21,3 @@ typedef struct { const mcu_periph_obj_t *mosi; const mcu_periph_obj_t *miso; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index d7f7f280d1958..62d2569cfde4f 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -425,10 +425,6 @@ safe_mode_t port_init(void) { } void reset_port(void) { - #if CIRCUITPY_BUSIO - spi_reset(); - #endif - #if CIRCUITPY_AUDIOIO audio_dma_reset(); #endif @@ -450,8 +446,6 @@ void reset_port(void) { #endif // reset_event_system(); - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/nordic/common-hal/busio/SPI.c b/ports/nordic/common-hal/busio/SPI.c index 8af4c5f4e83f1..b4fc887aa342d 100644 --- a/ports/nordic/common-hal/busio/SPI.c +++ b/ports/nordic/common-hal/busio/SPI.c @@ -65,15 +65,6 @@ static bool never_reset[MP_ARRAY_SIZE(spim_peripherals)]; // https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; -void spi_reset(void) { - for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { - if (never_reset[i]) { - continue; - } - nrfx_spim_uninit(&spim_peripherals[i].spim); - } -} - void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { if (self->spim_peripheral == &spim_peripherals[i]) { @@ -125,6 +116,9 @@ static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } @@ -178,6 +172,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock_pin_number == NO_PIN; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock_pin_number = NO_PIN; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -188,6 +186,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { reset_pin_number(self->clock_pin_number); reset_pin_number(self->MOSI_pin_number); reset_pin_number(self->MISO_pin_number); + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { diff --git a/ports/nordic/common-hal/busio/SPI.h b/ports/nordic/common-hal/busio/SPI.h index 7bfddd9625dcb..3260c5c27dee2 100644 --- a/ports/nordic/common-hal/busio/SPI.h +++ b/ports/nordic/common-hal/busio/SPI.h @@ -23,5 +23,3 @@ typedef struct { uint8_t MOSI_pin_number; uint8_t MISO_pin_number; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/nordic/supervisor/port.c b/ports/nordic/supervisor/port.c index ed371c6ad8582..1eabfcbe2166b 100644 --- a/ports/nordic/supervisor/port.c +++ b/ports/nordic/supervisor/port.c @@ -189,7 +189,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO - spi_reset(); uart_reset(); #endif @@ -216,8 +215,6 @@ void reset_port(void) { nrfx_gpiote_uninit(); } nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index 4735d1284f98e..21af168df3b73 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -20,23 +20,15 @@ #define NO_INSTANCE 0xff static bool never_reset_spi[2]; -static spi_inst_t *spi[2] = {spi0, spi1}; - -void reset_spi(void) { - for (size_t i = 0; i < 2; i++) { - if (never_reset_spi[i]) { - continue; - } - - spi_deinit(spi[i]); - } -} void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { size_t instance_index = NO_INSTANCE; + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } @@ -107,6 +99,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -117,7 +113,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { common_hal_reset_pin(self->clock); common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); - self->clock = NULL; + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/raspberrypi/common-hal/busio/SPI.h b/ports/raspberrypi/common-hal/busio/SPI.h index 8510eb7693ae2..3d43c1eff0072 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.h +++ b/ports/raspberrypi/common-hal/busio/SPI.h @@ -25,5 +25,3 @@ typedef struct { uint8_t phase; uint8_t bits; } busio_spi_obj_t; - -void reset_spi(void); diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 66e63248c4810..5cfbdfa66a32b 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -422,7 +422,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO - reset_spi(); reset_uart(); #endif @@ -453,8 +452,6 @@ void reset_port(void) { #if CIRCUITPY_WIFI wifi_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/renode/common-hal/busio/SPI.c b/ports/renode/common-hal/busio/SPI.c index 6f5f60506074f..1f66fc5ec4af1 100644 --- a/ports/renode/common-hal/busio/SPI.c +++ b/ports/renode/common-hal/busio/SPI.c @@ -21,6 +21,9 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return true; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; diff --git a/ports/silabs/common-hal/busio/SPI.c b/ports/silabs/common-hal/busio/SPI.c index 74cfc69bfb2a0..fcff2031fa267 100644 --- a/ports/silabs/common-hal/busio/SPI.c +++ b/ports/silabs/common-hal/busio/SPI.c @@ -39,15 +39,6 @@ static SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; static bool in_used = false; static bool never_reset = false; -// Reset SPI when reload -void spi_reset(void) { - if (!never_reset && in_used) { - SPIDRV_DeInit(&spidrv_eusart_handle); - in_used = false; - } - return; -} - // Construct SPI protocol, this function init SPI peripheral void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *sck, @@ -61,6 +52,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, MP_ERROR_TEXT("Half duplex SPI is not implemented")); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { if (sck->function_list[FN_EUSART1_SCLK] == 1 && miso->function_list[FN_EUSART1_RX] == 1 @@ -119,6 +113,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->sck == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + // Deinit SPI obj void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { @@ -132,13 +130,14 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } in_used = false; - self->sck = NULL; self->mosi = NULL; self->miso = NULL; self->handle = NULL; common_hal_reset_pin(self->mosi); common_hal_reset_pin(self->miso); common_hal_reset_pin(self->sck); + + common_hal_busio_spi_mark_deinit(self); } // Configures the SPI bus. The SPI object must be locked. diff --git a/ports/silabs/supervisor/port.c b/ports/silabs/supervisor/port.c index 2409e907deac1..85a6e0f92a5ec 100644 --- a/ports/silabs/supervisor/port.c +++ b/ports/silabs/supervisor/port.c @@ -156,10 +156,7 @@ safe_mode_t port_init(void) { } void reset_port(void) { - reset_all_pins(); - #if CIRCUITPY_BUSIO - spi_reset(); uart_reset(); #endif diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 98696271ca93a..347e94bef9ff9 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -76,18 +76,6 @@ static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t *prescaler, ui return SPI_BAUDRATEPRESCALER_256; } -void spi_reset(void) { - uint16_t never_reset_mask = 0x00; - for (int i = 0; i < MAX_SPI; i++) { - if (!never_reset_spi[i]) { - reserved_spi[i] = false; - } else { - never_reset_mask |= 1 << i; - } - } - spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask)); -} - static const mcu_periph_obj_t *find_pin_function(const mcu_periph_obj_t *table, size_t sz, const mcu_pin_obj_t *pin, int periph_index) { for (size_t i = 0; i < sz; i++, table++) { if (periph_index == table->periph_index && pin == table->pin) { @@ -152,6 +140,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, int periph_index = check_pins(self, sck, mosi, miso); SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1]; + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + // Start GPIO for each pin GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = pin_mask(sck->number); @@ -238,6 +229,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->sck == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; diff --git a/ports/stm/supervisor/port.c b/ports/stm/supervisor/port.c index c5a1685a7fddc..3820a046fc4af 100644 --- a/ports/stm/supervisor/port.c +++ b/ports/stm/supervisor/port.c @@ -302,14 +302,11 @@ void SysTick_Handler(void) { } void reset_port(void) { - reset_all_pins(); - #if CIRCUITPY_RTC rtc_reset(); #endif #if CIRCUITPY_BUSIO - spi_reset(); uart_reset(); #endif #if CIRCUITPY_SDIOIO diff --git a/py/mpstate.h b/py/mpstate.h index 4c48e9edaf4bd..e5e5f8d9fa3d1 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -369,4 +369,7 @@ extern mp_state_thread_t *mp_thread_get_state(void); #define mp_thread_is_main_thread() (true) #endif +// CIRCUITPY-CHANGE: defined in main.c +bool vm_is_running(void); + #endif // MICROPY_INCLUDED_PY_MPSTATE_H diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 0c8ae1bfdd72c..1513a7cf0944a 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -88,7 +88,7 @@ // TODO(tannewt): Support LSB SPI. static mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_SPI - busio_spi_obj_t *self = mp_obj_malloc(busio_spi_obj_t, &busio_spi_type); + busio_spi_obj_t *self = mp_obj_malloc_with_finaliser(busio_spi_obj_t, &busio_spi_type); enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -466,6 +466,7 @@ MP_PROPERTY_GETTER(busio_spi_frequency_obj, static const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { #if CIRCUITPY_BUSIO_SPI { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_spi_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 69e582411a169..34f34c927f613 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -22,6 +22,10 @@ extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); +// Mark as deinit without deiniting. This is used by displayio after copying the +// object elsewhere and prevents the heap from deiniting the object. +extern void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self); + extern bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); extern bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self); diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index e6d8453eae108..26892a79462d3 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -9,7 +9,8 @@ #include "py/objarray.h" #include "shared-bindings/sdcardio/SDCard.h" -#include "shared-module/sdcardio/SDCard.h" +#include "shared-bindings/util.h" + #include "common-hal/busio/SPI.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/microcontroller/Pin.h" @@ -58,6 +59,12 @@ //| os.listdir('/sd')""" //| +static void check_for_deinit(sdcardio_sdcard_obj_t *self) { + if (common_hal_sdcardio_sdcard_deinited(self)) { + raise_deinited_error(); + } +} + static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi, ARG_cs, ARG_baudrate, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -72,7 +79,7 @@ static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj, MP_QSTR_spi); const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); - sdcardio_sdcard_obj_t *self = mp_obj_malloc(sdcardio_sdcard_obj_t, &sdcardio_SDCard_type); + sdcardio_sdcard_obj_t *self = mp_obj_malloc_with_finaliser(sdcardio_sdcard_obj_t, &sdcardio_SDCard_type); common_hal_sdcardio_sdcard_construct(self, spi, cs, args[ARG_baudrate].u_int); @@ -89,6 +96,7 @@ static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg //| static mp_obj_t sdcardio_sdcard_count(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); return mp_obj_new_int_from_ull(common_hal_sdcardio_sdcard_get_blockcount(self)); } MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); @@ -116,10 +124,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit); //| static mp_obj_t _sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); + uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; int result = common_hal_sdcardio_sdcard_readblocks(self, start_block, &bufinfo); if (result < 0) { mp_raise_OSError(-result); @@ -137,6 +147,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, _sdcardio_sdcard_readb //| static mp_obj_t sdcardio_sdcard_sync(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); int result = common_hal_sdcardio_sdcard_sync(self); if (result < 0) { mp_raise_OSError(-result); @@ -158,10 +169,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_sync_obj, sdcardio_sdcard_sync); //| static mp_obj_t _sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); + uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; int result = common_hal_sdcardio_sdcard_writeblocks(self, start_block, &bufinfo); if (result < 0) { mp_raise_OSError(-result); @@ -173,6 +186,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, _sdcardio_sdcard_writ static const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdcardio_sdcard_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&sdcardio_sdcard_sync_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdcardio_sdcard_writeblocks_obj) }, diff --git a/shared-bindings/sdcardio/SDCard.h b/shared-bindings/sdcardio/SDCard.h index ac27b47aa4d21..95998f5af5e90 100644 --- a/shared-bindings/sdcardio/SDCard.h +++ b/shared-bindings/sdcardio/SDCard.h @@ -13,7 +13,9 @@ extern const mp_obj_type_t sdcardio_SDCard_type; void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *cs, int baudrate); void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self); +bool common_hal_sdcardio_sdcard_deinited(sdcardio_sdcard_obj_t *self); void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self); +void common_hal_sdcardio_sdcard_mark_deinit(sdcardio_sdcard_obj_t *self); int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self); int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index f3444241b3cca..3ffd4d002f534 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -13,6 +13,7 @@ #include "py/runtime.h" #include "shared-bindings/board/__init__.h" #include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/SPI.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" @@ -221,6 +222,7 @@ void reset_displays(void) { #endif memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); fourwire->bus = &fourwire->inline_bus; + // Check for other display buses that use the same spi bus and swap them too. for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { if (display_buses[j].fourwire_bus.base.type == &fourwire_fourwire_type && @@ -228,6 +230,8 @@ void reset_displays(void) { display_buses[j].fourwire_bus.bus = &fourwire->inline_bus; } } + // Mark the old SPI object so it is considered deinit. + common_hal_busio_spi_mark_deinit(original_spi); } #endif #if CIRCUITPY_I2CDISPLAYBUS diff --git a/shared-module/sdcardio/SDCard.c b/shared-module/sdcardio/SDCard.c index bd3ea62d141e5..878fed7a13c9b 100644 --- a/shared-module/sdcardio/SDCard.c +++ b/shared-module/sdcardio/SDCard.c @@ -32,18 +32,41 @@ #define TOKEN_STOP_TRAN (0xFD) #define TOKEN_DATA (0xFE) +bool common_hal_sdcardio_sdcard_deinited(sdcardio_sdcard_obj_t *self) { + // Also check SPI bus was deinited out from under us. + if (!self->bus || common_hal_busio_spi_deinited(self->bus)) { + return true; + } + return false; +} + +void common_hal_sdcardio_sdcard_mark_deinit(sdcardio_sdcard_obj_t *self) { + self->bus = NULL; +} + static void common_hal_sdcardio_check_for_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { + if (common_hal_sdcardio_sdcard_deinited(self)) { raise_deinited_error(); } } static bool lock_and_configure_bus(sdcardio_sdcard_obj_t *self) { + if (common_hal_sdcardio_sdcard_deinited(self)) { + return false; + } common_hal_sdcardio_check_for_deinit(self); if (!common_hal_busio_spi_try_lock(self->bus)) { return false; } + + // Make sure we can still use the SPI bus after grabbing the lock. + // The VM might be in the process of shutting down, and there could be a race. + if (!vm_is_running() && !self->persistent_mount) { + common_hal_busio_spi_unlock(self->bus); + return false; + } + common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8); common_hal_digitalio_digitalinout_set_value(&self->cs, false); return true; @@ -97,7 +120,7 @@ static int wait_for_ready(sdcardio_sdcard_obj_t *self) { } // Note: this is never called while "in cmd25" (in fact, it's only used by `exit_cmd25`) -static bool cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { +static int cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { uint8_t cmdbuf[2] = {cmd, 0xff}; assert(!self->in_cmd25); @@ -111,7 +134,7 @@ static bool cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { return 0; } } - return -EIO; + return -MP_EIO; } @@ -160,7 +183,7 @@ static int cmd(sdcardio_sdcard_obj_t *self, int cmd, int arg, void *response_buf } if (!response_received) { - return -EIO; + return -MP_EIO; } if (response_buf) { @@ -294,13 +317,16 @@ static mp_rom_error_text_t init_card(sdcardio_sdcard_obj_t *self) { return NULL; } -mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) { +mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate, bool persistent_mount) { self->bus = bus; + self->persistent_mount = persistent_mount; common_hal_digitalio_digitalinout_construct(&self->cs, cs); common_hal_digitalio_digitalinout_switch_to_output(&self->cs, true, DRIVE_MODE_PUSH_PULL); self->cdv = 512; self->sectors = 0; + + // During initialization, talk to the SPI card between 100 khZ and 400 kHz. After that, can use full speed. self->baudrate = 250000; lock_bus_or_throw(self); @@ -318,18 +344,19 @@ mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) { - mp_rom_error_text_t result = sdcardio_sdcard_construct(self, bus, cs, baudrate); + // User mounted, so persistent_mount=false. + mp_rom_error_text_t result = sdcardio_sdcard_construct(self, bus, cs, baudrate, false); if (result != NULL) { mp_raise_OSError_msg(result); } } void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { + if (common_hal_sdcardio_sdcard_deinited(self)) { return; } common_hal_sdcardio_sdcard_sync(self); - self->bus = 0; + common_hal_sdcardio_sdcard_mark_deinit(self); common_hal_digitalio_digitalinout_deinit(&self->cs); } @@ -428,7 +455,7 @@ static int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t DEBUG_PRINT("i=%02d cmd[0] = 0x%02x\n", i, cmd[0]); if ((cmd[0] & 0b00010001) == 0b00000001) { if ((cmd[0] & 0x1f) != 0x5) { - return -EIO; + return -MP_EIO; } else { break; } @@ -489,14 +516,10 @@ int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self) { } int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - // deinit check is in lock_and_configure_bus() if (buf->len % 512 != 0) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), 512); } - lock_and_configure_bus(self); - int r = sdcardio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512); - extraclock_and_unlock_bus(self); - return r; + return sdcardio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512); } bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) { @@ -504,11 +527,8 @@ bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *o *out_value = 0; switch (cmd) { case MP_BLOCKDEV_IOCTL_DEINIT: - common_hal_sdcardio_sdcard_sync(self); - break; // TODO properly case MP_BLOCKDEV_IOCTL_SYNC: - common_hal_sdcardio_sdcard_sync(self); - break; + return common_hal_sdcardio_sdcard_sync(self) == 0; case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: *out_value = common_hal_sdcardio_sdcard_get_blockcount(self); break; diff --git a/shared-module/sdcardio/SDCard.h b/shared-module/sdcardio/SDCard.h index f9cd64b812532..35a9ed1bf3c12 100644 --- a/shared-module/sdcardio/SDCard.h +++ b/shared-module/sdcardio/SDCard.h @@ -23,6 +23,9 @@ typedef struct { uint32_t sectors; uint32_t next_block; bool in_cmd25; + // Automounted SD cards are usually persistent across VM's. Note this as needed to allow access + // when the VM is not running. + bool persistent_mount; } sdcardio_sdcard_obj_t; -mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate); +mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate, bool persistent_mount); diff --git a/shared-module/sdcardio/__init__.c b/shared-module/sdcardio/__init__.c index 29c890c6870c1..4a7a4d500cc3f 100644 --- a/shared-module/sdcardio/__init__.c +++ b/shared-module/sdcardio/__init__.c @@ -22,7 +22,7 @@ static mp_vfs_mount_t _sdcard_vfs; fs_user_mount_t _sdcard_usermount; static bool _init_error = false; -static bool _mounted = false; +static bool _automounted = false; #ifdef DEFAULT_SD_MOSI static busio_spi_obj_t busio_spi_obj; @@ -45,7 +45,7 @@ void automount_sd_card(void) { if (common_hal_digitalio_digitalinout_get_value(&sd_card_detect_pin) != DEFAULT_SD_CARD_INSERTED) { // No card. _init_error = false; - if (_mounted) { + if (_automounted) { // Unmount the card. mp_vfs_mount_t *cur = MP_STATE_VM(vfs_mount_table); if (cur == &_sdcard_vfs) { @@ -63,11 +63,11 @@ void automount_sd_card(void) { #ifdef DEFAULT_SD_MOSI common_hal_busio_spi_deinit(&busio_spi_obj); #endif - _mounted = false; + _automounted = false; } return; - } else if (_init_error || _mounted) { - // We've already tried and failed to init the card. Don't try again. + } else if (_init_error || _automounted) { + // We've already tried and failed to init the card, or it's still mounted. Don't try again. return; } @@ -81,10 +81,10 @@ void automount_sd_card(void) { common_hal_busio_spi_never_reset(spi_obj); #endif sdcard.base.type = &sdcardio_SDCard_type; - mp_rom_error_text_t error = sdcardio_sdcard_construct(&sdcard, spi_obj, DEFAULT_SD_CS, 25000000); + mp_rom_error_text_t error = sdcardio_sdcard_construct(&sdcard, spi_obj, DEFAULT_SD_CS, 25000000, true); if (error != NULL) { // Failed to communicate with the card. - _mounted = false; + _automounted = false; _init_error = true; #ifdef DEFAULT_SD_MOSI common_hal_busio_spi_deinit(spi_obj); @@ -104,7 +104,7 @@ void automount_sd_card(void) { // mount the block device so the VFS methods can be used FRESULT res = f_mount(&vfs->fatfs); if (res != FR_OK) { - _mounted = false; + _automounted = false; _init_error = true; common_hal_sdcardio_sdcard_deinit(&sdcard); #ifdef DEFAULT_SD_MOSI @@ -122,6 +122,6 @@ void automount_sd_card(void) { sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); MP_STATE_VM(vfs_mount_table) = sdcard_vfs; - _mounted = true; + _automounted = true; #endif // DEFAULT_SD_CARD_DETECT } diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index febede876bbf5..adc182497617c 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -5,7 +5,6 @@ // SPDX-License-Identifier: MIT #include "tusb.h" -// // #include "supervisor/flash.h" // For updating fatfs's cache #include "extmod/vfs.h" @@ -14,6 +13,7 @@ #include "lib/oofatfs/ff.h" #include "py/gc.h" #include "py/mpstate.h" +#include "py/runtime.h" #include "shared-module/storage/__init__.h" #include "supervisor/filesystem.h" @@ -28,7 +28,7 @@ #define SAVES_COUNT 0 #endif -#if CIRCUITPY_SDCARDIO +#if CIRCUITPY_SDCARD_USB #include "shared-module/sdcardio/__init__.h" #define SDCARD_COUNT 1 @@ -137,7 +137,8 @@ static fs_user_mount_t *get_vfs(int lun) { if (lun == SAVES_LUN) { const char *path_under_mount; fs_user_mount_t *saves = filesystem_for_path("/saves", &path_under_mount); - if (saves != root && (saves->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0 && !gc_ptr_on_heap(saves)) { + if (saves != root && + (saves->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0 && !gc_ptr_on_heap(saves)) { return saves; } } @@ -146,8 +147,15 @@ static fs_user_mount_t *get_vfs(int lun) { if (lun == SDCARD_LUN) { const char *path_under_mount; fs_user_mount_t *sdcard = filesystem_for_path("/sd", &path_under_mount); - // If "/sd" is on the root filesystem, nothing has been mounted there. - if (sdcard != root && (sdcard->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0) { + // If sdcard ("/sd") is on the root filesystem, nothing has been mounted there, so don't + // return it as a separate filesystem. + // If the SD card was automounted at startup, then it persists across VMs and its fs_user_mount_t is + // not on the heap. + // If the SD card filesystem was mounted by the user using heap objects, + // it should not be used when the VM has stopped running. + if ((sdcard != root) && + ((sdcard->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0) && + (vm_is_running() || !gc_ptr_on_heap(sdcard))) { return sdcard; } else { // Clear any ejected state so that a re-insert causes it to reappear. @@ -359,7 +367,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { return false; } - #if CIRCUITPY_SDCARD_USB + #ifdef SDCARD_LUN if (lun == SDCARD_LUN) { automount_sd_card(); } From 2800777933166cf35ead80ec11743deb6ca79dfa Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 31 Oct 2025 14:50:34 -0400 Subject: [PATCH 191/208] remove local tracking of never_reset in all common-hal/busio/SPI.c --- ports/analog/common-hal/busio/SPI.c | 3 --- ports/broadcom/common-hal/busio/SPI.c | 4 ---- ports/espressif/common-hal/busio/SPI.c | 3 --- ports/espressif/supervisor/port.c | 2 +- ports/mimxrt10xx/common-hal/busio/SPI.c | 3 --- ports/nordic/common-hal/busio/SPI.c | 4 ---- ports/raspberrypi/common-hal/busio/SPI.c | 5 ----- ports/silabs/common-hal/busio/SPI.c | 2 -- ports/stm/common-hal/busio/SPI.c | 3 --- 9 files changed, 1 insertion(+), 28 deletions(-) diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c index a9bf4aad8df48..de3856b23b3f1 100644 --- a/ports/analog/common-hal/busio/SPI.c +++ b/ports/analog/common-hal/busio/SPI.c @@ -42,7 +42,6 @@ typedef enum { SPI_FREE = 0, SPI_BUSY, - SPI_NEVER_RESET, } spi_status_t; // Set each bit to indicate an active SPI @@ -121,8 +120,6 @@ void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { common_hal_never_reset_pin(self->miso); common_hal_never_reset_pin(self->sck); common_hal_never_reset_pin(self->nss); - - spi_status[self->spi_id] = SPI_NEVER_RESET; } // Check SPI status, deinited or not diff --git a/ports/broadcom/common-hal/busio/SPI.c b/ports/broadcom/common-hal/busio/SPI.c index 01d61ba9d1d0d..9e4834e86f352 100644 --- a/ports/broadcom/common-hal/busio/SPI.c +++ b/ports/broadcom/common-hal/busio/SPI.c @@ -30,7 +30,6 @@ static SPI0_Type *spi[NUM_SPI] = {SPI0, NULL, NULL}; static SPI1_Type *aux_spi[NUM_SPI] = {NULL, SPI1, SPI2}; #endif -static bool never_reset_spi[NUM_SPI]; static bool spi_in_use[NUM_SPI]; void common_hal_busio_spi_construct(busio_spi_obj_t *self, @@ -99,8 +98,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->index] = true; - common_hal_never_reset_pin(self->clock); common_hal_never_reset_pin(self->MOSI); common_hal_never_reset_pin(self->MISO); @@ -118,7 +115,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } - never_reset_spi[self->index] = false; common_hal_reset_pin(self->clock); common_hal_reset_pin(self->MOSI); diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 3db4c770190de..4c07917b20b86 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -16,7 +16,6 @@ #define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8) #define MAX_SPI_TRANSACTIONS 10 -static bool spi_never_reset[SOC_SPI_PERIPH_NUM]; static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM]; static bool spi_bus_is_free(spi_host_device_t host_id) { @@ -107,7 +106,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - spi_never_reset[self->host_id] = true; common_hal_never_reset_pin(self->clock); if (self->MOSI != NULL) { common_hal_never_reset_pin(self->MOSI); @@ -139,7 +137,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { common_hal_reset_pin(self->clock); common_hal_busio_spi_mark_deinit(self); - spi_never_reset[self->host_id] = false; spi_bus_remove_device(spi_handle[self->host_id]); spi_bus_free(self->host_id); diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index b67fae426b73f..c629eb52932e7 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -414,7 +414,7 @@ void reset_to_bootloader(void) { } void reset_cpu(void) { - #if CIRCUITPY_DEBUG || 1 + #if CIRCUITPY_DEBUG esp_backtrace_print(100); #endif esp_restart(); diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 9b988e0d15ef8..90695be4b4e6d 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -26,7 +26,6 @@ // arrays use 0 based numbering: SPI1 is stored at index 0 static bool reserved_spi[MP_ARRAY_SIZE(mcu_spi_banks)]; -static bool never_reset_spi[MP_ARRAY_SIZE(mcu_spi_banks)]; #if IMXRT11XX static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS; @@ -187,7 +186,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->clock->bank_idx - 1] = true; common_hal_never_reset_pin(self->clock->pin); if (self->mosi != NULL) { common_hal_never_reset_pin(self->mosi->pin); @@ -211,7 +209,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } LPSPI_Deinit(self->spi); reserved_spi[self->clock->bank_idx - 1] = false; - never_reset_spi[self->clock->bank_idx - 1] = false; common_hal_reset_pin(self->clock->pin); common_hal_reset_pin(self->mosi->pin); diff --git a/ports/nordic/common-hal/busio/SPI.c b/ports/nordic/common-hal/busio/SPI.c index b4fc887aa342d..de54dd08a2783 100644 --- a/ports/nordic/common-hal/busio/SPI.c +++ b/ports/nordic/common-hal/busio/SPI.c @@ -59,8 +59,6 @@ static const spim_peripheral_t spim_peripherals[] = { #endif }; -static bool never_reset[MP_ARRAY_SIZE(spim_peripherals)]; - // Separate RAM area for SPIM3 transmit buffer to avoid SPIM3 hardware errata. // https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; @@ -68,8 +66,6 @@ static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { if (self->spim_peripheral == &spim_peripherals[i]) { - never_reset[i] = true; - never_reset_pin_number(self->clock_pin_number); never_reset_pin_number(self->MOSI_pin_number); never_reset_pin_number(self->MISO_pin_number); diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index 21af168df3b73..aeb06d919ae45 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -19,8 +19,6 @@ #define NO_INSTANCE 0xff -static bool never_reset_spi[2]; - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -88,8 +86,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[spi_get_index(self->peripheral)] = true; - common_hal_never_reset_pin(self->clock); common_hal_never_reset_pin(self->MOSI); common_hal_never_reset_pin(self->MISO); @@ -107,7 +103,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } - never_reset_spi[spi_get_index(self->peripheral)] = false; spi_deinit(self->peripheral); common_hal_reset_pin(self->clock); diff --git a/ports/silabs/common-hal/busio/SPI.c b/ports/silabs/common-hal/busio/SPI.c index fcff2031fa267..fb3b7c4fd20c7 100644 --- a/ports/silabs/common-hal/busio/SPI.c +++ b/ports/silabs/common-hal/busio/SPI.c @@ -37,7 +37,6 @@ static SPIDRV_HandleData_t spidrv_eusart_handle; static SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; static bool in_used = false; -static bool never_reset = false; // Construct SPI protocol, this function init SPI peripheral void common_hal_busio_spi_construct(busio_spi_obj_t *self, @@ -102,7 +101,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Never reset SPI when reload void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset = true; common_hal_never_reset_pin(self->mosi); common_hal_never_reset_pin(self->miso); common_hal_never_reset_pin(self->sck); diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 347e94bef9ff9..1b86a9f55d5d4 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -19,7 +19,6 @@ #define MAX_SPI 6 static bool reserved_spi[MAX_SPI]; -static bool never_reset_spi[MAX_SPI]; #define ALL_CLOCKS 0xFF static void spi_clock_enable(uint8_t mask); @@ -215,7 +214,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->sck->periph_index - 1] = true; never_reset_pin_number(self->sck->pin->port, self->sck->pin->number); if (self->mosi != NULL) { never_reset_pin_number(self->mosi->pin->port, self->mosi->pin->number); @@ -239,7 +237,6 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } spi_clock_disable(1 << (self->sck->periph_index - 1)); reserved_spi[self->sck->periph_index - 1] = false; - never_reset_spi[self->sck->periph_index - 1] = false; reset_pin_number(self->sck->pin->port, self->sck->pin->number); if (self->mosi != NULL) { From 85e145f203d1d2f1cef2169b1af7103430d156a8 Mon Sep 17 00:00:00 2001 From: chinh4thepro Date: Sun, 2 Nov 2025 00:46:55 -0400 Subject: [PATCH 192/208] ports/espressif: add pins for seeed xiao esp32s3 plus board ports/espressif/boards: add pins for seeed xiao esp32s3 plus --- .../seeed_xiao_esp32_s3_sense/mpconfigboard.h | 10 +++++----- .../boards/seeed_xiao_esp32_s3_sense/pins.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h index c05b6a93a1054..d7f24b255d69c 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h @@ -12,9 +12,9 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO7) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO9) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO9) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO6) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index aa3a6f7b7f577..8269f1d7a951e 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -48,15 +48,30 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_TX_1), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_RX_1), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_MOSI_1), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_MISO_1), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCK_1), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO17) }, @@ -74,6 +89,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, From 4c4a1888b09e02ca08f0d4b76f9b2aac3db3a627 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 17 Oct 2025 12:36:18 -0700 Subject: [PATCH 193/208] Add mipidsi module for MIPI DSI displays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for MIPI DSI (Display Serial Interface) displays via a new mipidsi module. This enables high-speed serial communication with DSI displays using differential signaling. The module provides: - Bus class: Manages DSI bus with 1-4 data lanes - Display class: Handles display configuration and framebuffer Module is: - Disabled by default globally - Enabled only for ESP32-P4 (has hardware MIPI-DSI support) 🤖 Initial code generated with [Claude Code](https://claude.com/claude-code) and then hand improved. Co-Authored-By: Claude --- locale/circuitpython.pot | 17 +- ports/espressif/Makefile | 17 +- .../mpconfigboard.h | 7 +- .../espressif_esp32p4_function_ev/pins.c | 93 +++--- ports/espressif/boards/m5stack_tab5/board.c | 9 + .../boards/m5stack_tab5/mpconfigboard.h | 28 ++ .../boards/m5stack_tab5/mpconfigboard.mk | 14 + ports/espressif/boards/m5stack_tab5/pins.c | 128 ++++++++ ports/espressif/boards/m5stack_tab5/sdkconfig | 0 .../common-hal/microcontroller/Pin.c | 15 +- ports/espressif/common-hal/mipidsi/Bus.c | 52 ++++ ports/espressif/common-hal/mipidsi/Bus.h | 17 ++ ports/espressif/common-hal/mipidsi/Display.c | 254 +++++++++++++++ ports/espressif/common-hal/mipidsi/Display.h | 37 +++ ports/espressif/common-hal/mipidsi/__init__.c | 7 + ports/espressif/common-hal/mipidsi/__init__.h | 7 + ports/espressif/mpconfigport.mk | 3 + ports/espressif/supervisor/port.c | 2 +- py/circuitpy_defns.mk | 6 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/mipidsi/Bus.c | 96 ++++++ shared-bindings/mipidsi/Bus.h | 15 + shared-bindings/mipidsi/Display.c | 289 ++++++++++++++++++ shared-bindings/mipidsi/Display.h | 44 +++ shared-bindings/mipidsi/__init__.c | 30 ++ shared-bindings/mipidsi/__init__.h | 7 + shared-module/displayio/__init__.h | 6 + 27 files changed, 1153 insertions(+), 50 deletions(-) create mode 100644 ports/espressif/boards/m5stack_tab5/board.c create mode 100644 ports/espressif/boards/m5stack_tab5/mpconfigboard.h create mode 100644 ports/espressif/boards/m5stack_tab5/mpconfigboard.mk create mode 100644 ports/espressif/boards/m5stack_tab5/pins.c create mode 100644 ports/espressif/boards/m5stack_tab5/sdkconfig create mode 100644 ports/espressif/common-hal/mipidsi/Bus.c create mode 100644 ports/espressif/common-hal/mipidsi/Bus.h create mode 100644 ports/espressif/common-hal/mipidsi/Display.c create mode 100644 ports/espressif/common-hal/mipidsi/Display.h create mode 100644 ports/espressif/common-hal/mipidsi/__init__.c create mode 100644 ports/espressif/common-hal/mipidsi/__init__.h create mode 100644 shared-bindings/mipidsi/Bus.c create mode 100644 shared-bindings/mipidsi/Bus.h create mode 100644 shared-bindings/mipidsi/Display.c create mode 100644 shared-bindings/mipidsi/Display.h create mode 100644 shared-bindings/mipidsi/__init__.c create mode 100644 shared-bindings/mipidsi/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1e167c30353dd..35fc94513a547 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -159,10 +159,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -838,6 +834,10 @@ msgstr "" msgid "Clock unit in use" msgstr "" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -932,6 +932,7 @@ msgstr "" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -1276,7 +1277,8 @@ msgstr "" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2266,6 +2268,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "" @@ -3174,10 +3177,6 @@ msgstr "" msgid "file write is not available" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "" diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index b6ddc27e4084c..8302726aad7a4 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -76,6 +76,7 @@ INC += \ -isystem esp-idf/components/esp_driver_uart/include \ -isystem esp-idf/components/esp_event/include \ -isystem esp-idf/components/esp_hw_support/dma/include \ + -isystem esp-idf/components/esp_hw_support/ldo/include \ -isystem esp-idf/components/esp_hw_support/include \ -isystem esp-idf/components/esp_hw_support/include/soc \ -isystem esp-idf/components/esp_hw_support/port/$(IDF_TARGET)/private_include \ @@ -171,7 +172,8 @@ REGISTRATION_FUNCTIONS = \ -u esp_libc_init_funcs \ -u include_esp_phy_override \ -u vfs_include_syscalls_impl \ - -u esp_vfs_include_nullfs_register + -u esp_vfs_include_nullfs_register \ + -u usb_serial_jtag_vfs_include_dev_init #Debugging/Optimization @@ -329,7 +331,8 @@ LDFLAGS += \ CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_tsens \ + esp_driver_usb_serial_jtag else ifeq ($(IDF_TARGET),esp32h2) LDFLAGS += \ @@ -467,6 +470,13 @@ CFLAGS += \ -isystem esp-idf/components/esp_lcd/rgb/include endif +ifneq ($(CIRCUITPY_MIPIDSI),0) +CFLAGS += \ + -isystem esp-idf/components/esp_lcd/include \ + -isystem esp-idf/components/esp_lcd/interface \ + -isystem esp-idf/components/esp_lcd/dsi/include +endif + ifneq ($(CIRCUITPY_ESPCAMERA),0) SRC_CAMERA := \ $(wildcard common-hal/espcamera/*.c) \ @@ -757,6 +767,9 @@ endif ifneq ($(CIRCUITPY_DOTCLOCKFRAMEBUFFER),0) ESP_IDF_COMPONENTS_LINK += esp_lcd endif +ifneq ($(CIRCUITPY_MIPIDSI),0) + ESP_IDF_COMPONENTS_LINK += esp_lcd +endif ifneq ($(CIRCUITPY_PARALLELDISPLAYBUS),0) ESP_IDF_COMPONENTS_LINK += esp_lcd endif diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h index 646fb62e5623e..1bbf3a250fcd2 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h @@ -1,6 +1,6 @@ // This file is part of the CircuitPython project: https://circuitpython.org // -// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries // // SPDX-License-Identifier: MIT @@ -16,5 +16,10 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO38) #define DEFAULT_UART_BUS_TX (&pin_GPIO37) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO8) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO7) + // Use the second USB device (numbered 0 and 1) #define CIRCUITPY_USB_DEVICE_INSTANCE 1 + +#define CIRCUITPY_USB_HOST_INSTANCE 0 diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c index 3bb64f434d02f..7a3026f914dd9 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c @@ -1,6 +1,6 @@ // This file is part of the CircuitPython project: https://circuitpython.org // -// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries // // SPDX-License-Identifier: MIT @@ -9,47 +9,72 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + // Header Block J1 + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, - { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, - { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_C6_WAKEUP), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_C6_EN), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_IO54), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_PA_CTRL), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_IO53), MP_ROM_PTR(&pin_GPIO53) }, { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + // I2S + { MP_ROM_QSTR(MP_QSTR_I2S_DSDIN), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO13) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_RMII_RXDV), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD0), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD1), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_MDC), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD0), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD1), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXEN), MP_ROM_PTR(&pin_GPIO49) }, + { MP_ROM_QSTR(MP_QSTR_RMII_CLK), MP_ROM_PTR(&pin_GPIO50) }, + { MP_ROM_QSTR(MP_QSTR_PHY_RSTN), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_MDIO), MP_ROM_PTR(&pin_GPIO52) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_DATA0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA3), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_PWRN), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_tab5/board.c b/ports/espressif/boards/m5stack_tab5/board.c new file mode 100644 index 0000000000000..a3a9eec047145 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_tab5/mpconfigboard.h b/ports/espressif/boards/m5stack_tab5/mpconfigboard.h new file mode 100644 index 0000000000000..f85f1fe24b8ab --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Tab5" +#define MICROPY_HW_MCU_NAME "ESP32P4" + +// I2C bus for touch, IMU, RTC, power monitor, and GPIO expanders +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO32, .sda = &pin_GPIO31}} + +// UART +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO37) + +// SPI on M5-Bus +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO5) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO19) + +// Use the second USB device (numbered 0 and 1) +#define CIRCUITPY_USB_DEVICE_INSTANCE 1 diff --git a/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk b/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk new file mode 100644 index 0000000000000..4871a259e7a48 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x832B +USB_PRODUCT = "M5Stack Tab5" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32p4 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 32MB +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m diff --git a/ports/espressif/boards/m5stack_tab5/pins.c b/ports/espressif/boards/m5stack_tab5/pins.c new file mode 100644 index 0000000000000..67012cc670df2 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/pins.c @@ -0,0 +1,128 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // M5-Bus and general GPIO + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_G16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_G17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_G35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_G45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_G47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_G48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_G51), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_G52), MP_ROM_PTR(&pin_GPIO52) }, + + // SPI (on M5-Bus) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_G18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_G19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + + // UART (on M5-Bus) + { MP_ROM_QSTR(MP_QSTR_G37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TXD0), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_G38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_RXD0), MP_ROM_PTR(&pin_GPIO38) }, + + // I2C (Touch, IMU, RTC, Power Monitor, GPIO Expanders) + { MP_ROM_QSTR(MP_QSTR_G31), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_G32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO32) }, + + // Touch Panel + { MP_ROM_QSTR(MP_QSTR_G23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TP_INT), MP_ROM_PTR(&pin_GPIO23) }, + + // LCD + { MP_ROM_QSTR(MP_QSTR_G22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO22) }, + + // Audio ES8388/ES7210 + { MP_ROM_QSTR(MP_QSTR_G26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DSDIN), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_G27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_G28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_G29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_G30), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO30) }, + + // Camera + { MP_ROM_QSTR(MP_QSTR_G36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_GPIO36) }, + + // microSD Card (SDIO mode) + { MP_ROM_QSTR(MP_QSTR_G39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_G40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_G41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_G42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT3), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_G43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_G44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO44) }, + + // RS485 + { MP_ROM_QSTR(MP_QSTR_G20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RS485_TX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_G21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_RS485_RX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_G34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_RS485_DIR), MP_ROM_PTR(&pin_GPIO34) }, + + // HY2.0-4P PORT.A + { MP_ROM_QSTR(MP_QSTR_G53), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_Y), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_G54), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_W), MP_ROM_PTR(&pin_GPIO54) }, + + // ESP32-C6 SDIO interface + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D3), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D2), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D1), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_G12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_CK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_G13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_CMD), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_G14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_C6_IO2), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_G15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_C6_RESET), MP_ROM_PTR(&pin_GPIO15) }, + + // I2C and SPI objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_tab5/sdkconfig b/ports/espressif/boards/m5stack_tab5/sdkconfig new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ports/espressif/common-hal/microcontroller/Pin.c b/ports/espressif/common-hal/microcontroller/Pin.c index 922cde763e363..3ccd8dcbb693b 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.c +++ b/ports/espressif/common-hal/microcontroller/Pin.c @@ -77,6 +77,15 @@ static uint64_t _in_use_pin_mask; #define GPIO_SEL_47 ((uint64_t)PIN_BIT(47)) /*!< Pin 47 selected */ #define GPIO_SEL_48 ((uint64_t)PIN_BIT(48)) /*!< Pin 48 selected */ #endif +#if SOC_GPIO_PIN_COUNT > 49 +#define GPIO_SEL_49 ((uint64_t)PIN_BIT(49)) /*!< Pin 49 selected */ +#define GPIO_SEL_50 ((uint64_t)PIN_BIT(50)) /*!< Pin 50 selected */ +#define GPIO_SEL_51 ((uint64_t)PIN_BIT(51)) /*!< Pin 51 selected */ +#define GPIO_SEL_52 ((uint64_t)PIN_BIT(52)) /*!< Pin 52 selected */ +#define GPIO_SEL_53 ((uint64_t)PIN_BIT(53)) /*!< Pin 53 selected */ +#define GPIO_SEL_54 ((uint64_t)PIN_BIT(54)) /*!< Pin 54 selected */ +#define GPIO_SEL_55 ((uint64_t)PIN_BIT(55)) /*!< Pin 55 selected */ +#endif // Bit mask of all pins that should never EVER be reset. // Typically these are SPI flash and PSRAM control pins, and communication pins. @@ -202,10 +211,10 @@ static const uint64_t pin_mask_reset_forbidden = GPIO_SEL_32 | GPIO_SEL_33 | GPIO_SEL_34 | - #if CIRCUITPY_ESP_USB_SERIAL_JTAG + #if CIRCUITPY_ESP_USB_SERIAL_JTAG || (defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) && CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) // Never ever reset serial/JTAG communication pins. - GPIO_SEL_50 | // USB D- - GPIO_SEL_51 | // USB D+ + GPIO_SEL_24 | // USB D- + GPIO_SEL_25 | // USB D+ #endif #if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT && CONFIG_ESP_CONSOLE_UART_NUM == 0 // Never reset debug UART/console pins. diff --git a/ports/espressif/common-hal/mipidsi/Bus.c b/ports/espressif/common-hal/mipidsi/Bus.c new file mode 100644 index 0000000000000..7f9dc01b773ec --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Bus.c @@ -0,0 +1,52 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/Bus.h" +#include "bindings/espidf/__init__.h" +#include "py/runtime.h" +#include + +void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequency, uint8_t num_lanes) { + self->frequency = frequency; + self->num_data_lanes = num_lanes; + self->bus_handle = NULL; + + esp_ldo_channel_handle_t ldo_mipi_phy = NULL; + esp_ldo_channel_config_t ldo_mipi_phy_config = { + .chan_id = 3, + .voltage_mv = 2500, + }; + ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); + + // Create the DSI bus + esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = num_lanes, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = frequency / 1000000, // Convert Hz to MHz + }; + + CHECK_ESP_RESULT(esp_lcd_new_dsi_bus(&bus_config, &self->bus_handle)); +} + +void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) { + if (common_hal_mipidsi_bus_deinited(self)) { + return; + } + + // Delete the DSI bus + if (self->bus_handle != NULL) { + esp_lcd_del_dsi_bus(self->bus_handle); + self->bus_handle = NULL; + } + + self->frequency = 0; + self->num_data_lanes = 0; +} + +bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self) { + return self->bus_handle == NULL; +} diff --git a/ports/espressif/common-hal/mipidsi/Bus.h b/ports/espressif/common-hal/mipidsi/Bus.h new file mode 100644 index 0000000000000..0ffd333e52dd8 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Bus.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include + +typedef struct { + mp_obj_base_t base; + mp_uint_t frequency; + esp_lcd_dsi_bus_handle_t bus_handle; + uint8_t num_data_lanes; +} mipidsi_bus_obj_t; diff --git a/ports/espressif/common-hal/mipidsi/Display.c b/ports/espressif/common-hal/mipidsi/Display.c new file mode 100644 index 0000000000000..eff06f02bf7d4 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Display.c @@ -0,0 +1,254 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/Display.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "bindings/espidf/__init__.h" +#include +#include +#include "py/runtime.h" + +// Cache write-back function (should be from rom/cache.h but it's not always available) +extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size); + +void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, + mipidsi_bus_obj_t *bus, + const uint8_t *init_sequence, + size_t init_sequence_len, + mp_uint_t virtual_channel, + mp_uint_t width, + mp_uint_t height, + mp_int_t rotation, + mp_uint_t color_depth, + const mcu_pin_obj_t *backlight_pin, + mp_float_t brightness, + mp_uint_t native_frames_per_second, + bool backlight_on_high, + mp_uint_t hsync_pulse_width, + mp_uint_t hsync_back_porch, + mp_uint_t hsync_front_porch, + mp_uint_t vsync_pulse_width, + mp_uint_t vsync_back_porch, + mp_uint_t vsync_front_porch, + mp_uint_t pixel_clock_frequency) { + self->bus = bus; + self->virtual_channel = virtual_channel; + self->width = width; + self->height = height; + self->rotation = rotation; + self->color_depth = color_depth; + self->native_frames_per_second = native_frames_per_second; + self->backlight_on_high = backlight_on_high; + self->framebuffer = NULL; + self->dbi_io_handle = NULL; + self->dpi_panel_handle = NULL; + + // Create the DBI interface for sending commands + esp_lcd_dbi_io_config_t dbi_config = { + .virtual_channel = virtual_channel, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + }; + + CHECK_ESP_RESULT(esp_lcd_new_panel_io_dbi(bus->bus_handle, &dbi_config, &self->dbi_io_handle)); + + // Determine the pixel format based on color depth + lcd_color_format_t color_format; + if (color_depth == 16) { + color_format = LCD_COLOR_FMT_RGB565; + } else if (color_depth == 24) { + color_format = LCD_COLOR_FMT_RGB888; + } else { + common_hal_mipidsi_display_deinit(self); + mp_raise_ValueError(MP_ERROR_TEXT("Color depth must be 16 or 24")); + } + + // Create the DPI panel for sending pixel data + esp_lcd_dpi_panel_config_t dpi_config = { + .virtual_channel = virtual_channel, + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = pixel_clock_frequency / 1000000, + .in_color_format = color_format, + .num_fbs = 1, + .video_timing = { + .h_size = width, + .v_size = height, + .hsync_pulse_width = hsync_pulse_width, + .hsync_back_porch = hsync_back_porch, + .hsync_front_porch = hsync_front_porch, + .vsync_pulse_width = vsync_pulse_width, + .vsync_back_porch = vsync_back_porch, + .vsync_front_porch = vsync_front_porch, + }, + .flags = { + .use_dma2d = false, + .disable_lp = false, + }, + }; + + esp_err_t ret = esp_lcd_new_panel_dpi(bus->bus_handle, &dpi_config, &self->dpi_panel_handle); + if (ret != ESP_OK) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + // Get the framebuffer allocated by the driver + void *fb = NULL; + ret = esp_lcd_dpi_panel_get_frame_buffer(self->dpi_panel_handle, 1, &fb); + if (ret != ESP_OK || fb == NULL) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + self->framebuffer = (uint8_t *)fb; + self->framebuffer_size = width * height * (color_depth / 8); + + // Send initialization sequence (format matches busdisplay) + #define DELAY 0x80 + uint32_t i = 0; + while (i < init_sequence_len) { + const uint8_t *cmd = init_sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + const uint8_t *data = cmd + 2; + esp_lcd_panel_io_tx_param(self->dbi_io_handle, cmd[0], data, data_size); + + uint16_t delay_length_ms = 0; + if (delay) { + data_size++; + delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + } + common_hal_time_delay_ms(delay_length_ms); + i += 2 + data_size; + } + + // Initialize the panel after sending init commands + ret = esp_lcd_panel_init(self->dpi_panel_handle); + if (ret != ESP_OK) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + // Setup backlight PWM if pin is provided + self->backlight_inout.base.type = &mp_type_NoneType; + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + #if (CIRCUITPY_PWMIO) + pwmout_result_t result = common_hal_pwmio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + } else { + self->backlight_pwm.base.type = &pwmio_pwmout_type; + common_hal_pwmio_pwmout_never_reset(&self->backlight_pwm); + } + #else + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + #endif + + // Set initial brightness + #if (CIRCUITPY_PWMIO) + if (self->backlight_pwm.base.type == &pwmio_pwmout_type) { + common_hal_pwmio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t)(brightness * 0xFFFF)); + } else + #endif + if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + bool on = brightness > 0; + if (!backlight_on_high) { + on = !on; + } + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, on); + } + } +} + +void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) { + if (common_hal_mipidsi_display_deinited(self)) { + return; + } + + // Cleanup backlight + #if (CIRCUITPY_PWMIO) + if (self->backlight_pwm.base.type == &pwmio_pwmout_type) { + common_hal_pwmio_pwmout_deinit(&self->backlight_pwm); + } else + #endif + if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } + + // Delete the DPI panel + if (self->dpi_panel_handle != NULL) { + esp_lcd_panel_del(self->dpi_panel_handle); + self->dpi_panel_handle = NULL; + } + + // Delete the DBI interface + if (self->dbi_io_handle != NULL) { + esp_lcd_panel_io_del(self->dbi_io_handle); + self->dbi_io_handle = NULL; + } + + self->bus = NULL; + self->framebuffer = NULL; +} + +bool common_hal_mipidsi_display_deinited(mipidsi_display_obj_t *self) { + return self->dpi_panel_handle == NULL; +} + +void common_hal_mipidsi_display_refresh(mipidsi_display_obj_t *self) { + // Write back the cache to ensure framebuffer changes are visible + Cache_WriteBack_Addr((uint32_t)(self->framebuffer), self->framebuffer_size); + + // The DPI panel will automatically refresh from the framebuffer + // No explicit refresh call is needed as the DSI hardware continuously + // sends data from the framebuffer to the display +} + +int common_hal_mipidsi_display_get_width(mipidsi_display_obj_t *self) { + return self->width; +} + +int common_hal_mipidsi_display_get_height(mipidsi_display_obj_t *self) { + return self->height; +} + +int common_hal_mipidsi_display_get_row_stride(mipidsi_display_obj_t *self) { + return self->width * (self->color_depth / 8); +} + +int common_hal_mipidsi_display_get_color_depth(mipidsi_display_obj_t *self) { + return self->color_depth; +} + +int common_hal_mipidsi_display_get_native_frames_per_second(mipidsi_display_obj_t *self) { + return self->native_frames_per_second; +} + +bool common_hal_mipidsi_display_get_grayscale(mipidsi_display_obj_t *self) { + return false; +} + +mp_int_t common_hal_mipidsi_display_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + mipidsi_display_obj_t *self = (mipidsi_display_obj_t *)self_in; + + bufinfo->buf = self->framebuffer; + bufinfo->len = self->framebuffer_size; + bufinfo->typecode = 'B'; + + return 0; +} diff --git a/ports/espressif/common-hal/mipidsi/Display.h b/ports/espressif/common-hal/mipidsi/Display.h new file mode 100644 index 0000000000000..61e6cb73f6d75 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Display.h @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/digitalio/DigitalInOut.h" +#include "common-hal/pwmio/PWMOut.h" +#include +#include + +typedef struct { + mp_obj_base_t base; + mipidsi_bus_obj_t *bus; + mp_uint_t virtual_channel; + mp_uint_t width; + mp_uint_t height; + mp_int_t rotation; + mp_uint_t color_depth; + mp_uint_t native_frames_per_second; + uint8_t *framebuffer; + esp_lcd_panel_io_handle_t dbi_io_handle; + esp_lcd_panel_handle_t dpi_panel_handle; + size_t framebuffer_size; + union { + digitalio_digitalinout_obj_t backlight_inout; + #if CIRCUITPY_PWMIO + pwmio_pwmout_obj_t backlight_pwm; + #endif + }; + bool backlight_on_high; +} mipidsi_display_obj_t; diff --git a/ports/espressif/common-hal/mipidsi/__init__.c b/ports/espressif/common-hal/mipidsi/__init__.c new file mode 100644 index 0000000000000..173f2146e87ac --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/__init__.h" diff --git a/ports/espressif/common-hal/mipidsi/__init__.h b/ports/espressif/common-hal/mipidsi/__init__.h new file mode 100644 index 0000000000000..972a7c082fd7b --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index f133e86c6e068..c3585c7e39984 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -312,6 +312,9 @@ CIRCUITPY_PARALLELDISPLAYBUS = 0 # Library doesn't support P4 yet it seems CIRCUITPY_ESPCAMERA = 0 +# P4 has MIPI-DSI +CIRCUITPY_MIPIDSI = 1 + #### esp32s2 ########################################################## else ifeq ($(IDF_TARGET),esp32s2) # Modules diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index c629eb52932e7..192a91717169a 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -244,7 +244,7 @@ safe_mode_t port_init(void) { #endif // Send the ROM output out of the UART. This includes early logs. - #if DEBUG + #if DEBUG && (defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT) esp_rom_install_uart_printf(); #endif diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index f4ac2350ffbf1..56c836cb3a490 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -294,6 +294,9 @@ endif ifeq ($(CIRCUITPY_MICROCONTROLLER),1) SRC_PATTERNS += microcontroller/% endif +ifeq ($(CIRCUITPY_MIPIDSI),1) +SRC_PATTERNS += mipidsi/% +endif ifeq ($(CIRCUITPY_MSGPACK),1) SRC_PATTERNS += msgpack/% endif @@ -531,6 +534,9 @@ SRC_COMMON_HAL_ALL = \ mdns/__init__.c \ mdns/Server.c \ mdns/RemoteService.c \ + mipidsi/Bus.c \ + mipidsi/Display.c \ + mipidsi/__init__.c \ neopixel_write/__init__.c \ nvm/ByteArray.c \ nvm/__init__.c \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 09ef4361427da..9bbe5691dfb3b 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -405,6 +405,9 @@ CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR) CIRCUITPY_MICROCONTROLLER ?= 1 CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER) +CIRCUITPY_MIPIDSI ?= 0 +CFLAGS += -DCIRCUITPY_MIPIDSI=$(CIRCUITPY_MIPIDSI) + CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK) diff --git a/shared-bindings/mipidsi/Bus.c b/shared-bindings/mipidsi/Bus.c new file mode 100644 index 0000000000000..2f2ce046fe06c --- /dev/null +++ b/shared-bindings/mipidsi/Bus.c @@ -0,0 +1,96 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" + +//| class Bus: +//| def __init__( +//| self, +//| *, +//| frequency: int = 500_000_000, +//| num_lanes: int = 2, +//| ) -> None: +//| """Create a MIPI DSI Bus object. +//| +//| This creates a DSI bus interface. The specific pins used are determined by the board. +//| DSI supports 1-4 data lanes. +//| +//| :param int frequency: the high speed clock frequency in Hz (default 500 MHz) +//| :param int num_lanes: the number of data lanes to use (default 2, range 1-4) +//| """ +//| + +static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_frequency, ARG_num_lanes }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500000000} }, + { MP_QSTR_num_lanes, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 2} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mipidsi_bus_obj_t *self = mp_obj_malloc(mipidsi_bus_obj_t, &mipidsi_bus_type); + + mp_uint_t frequency = (mp_uint_t)mp_arg_validate_int_min(args[ARG_frequency].u_int, 1, MP_QSTR_frequency); + uint8_t num_lanes = (uint8_t)mp_arg_validate_int_range(args[ARG_num_lanes].u_int, 1, 4, MP_QSTR_num_lanes); + + common_hal_mipidsi_bus_construct(self, frequency, num_lanes); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| `mipidsi.Bus` instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| +static mp_obj_t mipidsi_bus_deinit(mp_obj_t self_in) { + mipidsi_bus_obj_t *self = (mipidsi_bus_obj_t *)self_in; + common_hal_mipidsi_bus_deinit(self); + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_bus_deinit_obj, mipidsi_bus_deinit); + +//| def __enter__(self) -> Bus: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t mipidsi_bus_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_mipidsi_bus_deinit(args[0]); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mipidsi_bus___exit___obj, 4, 4, mipidsi_bus_obj___exit__); + +static const mp_rom_map_elem_t mipidsi_bus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_bus_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mipidsi_bus___exit___obj) }, +}; +static MP_DEFINE_CONST_DICT(mipidsi_bus_locals_dict, mipidsi_bus_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + mipidsi_bus_type, + MP_QSTR_Bus, + MP_TYPE_FLAG_NONE, + make_new, mipidsi_bus_make_new, + locals_dict, &mipidsi_bus_locals_dict + ); diff --git a/shared-bindings/mipidsi/Bus.h b/shared-bindings/mipidsi/Bus.h new file mode 100644 index 0000000000000..f2fd13f7fc165 --- /dev/null +++ b/shared-bindings/mipidsi/Bus.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/mipidsi/Bus.h" + +extern const mp_obj_type_t mipidsi_bus_type; + +void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequency, uint8_t num_lanes); +void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self); +bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self); diff --git a/shared-bindings/mipidsi/Display.c b/shared-bindings/mipidsi/Display.c new file mode 100644 index 0000000000000..a553c7ca8fd55 --- /dev/null +++ b/shared-bindings/mipidsi/Display.c @@ -0,0 +1,289 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objtype.h" + +#include "shared-bindings/mipidsi/Display.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +//| class Display: +//| def __init__( +//| self, +//| bus: Bus, +//| init_sequence: ReadableBuffer, +//| *, +//| width: int, +//| height: int, +//| hsync_pulse_width: int, +//| hsync_back_porch: int, +//| hsync_front_porch: int, +//| vsync_pulse_width: int, +//| vsync_back_porch: int, +//| vsync_front_porch: int, +//| pixel_clock_frequency: int, +//| virtual_channel: int = 0, +//| rotation: int = 0, +//| color_depth: int = 16, +//| backlight_pin: Optional[microcontroller.Pin] = None, +//| brightness: float = 1.0, +//| native_frames_per_second: int = 60, +//| backlight_on_high: bool = True, +//| ) -> None: +//| """Create a MIPI DSI Display object connected to the given bus. +//| +//| This allocates a framebuffer and configures the DSI display to use the +//| specified virtual channel for communication. +//| +//| The framebuffer pixel format varies depending on color_depth: +//| +//| * 16 - Each two bytes is a pixel in RGB565 format. +//| * 24 - Each three bytes is a pixel in RGB888 format. +//| +//| A Display is often used in conjunction with a +//| `framebufferio.FramebufferDisplay`. +//| +//| :param Bus bus: the DSI bus to use +//| :param ~circuitpython_typing.ReadableBuffer init_sequence: Byte-packed initialization sequence for the display +//| :param int width: the width of the framebuffer in pixels +//| :param int height: the height of the framebuffer in pixels +//| :param int hsync_pulse_width: horizontal sync pulse width in pixel clocks +//| :param int hsync_back_porch: horizontal back porch in pixel clocks +//| :param int hsync_front_porch: horizontal front porch in pixel clocks +//| :param int vsync_pulse_width: vertical sync pulse width in lines +//| :param int vsync_back_porch: vertical back porch in lines +//| :param int vsync_front_porch: vertical front porch in lines +//| :param int pixel_clock_frequency: pixel clock frequency in Hz +//| :param int virtual_channel: the DSI virtual channel (0-3) +//| :param int rotation: the rotation of the display in degrees clockwise (0, 90, 180, 270) +//| :param int color_depth: the color depth of the framebuffer in bits (16 or 24) +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight +//| :param float brightness: Initial display brightness (0.0 to 1.0) +//| :param int native_frames_per_second: Number of display refreshes per second +//| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on +//| """ +//| + +static mp_obj_t mipidsi_display_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_hsync_pulse_width, ARG_hsync_back_porch, + ARG_hsync_front_porch, ARG_vsync_pulse_width, ARG_vsync_back_porch, ARG_vsync_front_porch, + ARG_pixel_clock_frequency, ARG_virtual_channel, ARG_rotation, + ARG_color_depth, ARG_backlight_pin, ARG_brightness, ARG_native_frames_per_second, + ARG_backlight_on_high }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_height, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_pulse_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_back_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_front_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_pulse_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_back_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_front_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_pixel_clock_frequency, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_virtual_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} }, + { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + { MP_QSTR_backlight_on_high, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mipidsi_display_obj_t *self = &allocate_display_bus_or_raise()->mipidsi; + self->base.type = &mipidsi_display_type; + + mipidsi_bus_obj_t *bus = mp_arg_validate_type(args[ARG_bus].u_obj, &mipidsi_bus_type, MP_QSTR_bus); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + const mcu_pin_obj_t *backlight_pin = + validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj, MP_QSTR_backlight_pin); + + mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("Display rotation must be in 90 degree increments")); + } + + mp_uint_t virtual_channel = (mp_uint_t)mp_arg_validate_int_range(args[ARG_virtual_channel].u_int, 0, 3, MP_QSTR_virtual_channel); + mp_uint_t width = (mp_uint_t)mp_arg_validate_int_min(args[ARG_width].u_int, 0, MP_QSTR_width); + mp_uint_t height = (mp_uint_t)mp_arg_validate_int_min(args[ARG_height].u_int, 0, MP_QSTR_height); + mp_uint_t color_depth = args[ARG_color_depth].u_int; + + if (color_depth != 8 && color_depth != 16 && color_depth != 24) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); + } + + common_hal_mipidsi_display_construct(self, bus, bufinfo.buf, bufinfo.len, virtual_channel, width, height, + rotation, color_depth, MP_OBJ_TO_PTR(backlight_pin), brightness, + args[ARG_native_frames_per_second].u_int, + args[ARG_backlight_on_high].u_bool, + args[ARG_hsync_pulse_width].u_int, + args[ARG_hsync_back_porch].u_int, + args[ARG_hsync_front_porch].u_int, + args[ARG_vsync_pulse_width].u_int, + args[ARG_vsync_back_porch].u_int, + args[ARG_vsync_front_porch].u_int, + args[ARG_pixel_clock_frequency].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +// Helper to ensure we have the native super class instead of a subclass. +static mipidsi_display_obj_t *native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_obj_cast_to_native_base(display_obj, &mipidsi_display_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| `mipidsi.Display` instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| +static mp_obj_t mipidsi_display_deinit(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + common_hal_mipidsi_display_deinit(self); + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_deinit_obj, mipidsi_display_deinit); + +static void check_for_deinit(mipidsi_display_obj_t *self) { + if (common_hal_mipidsi_display_deinited(self)) { + raise_deinited_error(); + } +} + +//| width: int +//| """The width of the framebuffer, in pixels.""" +static mp_obj_t mipidsi_display_get_width(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_width_obj, mipidsi_display_get_width); +MP_PROPERTY_GETTER(mipidsi_display_width_obj, + (mp_obj_t)&mipidsi_display_get_width_obj); + +//| height: int +//| """The height of the framebuffer, in pixels.""" +//| +//| +static mp_obj_t mipidsi_display_get_height(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_height_obj, mipidsi_display_get_height); + +MP_PROPERTY_GETTER(mipidsi_display_height_obj, + (mp_obj_t)&mipidsi_display_get_height_obj); + +//| color_depth: int +//| """The color depth of the framebuffer.""" +static mp_obj_t mipidsi_display_get_color_depth(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_color_depth(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_color_depth_obj, mipidsi_display_get_color_depth); +MP_PROPERTY_GETTER(mipidsi_display_color_depth_obj, + (mp_obj_t)&mipidsi_display_get_color_depth_obj); + + +static const mp_rom_map_elem_t mipidsi_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_display_deinit_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&mipidsi_display_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&mipidsi_display_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_color_depth), MP_ROM_PTR(&mipidsi_display_color_depth_obj) }, +}; +static MP_DEFINE_CONST_DICT(mipidsi_display_locals_dict, mipidsi_display_locals_dict_table); + +static void mipidsi_display_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + common_hal_mipidsi_display_get_buffer(self_in, bufinfo, 0); +} + +// These versions exist so that the prototype matches the protocol, +// avoiding a type cast that can hide errors +static void mipidsi_display_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { + (void)dirty_row_bitmap; + common_hal_mipidsi_display_refresh(self_in); +} + +static void mipidsi_display_deinit_proto(mp_obj_t self_in) { + common_hal_mipidsi_display_deinit(self_in); +} + +static int mipidsi_display_get_width_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_width(self_in); +} + +static int mipidsi_display_get_height_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_height(self_in); +} + +static int mipidsi_display_get_color_depth_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_color_depth(self_in); +} + +static bool mipidsi_display_get_grayscale_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_grayscale(self_in); +} + +static int mipidsi_display_get_bytes_per_cell_proto(mp_obj_t self_in) { + return 1; +} + +static int mipidsi_display_get_native_frames_per_second_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_native_frames_per_second(self_in); +} + +static bool mipidsi_display_get_pixels_in_byte_share_row_proto(mp_obj_t self_in) { + return true; +} + +static int mipidsi_display_get_row_stride_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_row_stride(self_in); +} + +static const framebuffer_p_t mipidsi_display_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .get_bufinfo = mipidsi_display_get_bufinfo, + .get_width = mipidsi_display_get_width_proto, + .get_height = mipidsi_display_get_height_proto, + .get_color_depth = mipidsi_display_get_color_depth_proto, + .get_grayscale = mipidsi_display_get_grayscale_proto, + .get_row_stride = mipidsi_display_get_row_stride_proto, + .get_bytes_per_cell = mipidsi_display_get_bytes_per_cell_proto, + .get_native_frames_per_second = mipidsi_display_get_native_frames_per_second_proto, + .get_pixels_in_byte_share_row = mipidsi_display_get_pixels_in_byte_share_row_proto, + .swapbuffers = mipidsi_display_swapbuffers, + .deinit = mipidsi_display_deinit_proto, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + mipidsi_display_type, + MP_QSTR_Display, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + locals_dict, &mipidsi_display_locals_dict, + make_new, mipidsi_display_make_new, + buffer, common_hal_mipidsi_display_get_buffer, + protocol, &mipidsi_display_proto + ); diff --git a/shared-bindings/mipidsi/Display.h b/shared-bindings/mipidsi/Display.h new file mode 100644 index 0000000000000..1cec788f16cd9 --- /dev/null +++ b/shared-bindings/mipidsi/Display.h @@ -0,0 +1,44 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/mipidsi/Display.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t mipidsi_display_type; + +void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, + mipidsi_bus_obj_t *bus, + const uint8_t *init_sequence, + size_t init_sequence_len, + mp_uint_t virtual_channel, + mp_uint_t width, + mp_uint_t height, + mp_int_t rotation, + mp_uint_t color_depth, + const mcu_pin_obj_t *backlight_pin, + mp_float_t brightness, + mp_uint_t native_frames_per_second, + bool backlight_on_high, + mp_uint_t hsync_pulse_width, + mp_uint_t hsync_back_porch, + mp_uint_t hsync_front_porch, + mp_uint_t vsync_pulse_width, + mp_uint_t vsync_back_porch, + mp_uint_t vsync_front_porch, + mp_uint_t pixel_clock_frequency); +void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self); +bool common_hal_mipidsi_display_deinited(mipidsi_display_obj_t *self); +void common_hal_mipidsi_display_refresh(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_width(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_height(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_row_stride(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_color_depth(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_native_frames_per_second(mipidsi_display_obj_t *self); +bool common_hal_mipidsi_display_get_grayscale(mipidsi_display_obj_t *self); +mp_int_t common_hal_mipidsi_display_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); diff --git a/shared-bindings/mipidsi/__init__.c b/shared-bindings/mipidsi/__init__.c new file mode 100644 index 0000000000000..0b6b856592918 --- /dev/null +++ b/shared-bindings/mipidsi/__init__.c @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/mipidsi/Display.h" + +//| """Low-level routines for interacting with MIPI DSI""" + +static const mp_rom_map_elem_t mipidsi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mipidsi) }, + { MP_ROM_QSTR(MP_QSTR_Bus), MP_ROM_PTR(&mipidsi_bus_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&mipidsi_display_type) }, +}; + +static MP_DEFINE_CONST_DICT(mipidsi_module_globals, mipidsi_module_globals_table); + +const mp_obj_module_t mipidsi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mipidsi_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_mipidsi, mipidsi_module); diff --git a/shared-bindings/mipidsi/__init__.h b/shared-bindings/mipidsi/__init__.h new file mode 100644 index 0000000000000..972a7c082fd7b --- /dev/null +++ b/shared-bindings/mipidsi/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 29b8c64c97240..f2f4691b313a7 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -38,6 +38,9 @@ #if CIRCUITPY_DOTCLOCKFRAMEBUFFER #include "common-hal/dotclockframebuffer/DotClockFramebuffer.h" #endif +#if CIRCUITPY_MIPIDSI +#include "shared-bindings/mipidsi/Display.h" +#endif // Port unique frame buffers. #if CIRCUITPY_VIDEOCORE #include "bindings/videocore/Framebuffer.h" @@ -81,6 +84,9 @@ typedef struct { #if CIRCUITPY_AURORA_EPAPER aurora_epaper_framebuffer_obj_t aurora_epaper; #endif + #if CIRCUITPY_MIPIDSI + mipidsi_display_obj_t mipidsi; + #endif }; } primary_display_bus_t; From eb84f5a6b3984cedcd68a525ab07b0f8e55ab764 Mon Sep 17 00:00:00 2001 From: chinh4thepro Date: Mon, 3 Nov 2025 19:29:47 -0500 Subject: [PATCH 194/208] ports/espressif: add MT* pin aliases to seeed xiao esp32s3 sense board --- ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index 8269f1d7a951e..222b17aa3372f 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -68,6 +68,10 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_MOSI_1), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_MISO_1), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_SCK_1), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_GPIO21) }, @@ -89,9 +93,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, From 672f6855410e1eea71e7bedc97eafc6eff496d27 Mon Sep 17 00:00:00 2001 From: chinh4thepro Date: Mon, 3 Nov 2025 19:30:48 -0500 Subject: [PATCH 195/208] ports/espressif: add back the I2S pin aliases --- ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index 222b17aa3372f..aa0d72b4d8699 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -93,6 +93,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, From 785d5991bdfd955edf2c1f50e147c393e3d6d8ed Mon Sep 17 00:00:00 2001 From: chinh4thepro Date: Mon, 3 Nov 2025 22:34:54 -0500 Subject: [PATCH 196/208] seeed_xiao_esp32_s3_sense: stylize pins.c --- .../boards/seeed_xiao_esp32_s3_sense/pins.c | 90 +++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index aa0d72b4d8699..fcf48c83659a3 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -31,71 +31,91 @@ static const mp_rom_obj_tuple_t camera_data_tuple = { static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_RX_1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX_1), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SCK_1), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MISO_1), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_TX_1), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_RX_1), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_MOSI_1), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_MISO_1), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_SCK_1), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_CAM_D2), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_CAM_D3), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_CAM_D4), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_CAM_D7), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, From 4c037682432b536c250213b380180a97afc2d122 Mon Sep 17 00:00:00 2001 From: chinh4thepro Date: Mon, 3 Nov 2025 22:39:08 -0500 Subject: [PATCH 197/208] seeed_xiao_esp32_s3_sense: add back pin alias --- ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index fcf48c83659a3..fbb6014685ca4 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -49,6 +49,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, From f469e93d53b6b6bc5c16a3b0291d996c0be4a4dc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 3 Nov 2025 11:27:07 -0800 Subject: [PATCH 198/208] Fix Zephyr build --- ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml | 1 + ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml | 1 + ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml | 1 + ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml | 1 + ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml | 1 + .../zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml | 1 + ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml | 1 + 7 files changed, 7 insertions(+) diff --git a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml index 222a325e346b6..35966d6f9e2c6 100644 --- a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml index 41631c3d6c02c..e3b6cc2248f2e 100644 --- a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml index ea009aa36e1ca..328105d715059 100644 --- a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml index a96d1bad1d2a6..2bc6e3e03a249 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml index e4946decb190b..2a2e16fd16afe 100644 --- a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml index 7519d8817687b..5042eb972b143 100644 --- a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false diff --git a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml index e029020982d20..cfe48a90ceea4 100644 --- a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml @@ -66,6 +66,7 @@ mdns = false memorymap = false memorymonitor = false microcontroller = true +mipidsi = false msgpack = false neopixel_write = false nvm = false From 7b452dc29a37b0976e0e6e8bb4ef38716d1b666e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 4 Nov 2025 17:23:52 +0100 Subject: [PATCH 199/208] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/cs.po | 4 ++-- locale/ru.po | 4 ++-- locale/tr.po | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index fa1cb2d40b738..e59cc974e0e76 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -4876,8 +4876,8 @@ msgstr "" #~ msgstr "IV musí být dlouhé %d bajtů" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Nekompatibilní soubor .mpy. Aktualizujte prosím všechny soubory .mpy. " #~ "Další informace naleznete na adrese http://adafru.it/mpy-update." diff --git a/locale/ru.po b/locale/ru.po index af7c8bca194d2..83bfaf324d7f6 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -5149,8 +5149,8 @@ msgstr "zi должен иметь форму (n_section, 2)" #~ msgstr "IV должен быть длиной %d байт" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Несовместимый файл .mpy. Пожалуйста, обновите все файлы .mpy. См. http://" #~ "adafru.it/mpy-update для получения дополнительной информации." diff --git a/locale/tr.po b/locale/tr.po index 758137eae21f8..4e03f59cbaffb 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -4818,8 +4818,8 @@ msgstr "" #~ msgstr "IV %d bayt uzunluğunda olmalı" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Uyumsuz .mpy dosyası. Lütfen tüm .mpy dosyalarını güncelleyin. Daha fazla " #~ "bilgi için http://adafru.it/mpy-update ." From d2dcfecb89420de5ad1495b7d5fa6d7bb5417f23 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 4 Nov 2025 14:01:24 -0500 Subject: [PATCH 200/208] espressif_esp32p4_function_ev/pins.c: add whitespace to clearly show pin aliases --- .../boards/espressif_esp32p4_function_ev/pins.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c index 7a3026f914dd9..165ce711b736a 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c @@ -12,18 +12,25 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { // Header Block J1 { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_C6_WAKEUP), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, @@ -36,12 +43,15 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_C6_EN), MP_ROM_PTR(&pin_GPIO54) }, { MP_ROM_QSTR(MP_QSTR_IO54), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, { MP_ROM_QSTR(MP_QSTR_PA_CTRL), MP_ROM_PTR(&pin_GPIO53) }, { MP_ROM_QSTR(MP_QSTR_IO53), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, From 292d209fae5750df85537f2f4c33936b2ea8c5a2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 4 Nov 2025 16:29:30 -0800 Subject: [PATCH 201/208] Better reasoned allocations --- ports/espressif/common-hal/mipidsi/Bus.c | 17 +++++++++++ ports/espressif/common-hal/mipidsi/Bus.h | 4 +++ ports/espressif/common-hal/mipidsi/Display.c | 4 ++- shared-bindings/mipidsi/Bus.c | 30 ++++++-------------- shared-bindings/mipidsi/Display.c | 2 +- shared-module/displayio/__init__.c | 17 ++++++++++- 6 files changed, 50 insertions(+), 24 deletions(-) diff --git a/ports/espressif/common-hal/mipidsi/Bus.c b/ports/espressif/common-hal/mipidsi/Bus.c index 7f9dc01b773ec..dbb559ea30f22 100644 --- a/ports/espressif/common-hal/mipidsi/Bus.c +++ b/ports/espressif/common-hal/mipidsi/Bus.c @@ -14,6 +14,10 @@ void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequen self->num_data_lanes = num_lanes; self->bus_handle = NULL; + if (self->use_count > 0) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_mipidsi); + } + esp_ldo_channel_handle_t ldo_mipi_phy = NULL; esp_ldo_channel_config_t ldo_mipi_phy_config = { .chan_id = 3, @@ -33,6 +37,9 @@ void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequen } void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) { + if (self->use_count > 0) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Bus); + } if (common_hal_mipidsi_bus_deinited(self)) { return; } @@ -50,3 +57,13 @@ void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) { bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self) { return self->bus_handle == NULL; } + +void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self) { + self->use_count++; +} +void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self) { + self->use_count--; + if (self->use_count == 0) { + common_hal_mipidsi_bus_deinit(self); + } +} diff --git a/ports/espressif/common-hal/mipidsi/Bus.h b/ports/espressif/common-hal/mipidsi/Bus.h index 0ffd333e52dd8..b6257fd7223dd 100644 --- a/ports/espressif/common-hal/mipidsi/Bus.h +++ b/ports/espressif/common-hal/mipidsi/Bus.h @@ -14,4 +14,8 @@ typedef struct { mp_uint_t frequency; esp_lcd_dsi_bus_handle_t bus_handle; uint8_t num_data_lanes; + uint8_t use_count; // Up to 4 displays } mipidsi_bus_obj_t; + +void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self); +void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self); diff --git a/ports/espressif/common-hal/mipidsi/Display.c b/ports/espressif/common-hal/mipidsi/Display.c index eff06f02bf7d4..dac16162e91ff 100644 --- a/ports/espressif/common-hal/mipidsi/Display.c +++ b/ports/espressif/common-hal/mipidsi/Display.c @@ -67,7 +67,7 @@ void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, color_format = LCD_COLOR_FMT_RGB888; } else { common_hal_mipidsi_display_deinit(self); - mp_raise_ValueError(MP_ERROR_TEXT("Color depth must be 16 or 24")); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); } // Create the DPI panel for sending pixel data @@ -173,6 +173,7 @@ void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, on); } } + mipidsi_bus_increment_use_count(self->bus); } void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) { @@ -202,6 +203,7 @@ void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) { self->dbi_io_handle = NULL; } + mipidsi_bus_decrement_use_count(self->bus); self->bus = NULL; self->framebuffer = NULL; } diff --git a/shared-bindings/mipidsi/Bus.c b/shared-bindings/mipidsi/Bus.c index 2f2ce046fe06c..bac3cd3c75e1b 100644 --- a/shared-bindings/mipidsi/Bus.c +++ b/shared-bindings/mipidsi/Bus.c @@ -28,6 +28,13 @@ //| :param int num_lanes: the number of data lanes to use (default 2, range 1-4) //| """ //| +// +// +// All MCUs we support only have one DSI bus but it can be shared between multiple displays. One +// display may live longer than the VM, so we need to allocate the bus outside the VM. To simplify +// memory tracking, we use a global object for the bus. +// +static mipidsi_bus_obj_t _mipidsi_bus_obj; static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_frequency, ARG_num_lanes }; @@ -38,7 +45,8 @@ static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, s mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mipidsi_bus_obj_t *self = mp_obj_malloc(mipidsi_bus_obj_t, &mipidsi_bus_type); + _mipidsi_bus_obj.base.type = &mipidsi_bus_type; + mipidsi_bus_obj_t *self = &_mipidsi_bus_obj; mp_uint_t frequency = (mp_uint_t)mp_arg_validate_int_min(args[ARG_frequency].u_int, 1, MP_QSTR_frequency); uint8_t num_lanes = (uint8_t)mp_arg_validate_int_range(args[ARG_num_lanes].u_int, 1, 4, MP_QSTR_num_lanes); @@ -62,28 +70,8 @@ static mp_obj_t mipidsi_bus_deinit(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_bus_deinit_obj, mipidsi_bus_deinit); -//| def __enter__(self) -> Bus: -//| """No-op used by Context Managers.""" -//| ... -//| -// Provided by context manager helper. - -//| def __exit__(self) -> None: -//| """Automatically deinitializes the hardware when exiting a context. See -//| :ref:`lifetime-and-contextmanagers` for more info.""" -//| ... -//| -static mp_obj_t mipidsi_bus_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_mipidsi_bus_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mipidsi_bus___exit___obj, 4, 4, mipidsi_bus_obj___exit__); - static const mp_rom_map_elem_t mipidsi_bus_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_bus_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mipidsi_bus___exit___obj) }, }; static MP_DEFINE_CONST_DICT(mipidsi_bus_locals_dict, mipidsi_bus_locals_dict_table); diff --git a/shared-bindings/mipidsi/Display.c b/shared-bindings/mipidsi/Display.c index a553c7ca8fd55..ad4522d653c7f 100644 --- a/shared-bindings/mipidsi/Display.c +++ b/shared-bindings/mipidsi/Display.c @@ -124,7 +124,7 @@ static mp_obj_t mipidsi_display_make_new(const mp_obj_type_t *type, size_t n_arg mp_uint_t height = (mp_uint_t)mp_arg_validate_int_min(args[ARG_height].u_int, 0, MP_QSTR_height); mp_uint_t color_depth = args[ARG_color_depth].u_int; - if (color_depth != 8 && color_depth != 16 && color_depth != 24) { + if (color_depth != 16 && color_depth != 24) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); } diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 3ffd4d002f534..747fdbec5a75a 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -41,6 +41,10 @@ #include "shared-module/aurora_epaper/aurora_framebuffer.h" #endif +#if CIRCUITPY_MIPIDSI +#include "shared-bindings/mipidsi/Display.h" +#endif + #ifdef BOARD_USE_INTERNAL_SPI #include "supervisor/spi_flash_api.h" #endif @@ -64,7 +68,7 @@ displayio_buffer_transform_t null_transform = { .transpose_xy = false }; -#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI +#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI || CIRCUITPY_MIPIDSI static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) { @@ -180,6 +184,10 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { } else if (bus_type == &picodvi_framebuffer_type) { common_hal_picodvi_framebuffer_deinit(&display_buses[i].picodvi); #endif + #if CIRCUITPY_MIPIDSI + } else if (bus_type == &mipidsi_display_type) { + common_hal_mipidsi_display_deinit(&display_buses[i].mipidsi); + #endif } display_buses[i].bus_base.type = &mp_type_NoneType; } @@ -333,6 +341,13 @@ void reset_displays(void) { // Set to None, gets deinit'd up by display_base display_buses[i].bus_base.type = &mp_type_NoneType; #endif + #if CIRCUITPY_MIPIDSI + } else if (display_bus_type == &mipidsi_display_type) { + mipidsi_display_obj_t *display = &display_buses[i].mipidsi; + if (!any_display_uses_this_framebuffer(&display->base)) { + common_hal_mipidsi_display_deinit(display); + } + #endif } else { // Not an active display bus. continue; From 000fa5ab5f3a3cdf077399af8a2c8ac9830aaefc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 4 Nov 2025 16:36:14 -0800 Subject: [PATCH 202/208] Use latest macos in CI --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0f837d793bddc..ddd4a2eb93697 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -107,7 +107,7 @@ jobs: cp-version: ${{ needs.scheduler.outputs.cp-version }} mpy-cross-mac: - runs-on: macos-13 + runs-on: macos-latest needs: scheduler if: needs.scheduler.outputs.ports != '{}' env: From 91e36f1b38f33719062168e3a7707edfff630948 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 5 Nov 2025 12:10:55 -0500 Subject: [PATCH 203/208] stop building intel and universal macos mpy-cross --- .github/workflows/build.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ddd4a2eb93697..fbd3af440c6b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,33 +131,18 @@ jobs: gcc --version python3 --version msgfmt --version - - name: Build mpy-cross - run: make -C mpy-cross -j4 - - uses: actions/upload-artifact@v4 - with: - name: mpy-cross-macos-x64 - path: mpy-cross/build/mpy-cross - name: Build mpy-cross (arm64) run: make -C mpy-cross -j4 -f Makefile.m1 V=2 - uses: actions/upload-artifact@v4 with: name: mpy-cross-macos-arm64 path: mpy-cross/build-arm64/mpy-cross-arm64 - - name: Make universal binary - run: lipo -create -output mpy-cross-macos-universal mpy-cross/build/mpy-cross mpy-cross/build-arm64/mpy-cross-arm64 - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: mpy-cross-macos-universal - path: mpy-cross-macos-universal - name: Upload to S3 if: >- (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')) run: | - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-"${CP_VERSION}"-universal --no-progress --region us-east-1 [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/build-arm64/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-"${CP_VERSION}"-arm64 --no-progress --region us-east-1 - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/build/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-"${CP_VERSION}"-x64 --no-progress --region us-east-1 env: AWS_PAGER: '' AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} From 7c9f9f6d3b40ad2b7efcade4f3c7fc4635112eea Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 5 Nov 2025 18:18:29 +0100 Subject: [PATCH 204/208] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/cs.po | 17 ++++++++--------- locale/el.po | 20 +++++++++++--------- locale/hi.po | 17 ++++++++--------- locale/ko.po | 22 ++++++++++++---------- locale/ru.po | 23 ++++++++++++++--------- locale/tr.po | 17 ++++++++--------- 6 files changed, 61 insertions(+), 55 deletions(-) diff --git a/locale/cs.po b/locale/cs.po index e59cc974e0e76..44adf48833626 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -170,10 +170,6 @@ msgstr "Délka %q musí být <= %d" msgid "%q length must be >= %d" msgstr "Délka %q musí být >= %d" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q musí být %d" @@ -854,6 +850,10 @@ msgstr "Jádro kódu CircuitPython tvrdě havarovalo. Jejda!\n" msgid "Clock unit in use" msgstr "Jednotka hodin je používána" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -950,6 +950,7 @@ msgstr "Displej musí mít 16bitový barevný prostor." #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "Otočení displeje musí být po 90 stupních" @@ -1296,7 +1297,8 @@ msgstr "" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2290,6 +2292,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "Není možné vytvořit zámek" @@ -3203,10 +3206,6 @@ msgstr "" msgid "file write is not available" msgstr "zápis do souboru není dostupný" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "První argument musí být zavolatelný" diff --git a/locale/el.po b/locale/el.po index 91624ceb08672..01f199d5c6a14 100644 --- a/locale/el.po +++ b/locale/el.po @@ -174,10 +174,6 @@ msgstr "%q μήκος πρέπει να είναι <= %d" msgid "%q length must be >= %d" msgstr "%q μήκος πρέπει να είναι >= %d" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "%q μετακινήθηκε από το %q στο %q" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q πρέπει να είναι %d" @@ -859,6 +855,10 @@ msgstr "Ο πυρήνας της CircuitPython κατέρευσε. Οουπς!\n msgid "Clock unit in use" msgstr "Μονάδα ρολογιού ήδη σε χρήση" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -957,6 +957,7 @@ msgstr "Η οθόνη πρέπει να έχει 16 bit χρωματική ευ #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "Η περιστροφή της οθόνη πρέπει να γίνεται σε βήματα 90 μοιρών" @@ -1302,7 +1303,8 @@ msgstr "" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2294,6 +2296,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "" @@ -3202,10 +3205,6 @@ msgstr "" msgid "file write is not available" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "" @@ -4583,6 +4582,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q μετακινήθηκε από το %q στο %q" + #, c-format #~ msgid "%%c requires int or char" #~ msgstr "%%c απαιτεί ακέραιο ή χαρακτήρα" diff --git a/locale/hi.po b/locale/hi.po index 1ab48338ebaba..ea538c2f6f3dc 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -161,10 +161,6 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "" @@ -840,6 +836,10 @@ msgstr "" msgid "Clock unit in use" msgstr "" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -934,6 +934,7 @@ msgstr "" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -1278,7 +1279,8 @@ msgstr "" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2268,6 +2270,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "" @@ -3176,10 +3179,6 @@ msgstr "" msgid "file write is not available" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 35bfed4de08e9..96d8003ff9324 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -172,11 +172,6 @@ msgstr "%q 길이는 <= %d>여야 합니다" msgid "%q length must be >= %d" msgstr "%q 길이는 >= %d이어야 합니다" -#: py/runtime.c -#, fuzzy -msgid "%q moved from %q to %q" -msgstr "%q가 %q에서 %q로 이동했습니다" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q는 %d이어야 합니다" @@ -885,6 +880,10 @@ msgstr "CircuitPython 핵심 코드가 심하게 충돌했습니다. 앗!\n" msgid "Clock unit in use" msgstr "시계 장치가 사용 중입니다" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -980,6 +979,7 @@ msgstr "디스플레이는 16 비트 색 공간을 가져야 합니다." #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "디스플레이 회전은 90도씩 증가해야 합니다" @@ -1330,7 +1330,8 @@ msgstr "출력 함수로 인해 종료되었다" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2344,6 +2345,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "" @@ -3252,10 +3254,6 @@ msgstr "" msgid "file write is not available" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "" @@ -4633,6 +4631,10 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#, fuzzy +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q가 %q에서 %q로 이동했습니다" + #, c-format #~ msgid "%%c requires int or char" #~ msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" diff --git a/locale/ru.po b/locale/ru.po index 83bfaf324d7f6..3b957b347c133 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -174,10 +174,6 @@ msgstr "Длинна %q должна быть <= %d" msgid "%q length must be >= %d" msgstr "Длинна %q должна быть >= %d" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "%q переместился из %q в %q" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q должно быть %d" @@ -862,6 +858,10 @@ msgstr "Основной код CircuitPython сильно разбился. У msgid "Clock unit in use" msgstr "Источник тактирования уже используется" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -960,6 +960,7 @@ msgstr "Дисплей должен иметь 16 битное цветовое #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "Поворот дисплея должен осуществляться с шагом 90 градусов" @@ -1317,7 +1318,8 @@ msgstr "Прерывается функцией выхода" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2324,6 +2326,7 @@ msgid "Unable to allocate to the heap." msgstr "Невозможно выделить место в куче." #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "Не удается создать блокировку" @@ -3257,10 +3260,6 @@ msgstr "Файл должен быть файлом, открытым в бай msgid "file write is not available" msgstr "Запись файлов недоступна" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "Файловая система должна предусматривать метод монтирования" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "Первый аргумент должен быть вызываемым" @@ -4650,6 +4649,12 @@ msgstr "zi должно быть типа float" msgid "zi must be of shape (n_section, 2)" msgstr "zi должен иметь форму (n_section, 2)" +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q переместился из %q в %q" + +#~ msgid "filesystem must provide mount method" +#~ msgstr "Файловая система должна предусматривать метод монтирования" + #~ msgid "start/end indices" #~ msgstr "Начальные/конечные индексы" diff --git a/locale/tr.po b/locale/tr.po index 4e03f59cbaffb..54155a605438a 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -172,10 +172,6 @@ msgstr "%q boyutu <= %d olmalıdır" msgid "%q length must be >= %d" msgstr "%q boyutu >= %d olmalıdır" -#: py/runtime.c -msgid "%q moved from %q to %q" -msgstr "" - #: py/argcheck.c msgid "%q must be %d" msgstr "%q, %d olmalıdır" @@ -854,6 +850,10 @@ msgstr "CircuitPython kor kodu patladı. Haydaaa!\n" msgid "Clock unit in use" msgstr "Saat ünitesi kullanımda" +#: ports/espressif/common-hal/mipidsi/Display.c +msgid "Color depth must be 16 or 24" +msgstr "" + #: shared-bindings/_bleio/Connection.c msgid "" "Connection has been disconnected and can no longer be used. Create a new " @@ -948,6 +948,7 @@ msgstr "Ekran 16 bitlik bir renk uzayına sahip olmalıdır." #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c msgid "Display rotation must be in 90 degree increments" msgstr "Ekran dönüşü 90 derecelik artışlarla olmalıdır" @@ -1296,7 +1297,8 @@ msgstr "" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/mipidsi/Display.c shared-bindings/pwmio/PWMOut.c #: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c #: shared-module/lvfontio/OnDiskFont.c @@ -2290,6 +2292,7 @@ msgid "Unable to allocate to the heap." msgstr "" #: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c msgid "Unable to create lock" msgstr "" @@ -3198,10 +3201,6 @@ msgstr "" msgid "file write is not available" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" msgstr "" From 91d4181a38c8dccff7fba060d512ed850d55010e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 5 Nov 2025 12:58:05 -0500 Subject: [PATCH 205/208] update frozen libraries --- frozen/Adafruit_CircuitPython_AHTx0 | 2 +- frozen/Adafruit_CircuitPython_APDS9960 | 2 +- frozen/Adafruit_CircuitPython_BLE | 2 +- frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center | 2 +- frozen/Adafruit_CircuitPython_Bitmap_Font | 2 +- frozen/Adafruit_CircuitPython_BusDevice | 2 +- frozen/Adafruit_CircuitPython_CircuitPlayground | 2 +- frozen/Adafruit_CircuitPython_ConnectionManager | 2 +- frozen/Adafruit_CircuitPython_Crickit | 2 +- frozen/Adafruit_CircuitPython_DRV2605 | 2 +- frozen/Adafruit_CircuitPython_DS3231 | 2 +- frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 | 2 +- frozen/Adafruit_CircuitPython_Display_Text | 2 +- frozen/Adafruit_CircuitPython_DotStar | 2 +- frozen/Adafruit_CircuitPython_ESP32SPI | 2 +- frozen/Adafruit_CircuitPython_FakeRequests | 2 +- frozen/Adafruit_CircuitPython_FocalTouch | 2 +- frozen/Adafruit_CircuitPython_HID | 2 +- frozen/Adafruit_CircuitPython_HTTPServer | 2 +- frozen/Adafruit_CircuitPython_IRRemote | 2 +- frozen/Adafruit_CircuitPython_IS31FL3731 | 2 +- frozen/Adafruit_CircuitPython_ImageLoad | 2 +- frozen/Adafruit_CircuitPython_LC709203F | 2 +- frozen/Adafruit_CircuitPython_LED_Animation | 2 +- frozen/Adafruit_CircuitPython_LIS3DH | 2 +- frozen/Adafruit_CircuitPython_LSM6DS | 2 +- frozen/Adafruit_CircuitPython_MIDI | 2 +- frozen/Adafruit_CircuitPython_MPU6050 | 2 +- frozen/Adafruit_CircuitPython_Motor | 2 +- frozen/Adafruit_CircuitPython_NeoPixel | 2 +- frozen/Adafruit_CircuitPython_PCF8563 | 2 +- frozen/Adafruit_CircuitPython_Pixel_Framebuf | 2 +- frozen/Adafruit_CircuitPython_PortalBase | 2 +- frozen/Adafruit_CircuitPython_ProgressBar | 2 +- frozen/Adafruit_CircuitPython_RFM69 | 2 +- frozen/Adafruit_CircuitPython_RFM9x | 2 +- frozen/Adafruit_CircuitPython_Register | 2 +- frozen/Adafruit_CircuitPython_Requests | 2 +- frozen/Adafruit_CircuitPython_SD | 2 +- frozen/Adafruit_CircuitPython_SHT4x | 2 +- frozen/Adafruit_CircuitPython_SSD1306 | 2 +- frozen/Adafruit_CircuitPython_SSD1680 | 2 +- frozen/Adafruit_CircuitPython_ST7789 | 2 +- frozen/Adafruit_CircuitPython_SimpleIO | 2 +- frozen/Adafruit_CircuitPython_SimpleMath | 2 +- frozen/Adafruit_CircuitPython_Thermistor | 2 +- frozen/Adafruit_CircuitPython_Ticks | 2 +- frozen/Adafruit_CircuitPython_UC8151D | 2 +- frozen/Adafruit_CircuitPython_Wave | 2 +- frozen/Adafruit_CircuitPython_Wiznet5k | 2 +- frozen/Adafruit_CircuitPython_asyncio | 2 +- frozen/Adafruit_CircuitPython_framebuf | 2 +- frozen/Adafruit_CircuitPython_seesaw | 2 +- 53 files changed, 53 insertions(+), 53 deletions(-) diff --git a/frozen/Adafruit_CircuitPython_AHTx0 b/frozen/Adafruit_CircuitPython_AHTx0 index ff95dd5f3d018..8c61ed111fc83 160000 --- a/frozen/Adafruit_CircuitPython_AHTx0 +++ b/frozen/Adafruit_CircuitPython_AHTx0 @@ -1 +1 @@ -Subproject commit ff95dd5f3d0186c5cdc8bd8cb34ac22ac2e2225d +Subproject commit 8c61ed111fc83e4e1703cf5e014e645f4dbbef32 diff --git a/frozen/Adafruit_CircuitPython_APDS9960 b/frozen/Adafruit_CircuitPython_APDS9960 index 00127a75d22f0..f05a7239131dc 160000 --- a/frozen/Adafruit_CircuitPython_APDS9960 +++ b/frozen/Adafruit_CircuitPython_APDS9960 @@ -1 +1 @@ -Subproject commit 00127a75d22f035096ea9317ad57c74c6a9b4232 +Subproject commit f05a7239131dc05df949e49c1bb5732529a864bf diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index 1acb303cc7f63..6744b6869e4c3 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit 1acb303cc7f63a752c9fb87655d2ec478e564be2 +Subproject commit 6744b6869e4c3112610132bcac23535ae5ef3983 diff --git a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center index 476082b43c9e5..e162713efa578 160000 --- a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center +++ b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center @@ -1 +1 @@ -Subproject commit 476082b43c9e5971da20a320a05546a8285d4891 +Subproject commit e162713efa578b9967f7ec921b129362036571b3 diff --git a/frozen/Adafruit_CircuitPython_Bitmap_Font b/frozen/Adafruit_CircuitPython_Bitmap_Font index 5ca3f55f2e393..13c6a39a58e28 160000 --- a/frozen/Adafruit_CircuitPython_Bitmap_Font +++ b/frozen/Adafruit_CircuitPython_Bitmap_Font @@ -1 +1 @@ -Subproject commit 5ca3f55f2e39302c787ca93f95276e8269024038 +Subproject commit 13c6a39a58e28030f3651a90e116c1ab30f2035b diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index afe91665e4389..baa6bcafa2251 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit afe91665e438947bd3d88ba4a0f937ec58ff1035 +Subproject commit baa6bcafa22512ac56f343c7d124f3b029861c33 diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index d093fed40590a..65be0763beda7 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit d093fed40590af312e44b1efa8d88ecaef9aaed4 +Subproject commit 65be0763beda780d3a1a8c4c49b033628bc54d28 diff --git a/frozen/Adafruit_CircuitPython_ConnectionManager b/frozen/Adafruit_CircuitPython_ConnectionManager index 95f39faaa647b..2c85f3b98d081 160000 --- a/frozen/Adafruit_CircuitPython_ConnectionManager +++ b/frozen/Adafruit_CircuitPython_ConnectionManager @@ -1 +1 @@ -Subproject commit 95f39faaa647b4215f615603368a453742423a09 +Subproject commit 2c85f3b98d08102d2494195074ad836fc3020610 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index efeb183228ff9..722f7937bfb0c 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit efeb183228ff9640aec5938f9c2305766579dc25 +Subproject commit 722f7937bfb0c02340dcf737ebf37cc4ecf86b83 diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index f120d56222166..616d61c7495e5 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit f120d56222166af85b33e8e9c70eff6aec2e4828 +Subproject commit 616d61c7495e5dadc6b77ea9fce07a3861580534 diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index a5d94eee49d32..62cc4dc49b587 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit a5d94eee49d324bad474847749c3d481a1f7c908 +Subproject commit 62cc4dc49b587fad935368ed60b9ba1433250fdc diff --git a/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 b/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 index 4b382e8986db3..89463c9bd81aa 160000 --- a/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 +++ b/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 @@ -1 +1 @@ -Subproject commit 4b382e8986db36eaef558fec67be543205f268b2 +Subproject commit 89463c9bd81aaf43a14fd4f3c7bdbb75d4e48b40 diff --git a/frozen/Adafruit_CircuitPython_Display_Text b/frozen/Adafruit_CircuitPython_Display_Text index 7d1f187aac8e8..727a1022e140b 160000 --- a/frozen/Adafruit_CircuitPython_Display_Text +++ b/frozen/Adafruit_CircuitPython_Display_Text @@ -1 +1 @@ -Subproject commit 7d1f187aac8e899e791324cc78633bf4f32c984b +Subproject commit 727a1022e140b971a2f4bde5e6571dd327f6785d diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index 4b0ba649e5abd..8d19e1b23cbe6 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit 4b0ba649e5abdebead5b9a47a6c695d67c2c25fa +Subproject commit 8d19e1b23cbe6c1d17a29f321d06b16d21909b92 diff --git a/frozen/Adafruit_CircuitPython_ESP32SPI b/frozen/Adafruit_CircuitPython_ESP32SPI index 063b90c8706dd..3fcea236876b0 160000 --- a/frozen/Adafruit_CircuitPython_ESP32SPI +++ b/frozen/Adafruit_CircuitPython_ESP32SPI @@ -1 +1 @@ -Subproject commit 063b90c8706ddef97cc4abf9cb78e0cc09ff3c6c +Subproject commit 3fcea236876b05d09ebf95f43cec6016667ccf84 diff --git a/frozen/Adafruit_CircuitPython_FakeRequests b/frozen/Adafruit_CircuitPython_FakeRequests index 020121e90c630..ff942eaae8351 160000 --- a/frozen/Adafruit_CircuitPython_FakeRequests +++ b/frozen/Adafruit_CircuitPython_FakeRequests @@ -1 +1 @@ -Subproject commit 020121e90c6306147f91b8079b75f3d14ff86138 +Subproject commit ff942eaae835144f7269d8206adf506c99f699f4 diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index 2fb86313db340..f20c13bdffa9b 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit 2fb86313db3408e57b1fbfbc56359ccb4f16f38b +Subproject commit f20c13bdffa9b586c648f331851f427368a995ae diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index d06b8b812caef..788e46ca2cb2f 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit d06b8b812caef3ae2eebb662f4e57ca306ce3219 +Subproject commit 788e46ca2cb2febddac83e0c660972598d6a8a27 diff --git a/frozen/Adafruit_CircuitPython_HTTPServer b/frozen/Adafruit_CircuitPython_HTTPServer index c43147a016ffd..e234a4940504b 160000 --- a/frozen/Adafruit_CircuitPython_HTTPServer +++ b/frozen/Adafruit_CircuitPython_HTTPServer @@ -1 +1 @@ -Subproject commit c43147a016ffd13c57a0923730bc6a83afefb4ad +Subproject commit e234a4940504b4fb21c7338d774ec273260ef672 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index b92d69304212e..98bd8fad8cd65 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit b92d69304212ee57a5f008317fcc4ebaf75ddebb +Subproject commit 98bd8fad8cd65f481b8808e5de8cdbf62d0dd300 diff --git a/frozen/Adafruit_CircuitPython_IS31FL3731 b/frozen/Adafruit_CircuitPython_IS31FL3731 index a0d701892d8be..1babff02ea87f 160000 --- a/frozen/Adafruit_CircuitPython_IS31FL3731 +++ b/frozen/Adafruit_CircuitPython_IS31FL3731 @@ -1 +1 @@ -Subproject commit a0d701892d8bef096d80f1117bee718cecb380ff +Subproject commit 1babff02ea87f5c4863aed20be0da553d76e9600 diff --git a/frozen/Adafruit_CircuitPython_ImageLoad b/frozen/Adafruit_CircuitPython_ImageLoad index 135b0e4478b34..67532099f7a57 160000 --- a/frozen/Adafruit_CircuitPython_ImageLoad +++ b/frozen/Adafruit_CircuitPython_ImageLoad @@ -1 +1 @@ -Subproject commit 135b0e4478b34e1271e6bd87fa6d8efa0bef64b5 +Subproject commit 67532099f7a574f08955b31efb7c1ca5cc3f143c diff --git a/frozen/Adafruit_CircuitPython_LC709203F b/frozen/Adafruit_CircuitPython_LC709203F index b007bcae07b34..7fe15ca666bd3 160000 --- a/frozen/Adafruit_CircuitPython_LC709203F +++ b/frozen/Adafruit_CircuitPython_LC709203F @@ -1 +1 @@ -Subproject commit b007bcae07b346fd28aaee770dcabc9dde698c67 +Subproject commit 7fe15ca666bd3730a17e13bb29ff884092345b5f diff --git a/frozen/Adafruit_CircuitPython_LED_Animation b/frozen/Adafruit_CircuitPython_LED_Animation index 8af05705962e8..515553f0b6cb1 160000 --- a/frozen/Adafruit_CircuitPython_LED_Animation +++ b/frozen/Adafruit_CircuitPython_LED_Animation @@ -1 +1 @@ -Subproject commit 8af05705962e8bb7d2f8003e6a70916a9a51b863 +Subproject commit 515553f0b6cb1290b92965f8e4e8beab9e83bcf1 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index 640b18ec1bfd7..a3c33eff7c03e 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit 640b18ec1bfd71e0a70f7ff3b8784043cd2d2671 +Subproject commit a3c33eff7c03e7c1f1e896a08f4878f5db6a6cbf diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index 2f50836f4bf0d..e7da74fd8d7fd 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit 2f50836f4bf0d9e48e4b8e046ba4d4167ad6dbdc +Subproject commit e7da74fd8d7fddd9515e975be5479596283a719c diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI index c4e693c2d4904..2bc5554857727 160000 --- a/frozen/Adafruit_CircuitPython_MIDI +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -1 +1 @@ -Subproject commit c4e693c2d4904d885cf842efc25687ccaccbabfa +Subproject commit 2bc555485772743b70f620fe939048020924a605 diff --git a/frozen/Adafruit_CircuitPython_MPU6050 b/frozen/Adafruit_CircuitPython_MPU6050 index 05a0c3b72279d..bb5100733f339 160000 --- a/frozen/Adafruit_CircuitPython_MPU6050 +++ b/frozen/Adafruit_CircuitPython_MPU6050 @@ -1 +1 @@ -Subproject commit 05a0c3b72279db9fa2431308a77e6ab7ba040c8a +Subproject commit bb5100733f339dcad24df7d32eeeb492023b5059 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index 89facc69a405a..610c42f118704 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit 89facc69a405ae83702ce566414adc39d46068f1 +Subproject commit 610c42f1187045fb962807ac8d895e66e2612298 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index 0ba2f2122a54a..1a9523574b68c 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit 0ba2f2122a54a71b1bc3576f87b1ba7dfc9db11e +Subproject commit 1a9523574b68cc205c151aaf080909348df7417c diff --git a/frozen/Adafruit_CircuitPython_PCF8563 b/frozen/Adafruit_CircuitPython_PCF8563 index 74bb72d1c607e..3f40c877acbbd 160000 --- a/frozen/Adafruit_CircuitPython_PCF8563 +++ b/frozen/Adafruit_CircuitPython_PCF8563 @@ -1 +1 @@ -Subproject commit 74bb72d1c607e44cf0d5349c466acd34863c11b4 +Subproject commit 3f40c877acbbda0ef82336c18f3620ce1b9013f5 diff --git a/frozen/Adafruit_CircuitPython_Pixel_Framebuf b/frozen/Adafruit_CircuitPython_Pixel_Framebuf index 1db789cf99429..d355df47c0d5c 160000 --- a/frozen/Adafruit_CircuitPython_Pixel_Framebuf +++ b/frozen/Adafruit_CircuitPython_Pixel_Framebuf @@ -1 +1 @@ -Subproject commit 1db789cf99429e27d740279000788edc794d9d0d +Subproject commit d355df47c0d5c1f80da01c86d585223988f30a33 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index d26e2324de496..25fc43dd67ae9 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit d26e2324de496761e0aa72abc30ba07cdce8814b +Subproject commit 25fc43dd67ae95a8e62173e90c3069502194873a diff --git a/frozen/Adafruit_CircuitPython_ProgressBar b/frozen/Adafruit_CircuitPython_ProgressBar index 6ba9d9d991ada..9fa23112cea1a 160000 --- a/frozen/Adafruit_CircuitPython_ProgressBar +++ b/frozen/Adafruit_CircuitPython_ProgressBar @@ -1 +1 @@ -Subproject commit 6ba9d9d991ada6c0cea6a32bd64595cfd37e06b2 +Subproject commit 9fa23112cea1a8db2b9b87cf2156cc4b039440a7 diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 index 07be137bf5bda..62cb5cf6fbeb9 160000 --- a/frozen/Adafruit_CircuitPython_RFM69 +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -1 +1 @@ -Subproject commit 07be137bf5bda7a0469225c9cbb09b9a0aa08791 +Subproject commit 62cb5cf6fbeb9943bf7b2db4fc614f9b40830bf3 diff --git a/frozen/Adafruit_CircuitPython_RFM9x b/frozen/Adafruit_CircuitPython_RFM9x index 609aafb018b1c..5b8a9ae0ace6b 160000 --- a/frozen/Adafruit_CircuitPython_RFM9x +++ b/frozen/Adafruit_CircuitPython_RFM9x @@ -1 +1 @@ -Subproject commit 609aafb018b1cf5b7f60f2a7c961b827dce7468e +Subproject commit 5b8a9ae0ace6bd5f3a0860c95c3c389a09e4b59b diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index 96d0a4774f552..98faa16a0dd6c 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit 96d0a4774f5525b926c131618e436b8e5c218a2f +Subproject commit 98faa16a0dd6c63a2726b291a53fde760a0fcabb diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 5e646b244cf36..1479169b59d06 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 5e646b244cf36f879f15aaf77a270e4c7e6e8336 +Subproject commit 1479169b59d069b15384da64645f1e2d711a4679 diff --git a/frozen/Adafruit_CircuitPython_SD b/frozen/Adafruit_CircuitPython_SD index ee4d73293c8d0..dfbb9fd6ae297 160000 --- a/frozen/Adafruit_CircuitPython_SD +++ b/frozen/Adafruit_CircuitPython_SD @@ -1 +1 @@ -Subproject commit ee4d73293c8d059cd0c8bcf46758e62f5393cbee +Subproject commit dfbb9fd6ae297d6246554ea44e6c318970de98af diff --git a/frozen/Adafruit_CircuitPython_SHT4x b/frozen/Adafruit_CircuitPython_SHT4x index 26a0a407d43bd..9da248ca94426 160000 --- a/frozen/Adafruit_CircuitPython_SHT4x +++ b/frozen/Adafruit_CircuitPython_SHT4x @@ -1 +1 @@ -Subproject commit 26a0a407d43bd6208deffdf577e214d899855c0e +Subproject commit 9da248ca944264cbc4278c1732f901f3e1229231 diff --git a/frozen/Adafruit_CircuitPython_SSD1306 b/frozen/Adafruit_CircuitPython_SSD1306 index d75b4d593cd18..2d7fd1fd8f7bb 160000 --- a/frozen/Adafruit_CircuitPython_SSD1306 +++ b/frozen/Adafruit_CircuitPython_SSD1306 @@ -1 +1 @@ -Subproject commit d75b4d593cd184cbea5e237f5212cd9122d46263 +Subproject commit 2d7fd1fd8f7bb1b83d60926a28ab01ffaf67fa3b diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 index d6aa01c4f8fa1..c22e6d097b44c 160000 --- a/frozen/Adafruit_CircuitPython_SSD1680 +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -1 +1 @@ -Subproject commit d6aa01c4f8fa1004430bfcdd4db2219183425693 +Subproject commit c22e6d097b44c6e9612ff6b866ebec569796e6f5 diff --git a/frozen/Adafruit_CircuitPython_ST7789 b/frozen/Adafruit_CircuitPython_ST7789 index 0f7269267c0d1..1060cf1753df0 160000 --- a/frozen/Adafruit_CircuitPython_ST7789 +++ b/frozen/Adafruit_CircuitPython_ST7789 @@ -1 +1 @@ -Subproject commit 0f7269267c0d17ada34926333bbda4021e5d7cb3 +Subproject commit 1060cf1753df0024a95070132045357ddd9ce559 diff --git a/frozen/Adafruit_CircuitPython_SimpleIO b/frozen/Adafruit_CircuitPython_SimpleIO index d5278d246bcf6..054d2643744fe 160000 --- a/frozen/Adafruit_CircuitPython_SimpleIO +++ b/frozen/Adafruit_CircuitPython_SimpleIO @@ -1 +1 @@ -Subproject commit d5278d246bcf658ef5d44e7658c956fac29bd9e1 +Subproject commit 054d2643744fe78fed3c4c8b371ced26c8ab2ebe diff --git a/frozen/Adafruit_CircuitPython_SimpleMath b/frozen/Adafruit_CircuitPython_SimpleMath index 33f82828598a3..da27f05235713 160000 --- a/frozen/Adafruit_CircuitPython_SimpleMath +++ b/frozen/Adafruit_CircuitPython_SimpleMath @@ -1 +1 @@ -Subproject commit 33f82828598a3a10c73dfa50601fef4beac40be8 +Subproject commit da27f05235713bc8e79cf3a005d11bab920e13bb diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 2b45967cc5283..f109e9d847b7f 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 2b45967cc5283e71b7826f6a158d8c8556dde287 +Subproject commit f109e9d847b7f8ba8545a2b6be8d0c3dd6a8a280 diff --git a/frozen/Adafruit_CircuitPython_Ticks b/frozen/Adafruit_CircuitPython_Ticks index 6e159f899b017..83695404ab734 160000 --- a/frozen/Adafruit_CircuitPython_Ticks +++ b/frozen/Adafruit_CircuitPython_Ticks @@ -1 +1 @@ -Subproject commit 6e159f899b017e920a6058a6b16735af8a6e852e +Subproject commit 83695404ab734eb60d32c9e96784b9bd90c58a1a diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D index 4ebf9c2854376..b9bd61a0bbef1 160000 --- a/frozen/Adafruit_CircuitPython_UC8151D +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -1 +1 @@ -Subproject commit 4ebf9c2854376a06766a6ae4732a4537a766fb75 +Subproject commit b9bd61a0bbef1f4705abb831739d4888f1dcec95 diff --git a/frozen/Adafruit_CircuitPython_Wave b/frozen/Adafruit_CircuitPython_Wave index 6fba948b024ec..d302cd78d29ef 160000 --- a/frozen/Adafruit_CircuitPython_Wave +++ b/frozen/Adafruit_CircuitPython_Wave @@ -1 +1 @@ -Subproject commit 6fba948b024ec210b3cf1f1b068b3eebc82fe8d4 +Subproject commit d302cd78d29ef821faa1c18482a0b20fdca1d4ee diff --git a/frozen/Adafruit_CircuitPython_Wiznet5k b/frozen/Adafruit_CircuitPython_Wiznet5k index 736241c7a22f8..ea7b97c5b1faa 160000 --- a/frozen/Adafruit_CircuitPython_Wiznet5k +++ b/frozen/Adafruit_CircuitPython_Wiznet5k @@ -1 +1 @@ -Subproject commit 736241c7a22f86dcf8ff73a77c4536cedfdc4cdd +Subproject commit ea7b97c5b1faa2db4b54d7f6d9a61b545b49f383 diff --git a/frozen/Adafruit_CircuitPython_asyncio b/frozen/Adafruit_CircuitPython_asyncio index 24818f817f511..e69ac03dccfd8 160000 --- a/frozen/Adafruit_CircuitPython_asyncio +++ b/frozen/Adafruit_CircuitPython_asyncio @@ -1 +1 @@ -Subproject commit 24818f817f5118f59aa696a04776049c179c0f4f +Subproject commit e69ac03dccfd87ccaf3655dc751331ff922f525f diff --git a/frozen/Adafruit_CircuitPython_framebuf b/frozen/Adafruit_CircuitPython_framebuf index 0fedf2f308ed6..8a94ddb7257be 160000 --- a/frozen/Adafruit_CircuitPython_framebuf +++ b/frozen/Adafruit_CircuitPython_framebuf @@ -1 +1 @@ -Subproject commit 0fedf2f308ed6b3e8261661e4810e613f33d7171 +Subproject commit 8a94ddb7257bebfb856fe476d9b851dfa63ce443 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 94c541f45313d..d01642926b80a 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 94c541f45313dc7eb98a4cd1a6c3af39f001cc49 +Subproject commit d01642926b80a46762f1dd76dcdd5aefb0d95bc8 From 3f0b1b8c9d9fc41b29ef5fd36cb8283b75c48198 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 14 Nov 2025 12:20:00 -0800 Subject: [PATCH 206/208] Fix mipidsi cache flush The old way didn't flush all caches and left artifacts. Fixes #10708 --- ports/espressif/common-hal/mipidsi/Display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ports/espressif/common-hal/mipidsi/Display.c b/ports/espressif/common-hal/mipidsi/Display.c index dac16162e91ff..cc45db72375a2 100644 --- a/ports/espressif/common-hal/mipidsi/Display.c +++ b/ports/espressif/common-hal/mipidsi/Display.c @@ -213,8 +213,9 @@ bool common_hal_mipidsi_display_deinited(mipidsi_display_obj_t *self) { } void common_hal_mipidsi_display_refresh(mipidsi_display_obj_t *self) { - // Write back the cache to ensure framebuffer changes are visible - Cache_WriteBack_Addr((uint32_t)(self->framebuffer), self->framebuffer_size); + // Drawing the framebuffer we got from the IDF will flush the cache(s) so + // DMA can see our changes. It won't cause an extra copy. + esp_lcd_panel_draw_bitmap(self->dpi_panel_handle, 0, 0, self->width, self->height, self->framebuffer); // The DPI panel will automatically refresh from the framebuffer // No explicit refresh call is needed as the DSI hardware continuously From b35fbdc624c19ae8b4b034d59e5b175b705b4594 Mon Sep 17 00:00:00 2001 From: Hans Maerki Date: Thu, 20 Nov 2025 21:24:47 +0000 Subject: [PATCH 207/208] Allow microcontroller.nvm to be bigger than 8k Signed-off-by: Hans Maerki --- shared-bindings/nvm/ByteArray.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index be01c1f706414..b278300626737 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -35,7 +35,7 @@ //| static mp_obj_t nvm_bytearray_unary_op(mp_unary_op_t op, mp_obj_t self_in) { nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint16_t len = common_hal_nvm_bytearray_get_length(self); + uint32_t len = common_hal_nvm_bytearray_get_length(self); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); From 70a3af8cf86b31cd6a20e318cd7af222b558944c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 17 Nov 2025 12:10:37 -0800 Subject: [PATCH 208/208] Update to Zephyr v4.3.0 --- .../actions/deps/ports/zephyr-cp/action.yml | 6 + ports/zephyr-cp/README.md | 4 +- .../boards/nrf7002dk_nrf5340_cpuapp.conf | 2 +- .../zephyr-cp/cptools/build_circuitpython.py | 21 +- ports/zephyr-cp/cptools/compat2driver.py | 742 ++++++++++++++++-- ports/zephyr-cp/cptools/cpbuild.py | 89 ++- ports/zephyr-cp/cptools/gen_compat2driver.py | 2 +- ports/zephyr-cp/cptools/zephyr2cp.py | 93 ++- ports/zephyr-cp/prj.conf | 2 +- ports/zephyr-cp/zephyr-config/west.yml | 2 +- 10 files changed, 838 insertions(+), 125 deletions(-) diff --git a/.github/actions/deps/ports/zephyr-cp/action.yml b/.github/actions/deps/ports/zephyr-cp/action.yml index cfa1177598e4d..75ff232562c4d 100644 --- a/.github/actions/deps/ports/zephyr-cp/action.yml +++ b/.github/actions/deps/ports/zephyr-cp/action.yml @@ -3,6 +3,12 @@ name: Fetch Zephyr port deps runs: using: composite steps: + - name: Get libusb + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libusb-1.0-0-dev libudev-dev + shell: bash - name: Setup Zephyr project uses: zephyrproject-rtos/action-zephyr-setup@v1 with: diff --git a/ports/zephyr-cp/README.md b/ports/zephyr-cp/README.md index 4d08936cad66c..1fba1d7d3f7f4 100644 --- a/ports/zephyr-cp/README.md +++ b/ports/zephyr-cp/README.md @@ -15,11 +15,11 @@ pip install west west init -l zephyr-config west update west zephyr-export -pip install -r lib/zephyr/scripts/requirements.txt +pip install -r zephyr/scripts/requirements.txt west sdk install ``` -Now to build from the top level: +Now to build from `ports/zephyr-cp`: ```sh make BOARD=nordic_nrf7002dk diff --git a/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf index 6f01624bb3a4a..c61851fad2d24 100644 --- a/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf +++ b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -1,7 +1,7 @@ CONFIG_NETWORKING=y CONFIG_WIFI=y -CONFIG_MBEDTLS_TLS_VERSION_1_2=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y CONFIG_MBEDTLS_USE_PSA_CRYPTO=n CONFIG_BT=y diff --git a/ports/zephyr-cp/cptools/build_circuitpython.py b/ports/zephyr-cp/cptools/build_circuitpython.py index 61e103e9fe109..fd1ca7dc43ffc 100644 --- a/ports/zephyr-cp/cptools/build_circuitpython.py +++ b/ports/zephyr-cp/cptools/build_circuitpython.py @@ -1,16 +1,16 @@ import asyncio -import colorlog -import sys import logging import os import pathlib -import tomllib -import tomlkit -import yaml import pickle +import sys -import cpbuild import board_tools +import colorlog +import cpbuild +import tomlkit +import tomllib +import yaml logger = logging.getLogger(__name__) @@ -219,13 +219,13 @@ async def build_circuitpython(): circuitpython_flags.append(f"-DCIRCUITPY_ENABLE_MPY_NATIVE={1 if enable_mpy_native else 0}") circuitpython_flags.append(f"-DCIRCUITPY_FULL_BUILD={1 if full_build else 0}") circuitpython_flags.append(f"-DCIRCUITPY_USB_HOST={1 if usb_host else 0}") - circuitpython_flags.append(f'-DCIRCUITPY_BOARD_ID=\\"{board}\\"') + circuitpython_flags.append(f"-DCIRCUITPY_BOARD_ID='\"{board}\"'") circuitpython_flags.append(f"-DCIRCUITPY_TUSB_MEM_ALIGN={tusb_mem_align}") circuitpython_flags.append(f"-DCIRCUITPY_TRANSLATE_OBJECT={1 if lto else 0}") circuitpython_flags.append("-DINTERNAL_FLASH_FILESYSTEM") circuitpython_flags.append("-DLONGINT_IMPL_MPZ") circuitpython_flags.append("-DCIRCUITPY_SSL_MBEDTLS") - circuitpython_flags.append('-DFFCONF_H=\\"lib/oofatfs/ffconf.h\\"') + circuitpython_flags.append("-DFFCONF_H='\"lib/oofatfs/ffconf.h\"'") circuitpython_flags.extend(("-I", srcdir)) circuitpython_flags.extend(("-I", srcdir / "lib/tinyusb/src")) circuitpython_flags.extend(("-I", srcdir / "supervisor/shared/usb")) @@ -448,10 +448,7 @@ async def build_circuitpython(): if "ssl" in enabled_modules: # TODO: Figure out how to get these paths from zephyr - circuitpython_flags.append('-DMBEDTLS_CONFIG_FILE=\\"config-tls-generic.h\\"') - circuitpython_flags.extend( - ("-isystem", portdir / "modules" / "crypto" / "tinycrypt" / "lib" / "include") - ) + circuitpython_flags.append("-DMBEDTLS_CONFIG_FILE='\"config-mbedtls.h\"'") circuitpython_flags.extend( ("-isystem", portdir / "modules" / "crypto" / "mbedtls" / "include") ) diff --git a/ports/zephyr-cp/cptools/compat2driver.py b/ports/zephyr-cp/cptools/compat2driver.py index 2b818c4c23762..dff09787b2881 100644 --- a/ports/zephyr-cp/cptools/compat2driver.py +++ b/ports/zephyr-cp/cptools/compat2driver.py @@ -1,18 +1,29 @@ # This file was generated by gen_compat2driver.py COMPAT_TO_DRIVER = { # adc + "adi_ad4050_adc": "adc", + "adi_ad4052_adc": "adc", "adi_ad4114_adc": "adc", + "adi_ad4130_adc": "adc", + "adi_ad4170_adc": "adc", + "adi_ad4190_adc": "adc", + "adi_ad4195_adc": "adc", "adi_ad559x_adc": "adc", + "adi_ad7124_adc": "adc", "adi_max32_adc": "adc", "ambiq_adc": "adc", "atmel_sam0_adc": "adc", "atmel_sam_adc": "adc", "atmel_sam_afec": "adc", + "ene_kb106x_adc": "adc", "ene_kb1200_adc": "adc", "espressif_esp32_adc": "adc", "gd_gd32_adc": "adc", + "infineon_autanalog_sar_adc": "adc", "infineon_cat1_adc": "adc", + "infineon_hppass_sar_adc": "adc", "infineon_xmc4xxx_adc": "adc", + "ite_it51xxx_adc": "adc", "ite_it8xxx2_adc": "adc", "lltc_ltc2451": "adc", "maxim_max11102": "adc", @@ -26,6 +37,7 @@ "maxim_max11117": "adc", "maxim_max11253": "adc", "maxim_max11254": "adc", + "microchip_mcp356xr": "adc", "microchip_xec_adc": "adc", "nordic_nrf_adc": "adc", "nordic_nrf_saadc": "adc", @@ -37,13 +49,19 @@ "nxp_lpc_lpadc": "adc", "nxp_mcux_12b1msps_sar": "adc", "nxp_s32_adc_sar": "adc", + "nxp_sar_adc": "adc", "nxp_vf610_adc": "adc", "raspberrypi_pico_adc": "adc", + "realtek_rts5912_adc": "adc", "renesas_ra_adc": "adc", + "renesas_rx_adc": "adc", + "renesas_rz_adc": "adc", + "renesas_rz_adc_c": "adc", "renesas_smartbond_adc": "adc", "renesas_smartbond_sdadc": "adc", "silabs_gecko_adc": "adc", - "silabs_gecko_iadc": "adc", + "silabs_iadc": "adc", + "silabs_siwx91x_adc": "adc", "st_stm32_adc": "adc", "st_stm32wb0_adc": "adc", "telink_b91_adc": "adc", @@ -55,10 +73,15 @@ "ti_ads1114": "adc", "ti_ads1115": "adc", "ti_ads1119": "adc", + "ti_ads114s06": "adc", "ti_ads114s08": "adc", + "ti_ads124s06": "adc", + "ti_ads124s08": "adc", "ti_ads131m02": "adc", "ti_ads7052": "adc", + "ti_am335x_adc": "adc", "ti_cc13xx_cc26xx_adc": "adc", + "ti_cc23x0_adc": "adc", "ti_cc32xx_adc": "adc", "ti_lmp90077": "adc", "ti_lmp90078": "adc", @@ -72,26 +95,42 @@ "ti_tla2022": "adc", "ti_tla2024": "adc", "vnd_adc": "adc", + "wch_adc": "adc", "zephyr_adc_emul": "adc", # # audio + "ambiq_pdm": "audio", + "cirrus_cs43l22": "audio", + "dlg_da7212": "audio", + "maxim_max98091": "audio", "nxp_dmic": "audio", + "nxp_micfil": "audio", "st_mpxxdtyy": "audio", + "ti_pcm1681": "audio", "ti_tas6422dac": "audio", + "ti_tlv320aic3110": "audio", "ti_tlv320dac": "audio", "wolfson_wm8904": "audio", + "wolfson_wm8962": "audio", + # + # audio/mic_privacy/intel + "intel_adsp_mic_privacy": "audio/mic_privacy/intel", # # auxdisplay + "gpio_7_segment": "auxdisplay", "hit_hd44780": "auxdisplay", "jhd_jhd1313": "auxdisplay", "noritake_itron": "auxdisplay", "ptc_pt6314": "auxdisplay", "sparkfun_serlcd": "auxdisplay", + "titanmec_tm1637": "auxdisplay", # # bbram "ite_it8xxx2_bbram": "bbram", "microchip_xec_bbram": "bbram", + "motorola_mc146818_bbram": "bbram", "nuvoton_npcx_bbram": "bbram", + "realtek_rts5912_bbram": "bbram", "st_stm32_bbram": "bbram", "zephyr_bbram_emul": "bbram", # @@ -106,6 +145,7 @@ "renesas_bt_hci_da1453x": "bluetooth/hci", "renesas_bt_hci_da1469x": "bluetooth/hci", "silabs_bt_hci_efr32": "bluetooth/hci", + "silabs_siwx91x_bt_hci": "bluetooth/hci", "st_hci_spi_v1": "bluetooth/hci", "st_hci_spi_v2": "bluetooth/hci", "st_hci_stm32wb0": "bluetooth/hci", @@ -117,7 +157,11 @@ "zephyr_bt_hci_uart": "bluetooth/hci", "zephyr_bt_hci_userchan": "bluetooth/hci", # + # cache + "bflb_l1c": "cache", + # # can + "adi_max32_can": "can", "atmel_sam0_can": "can", "atmel_sam_can": "can", "espressif_esp32_twai": "can", @@ -132,6 +176,7 @@ "nxp_s32_canxl": "can", "renesas_ra_canfd": "can", "renesas_rcar_can": "can", + "renesas_rz_canfd": "can", "st_stm32_bxcan": "can", "st_stm32_fdcan": "can", "st_stm32h7_fdcan": "can", @@ -145,9 +190,13 @@ # # charger "maxim_max20335_charger": "charger", + "nxp_pca9422_charger": "charger", + "nxp_pf1550_charger": "charger", "sbs_sbs_charger": "charger", "ti_bq24190": "charger", "ti_bq25180": "charger", + "ti_bq25713": "charger", + "x_powers_axp2101_charger": "charger", # # clock_control "adi_max32_gcr": "clock_control", @@ -156,10 +205,20 @@ "arm_scmi_clock": "clock_control", "aspeed_ast10x0_clock": "clock_control", "atmel_sam_pmc": "clock_control", - "espressif_esp32_rtc": "clock_control", + "bflb_bl60x_clock_controller": "clock_control", + "bflb_bl61x_clock_controller": "clock_control", + "bflb_bl70x_clock_controller": "clock_control", + "espressif_esp32_clock": "clock_control", "fixed_clock": "clock_control", "gd_gd32_cctl": "clock_control", + "infineon_fixed_clock": "clock_control", + "infineon_fixed_factor_clock": "clock_control", + "infineon_peri_div": "clock_control", "intel_agilex5_clock": "clock_control", + "ite_it51xxx_ecpm": "clock_control", + "microchip_sam_d5x_e5x_clock": "clock_control", + "microchip_sam_pmc": "clock_control", + "microchip_sama7g5_sckc": "clock_control", "microchip_xec_pcr": "clock_control", "nordic_nrf54h_hfxo": "clock_control", "nordic_nrf_auxpll": "clock_control", @@ -167,7 +226,9 @@ "nordic_nrf_fll16m": "clock_control", "nordic_nrf_hsfll_global": "clock_control", "nordic_nrf_hsfll_local": "clock_control", + "nordic_nrf_iron_hsfll_local": "clock_control", "nordic_nrf_lfclk": "clock_control", + "nordic_nrfs_audiopll": "clock_control", "nuvoton_npcm_pcc": "clock_control", "nuvoton_npcx_pcc": "clock_control", "nuvoton_numaker_scc": "clock_control", @@ -179,6 +240,7 @@ "nxp_kinetis_sim": "clock_control", "nxp_lpc11u6x_syscon": "clock_control", "nxp_lpc_syscon": "clock_control", + "nxp_mc_cgm": "clock_control", "nxp_s32_clock": "clock_control", "nxp_scg_k4": "clock_control", "openisa_rv32m1_pcc": "clock_control", @@ -187,10 +249,20 @@ "realtek_rts5912_sccon": "clock_control", "renesas_r8a7795_cpg_mssr": "clock_control", "renesas_r8a779f0_cpg_mssr": "clock_control", + "renesas_ra_cgc_subclk": "clock_control", + "renesas_rx_cgc_pclk": "clock_control", + "renesas_rx_cgc_pll": "clock_control", + "renesas_rx_cgc_root_clock": "clock_control", + "renesas_rz_cgc": "clock_control", + "renesas_rz_cpg": "clock_control", + "renesas_rza2m_cpg": "clock_control", + "sifli_sf32lb_hxt48": "clock_control", + "sifli_sf32lb_rcc_clk": "clock_control", "silabs_series_clock": "clock_control", "silabs_si32_ahb": "clock_control", "silabs_si32_apb": "clock_control", "silabs_si32_pll": "clock_control", + "silabs_siwx91x_clock": "clock_control", "smartbond_clock": "clock_control", "st_stm32_clock_mco": "clock_control", "st_stm32_clock_mux": "clock_control", @@ -198,8 +270,15 @@ "wch_rcc": "clock_control", # # comparator + "ite_it51xxx_vcmp": "comparator", "nordic_nrf_comp": "comparator", "nordic_nrf_lpcomp": "comparator", + "nxp_cmp": "comparator", + "renesas_ra_acmphs": "comparator", + "renesas_ra_lvd": "comparator", + "renesas_rx_lvd": "comparator", + "silabs_acmp": "comparator", + "st_stm32_comp": "comparator", "zephyr_fake_comp": "comparator", # # coredump @@ -208,21 +287,27 @@ # counter "adi_max32_counter": "counter", "adi_max32_rtc_counter": "counter", + "adi_max32_wut": "counter", "ambiq_counter": "counter", "andestech_atcpit100": "counter", "arm_cmsdk_dtimer": "counter", "arm_cmsdk_timer": "counter", "atmel_sam0_tc32": "counter", "atmel_sam_tc": "counter", + "espressif_esp32_counter": "counter", "espressif_esp32_rtc_timer": "counter", - "espressif_esp32_timer": "counter", "gd_gd32_timer": "counter", "infineon_cat1_counter": "counter", + "infineon_tcpwm_counter": "counter", + "ite_it51xxx_counter": "counter", + "ite_it8xxx2_counter": "counter", "maxim_ds3231": "counter", "microchip_mcp7940n": "counter", "microchip_xec_timer": "counter", + "neorv32_gptmr": "counter", "nordic_nrf_rtc": "counter", "nordic_nrf_timer": "counter", + "nxp_ftm": "counter", "nxp_imx_epit": "counter", "nxp_imx_gpt": "counter", "nxp_imx_qtmr": "counter", @@ -231,37 +316,58 @@ "nxp_lpc_ctimer": "counter", "nxp_lpc_rtc": "counter", "nxp_lpc_rtc_highres": "counter", + "nxp_lpit": "counter", "nxp_mrt": "counter", "nxp_pit": "counter", "nxp_rtc": "counter", "nxp_s32_sys_timer": "counter", + "nxp_stm": "counter", "nxp_tpm_timer": "counter", "raspberrypi_pico_timer": "counter", + "realtek_rts5912_slwtimer": "counter", + "realtek_rts5912_timer": "counter", "renesas_ra_agt_counter": "counter", + "renesas_rz_cmtw_counter": "counter", + "renesas_rz_gtm_counter": "counter", "renesas_smartbond_timer": "counter", "silabs_gecko_rtcc": "counter", - "silabs_gecko_stimer": "counter", "snps_dw_timers": "counter", "st_stm32_counter": "counter", + "ti_cc23x0_lgpt": "counter", + "ti_cc23x0_rtc": "counter", + "ti_mspm0_timer_counter": "counter", "xlnx_xps_timer_1_00_a": "counter", "zephyr_native_posix_counter": "counter", + "zephyr_native_sim_counter": "counter", + # + # crc + "renesas_ra_crc": "crc", # # crypto "atmel_ataes132a": "crypto", + "espressif_esp32_aes": "crypto", + "espressif_esp32_sha": "crypto", "intel_adsp_sha": "crypto", + "ite_it51xxx_sha": "crypto", "ite_it8xxx2_sha": "crypto", "ite_it8xxx2_sha_v2": "crypto", "microchip_xec_symcr": "crypto", "nordic_nrf_ecb": "crypto", "nuvoton_npcx_sha": "crypto", "nxp_mcux_dcp": "crypto", + "realtek_rts5912_sha": "crypto", "renesas_smartbond_crypto": "crypto", "silabs_si32_aes": "crypto", "st_stm32_aes": "crypto", "st_stm32_cryp": "crypto", + "st_stm32_hash": "crypto", + "ti_cc23x0_aes": "crypto", # # dac "adi_ad559x_dac": "dac", + "adi_ad5601": "dac", + "adi_ad5611": "dac", + "adi_ad5621": "dac", "adi_ad5628": "dac", "adi_ad5648": "dac", "adi_ad5668": "dac", @@ -279,15 +385,20 @@ "adi_max22017_dac": "dac", "atmel_sam0_dac": "dac", "atmel_sam_dac": "dac", + "atmel_samd5x_dac": "dac", "espressif_esp32_dac": "dac", "gd_gd32_dac": "dac", "microchip_mcp4725": "dac", "microchip_mcp4728": "dac", + "nxp_dac12": "dac", "nxp_gau_dac": "dac", "nxp_kinetis_dac": "dac", "nxp_kinetis_dac32": "dac", "nxp_lpdac": "dac", + "renesas_ra_dac": "dac", + "silabs_vdac": "dac", "st_stm32_dac": "dac", + "ti_dac161s997": "dac", "ti_dacx0501": "dac", "vnd_dac": "dac", # @@ -303,9 +414,16 @@ # dai/intel/ssp "intel_ssp_dai": "dai/intel/ssp", # + # dai/nxp/micfil + "nxp_dai_micfil": "dai/nxp/micfil", + # # dai/nxp/sai "nxp_dai_sai": "dai/nxp/sai", # + # debug + "nordic_coresight_nrf": "debug", + "silabs_pti": "debug", + # # disk "st_stm32_sdmmc": "disk", "zephyr_flash_disk": "disk", @@ -317,36 +435,45 @@ "nvme_controller": "disk/nvme", # # display + "chipone_co5300": "display", "frida_nt35510": "display", "galaxycore_gc9x01x": "display", + "himax_hx8379c": "display", "himax_hx8394": "display", "ilitek_ili9806e_dsi": "display", "intel_multiboot_framebuffer": "display", "istech_ist3931": "display", + "jdi_lpm013m126": "display", "led_strip_matrix": "display", "maxim_max7219": "display", "nxp_dcnano_lcdif": "display", "nxp_imx_elcdif": "display", + "nxp_imx_lcdifv3": "display", "orisetech_otm8009a": "display", "raydium_rm67162": "display", "raydium_rm68200": "display", "renesas_ra_glcdc": "display", "renesas_smartbond_display": "display", "sharp_ls0xx": "display", + "sitronix_st75256": "display", + "sitronix_st7701": "display", "sitronix_st7735r": "display", "sitronix_st7789v": "display", "sitronix_st7796s": "display", "solomon_ssd1322": "display", "st_stm32_ltdc": "display", + "waveshare_7inch_dsi_lcd_c": "display", "zephyr_dummy_dc": "display", + "zephyr_hub12": "display", "zephyr_sdl_dc": "display", # # dma "adi_max32_dma": "dma", "altr_msgdma": "dma", - "andestech_atcdmac300": "dma", + "andestech_atcdmacx00": "dma", "atmel_sam0_dmac": "dma", "atmel_sam_xdmac": "dma", + "bflb_dma": "dma", "brcm_iproc_pax_dma_v1": "dma", "brcm_iproc_pax_dma_v2": "dma", "espressif_esp32_gdma": "dma", @@ -362,6 +489,7 @@ "intel_lpss": "dma", "intel_sedi_dma": "dma", "microchip_xec_dmac": "dma", + "nuvoton_npcx_gdma": "dma", "nxp_lpc_dma": "dma", "nxp_mcux_edma": "dma", "nxp_pxp": "dma", @@ -369,9 +497,15 @@ "nxp_smartdma": "dma", "nxp_sof_host_dma": "dma", "raspberrypi_pico_dma": "dma", + "renesas_ra_dma": "dma", + "renesas_rz_dmac": "dma", + "renesas_rz_dmac_b": "dma", "renesas_smartbond_dma": "dma", + "sifli_sf32lb_dmac": "dma", + "silabs_gpdma": "dma", "silabs_ldma": "dma", "silabs_si32_dma": "dma", + "silabs_siwx91x_dma": "dma", "snps_designware_dma": "dma", "snps_designware_dma_axi": "dma", "st_stm32_bdma": "dma", @@ -380,6 +514,8 @@ "st_stm32_dma_v2bis": "dma", "st_stm32_dmamux": "dma", "st_stm32u5_dma": "dma", + "ti_cc23x0_dma": "dma", + "wch_wch_dma": "dma", "xlnx_axi_dma_1_00_a": "dma", "xlnx_eth_dma": "dma", "zephyr_dma_emul": "dma", @@ -389,40 +525,50 @@ # # edac "intel_ibecc": "edac", + "xlnx_zynqmp_ddrc_2_40a": "edac", # # eeprom "atmel_at24": "eeprom", "fujitsu_mb85rcxx": "eeprom", "fujitsu_mb85rsxx": "eeprom", + "infineon_fm25xxx": "eeprom", "microchip_xec_eeprom": "eeprom", "nxp_lpc11u6x_eeprom": "eeprom", "st_stm32_eeprom": "eeprom", - "ti_tmp116_eeprom": "eeprom", + "ti_tmp11x_eeprom": "eeprom", "zephyr_emu_eeprom": "eeprom", "zephyr_fake_eeprom": "eeprom", "zephyr_sim_eeprom": "eeprom", # # entropy "adi_max32_trng": "entropy", + "adi_maxq10xx_trng": "entropy", + "ambiq_puf_trng": "entropy", "atmel_sam_trng": "entropy", + "brcm_iproc_rng200": "entropy", "espressif_esp32_trng": "entropy", "litex_prbs": "entropy", "neorv32_trng": "entropy", + "nordic_nrf_cracen_ctrdrbg": "entropy", "nordic_nrf_rng": "entropy", "nuvoton_npcx_drbg": "entropy", + "nxp_ele_trng": "entropy", "nxp_imx_caam": "entropy", "nxp_kinetis_rnga": "entropy", "nxp_kinetis_trng": "entropy", "nxp_lpc_rng": "entropy", "openisa_rv32m1_trng": "entropy", "renesas_smartbond_trng": "entropy", + "sensry_sy1xx_trng": "entropy", "silabs_gecko_semailbox": "entropy", "silabs_gecko_trng": "entropy", - "st_stm32_rng": "entropy", + "silabs_siwx91x_rng": "entropy", "telink_b91_trng": "entropy", "ti_cc13xx_cc26xx_trng": "entropy", + "virtio_device4": "entropy", "zephyr_bt_hci_entropy": "entropy", "zephyr_native_posix_rng": "entropy", + "zephyr_native_sim_rng": "entropy", "zephyr_psa_crypto_rng": "entropy", # # espi @@ -435,6 +581,7 @@ "nuvoton_npcx_espi": "espi", "nuvoton_npcx_espi_taf": "espi", "nuvoton_npcx_host_sub": "espi", + "realtek_rts5912_espi": "espi", "zephyr_espi_emul_controller": "espi", # # ethernet @@ -448,26 +595,36 @@ "litex_liteeth": "ethernet", "microchip_enc28j60": "ethernet", "microchip_enc424j600": "ethernet", - "microchip_ksz8794": "ethernet", - "microchip_ksz8863": "ethernet", "microchip_lan865x": "ethernet", "microchip_lan9250": "ethernet", "nuvoton_numaker_ethernet": "ethernet", - "nxp_imx_netc_psi": "ethernet", + "nxp_enet": "ethernet", + "nxp_enet1g": "ethernet", + "nxp_enet_mac": "ethernet", "nxp_s32_gmac": "ethernet", "nxp_s32_netc_psi": "ethernet", "nxp_s32_netc_vsi": "ethernet", "renesas_ra_ethernet": "ethernet", + "sensry_sy1xx_mac": "ethernet", "siemens_ivshmem_eth": "ethernet", "silabs_gecko_ethernet": "ethernet", "smsc_lan91c111": "ethernet", + "smsc_lan91c111_mdio": "ethernet", "smsc_lan9220": "ethernet", "snps_designware_ethernet": "ethernet", "snps_ethernet_cyclonev": "ethernet", "st_stm32_ethernet": "ethernet", "ti_stellaris_ethernet": "ethernet", + "virtio_net": "ethernet", "vnd_ethernet": "ethernet", "wiznet_w5500": "ethernet", + "xlnx_axi_ethernet_1_00_a": "ethernet", + # + # ethernet/dsa + "microchip_ksz8463": "ethernet/dsa", + "microchip_ksz8794": "ethernet/dsa", + "microchip_ksz8863": "ethernet/dsa", + "nxp_netc_switch": "ethernet/dsa", # # ethernet/dwc_xgmac "snps_dwcxgmac": "ethernet/dwc_xgmac", @@ -476,11 +633,13 @@ "nxp_enet_qos": "ethernet/eth_nxp_enet_qos", "nxp_enet_qos_mac": "ethernet/eth_nxp_enet_qos", # - # ethernet/nxp_enet - "nxp_enet": "ethernet/nxp_enet", - "nxp_enet1g": "ethernet/nxp_enet", - "nxp_enet_mac": "ethernet/nxp_enet", - "nxp_kinetis_ethernet": "ethernet/nxp_enet", + # ethernet/intel + "intel_eth_plat": "ethernet/intel", + "intel_igc_mac": "ethernet/intel", + # + # ethernet/nxp_imx_netc + "nxp_imx_netc_blk_ctrl": "ethernet/nxp_imx_netc", + "nxp_imx_netc_psi": "ethernet/nxp_imx_netc", # # ethernet/phy "adi_adin1100_phy": "ethernet/phy", @@ -488,21 +647,29 @@ "davicom_dm8806_phy": "ethernet/phy", "ethernet_phy": "ethernet/phy", "microchip_ksz8081": "ethernet/phy", + "microchip_ksz9131": "ethernet/phy", "microchip_t1s_phy": "ethernet/phy", "microchip_vsc8541": "ethernet/phy", "nxp_tja1103": "ethernet/phy", + "nxp_tja11xx": "ethernet/phy", "qca_ar8031": "ethernet/phy", "realtek_rtl8211f": "ethernet/phy", "ti_dp83825": "ethernet/phy", + "ti_dp83867": "ethernet/phy", # # firmware/scmi "arm_scmi_shmem": "firmware/scmi", # + # firmware/tisci + "ti_k2g_sci": "firmware/tisci", + # # flash "adi_max32_flash_controller": "flash", - "altr_nios2_qspi_nor": "flash", + "adi_max32_spixf_nor": "flash", "ambiq_flash_controller": "flash", "andestech_qspi_nor": "flash", + "andestech_qspi_nor_xip": "flash", + "atmel_at25xv021a": "flash", "atmel_at45": "flash", "atmel_sam0_nvmctrl": "flash", "atmel_sam_flash_controller": "flash", @@ -513,14 +680,19 @@ "infineon_cat1_flash_controller": "flash", "infineon_cat1_qspi_flash": "flash", "infineon_xmc4xxx_flash_controller": "flash", + "ite_it51xxx_manual_flash_1k": "flash", "ite_it8xxx2_flash_controller": "flash", + "jedec_mspi_nor": "flash", "jedec_spi_nor": "flash", + "microchip_nvmctrl_g1_flash": "flash", "mspi_atxp032": "flash", + "mspi_is25xx0xx": "flash", "nordic_mram": "flash", "nordic_nrf51_flash_controller": "flash", "nordic_nrf52_flash_controller": "flash", "nordic_nrf53_flash_controller": "flash", "nordic_nrf91_flash_controller": "flash", + "nordic_nrf_mramc": "flash", "nordic_qspi_nor": "flash", "nordic_rram_controller": "flash", "nuvoton_npcx_fiu_nor": "flash", @@ -538,15 +710,25 @@ "nxp_kinetis_ftfe": "flash", "nxp_kinetis_ftfl": "flash", "nxp_msf1": "flash", + "nxp_s32_qspi_hyperflash": "flash", "nxp_s32_qspi_nor": "flash", + "nxp_xspi_nor": "flash", "openisa_rv32m1_ftfe": "flash", "raspberrypi_pico_flash_controller": "flash", + "realtek_rts5912_flash_controller": "flash", "renesas_ra_flash_hp_controller": "flash", + "renesas_ra_mram_controller": "flash", "renesas_ra_ospi_b_nor": "flash", "renesas_ra_qspi_nor": "flash", + "renesas_rx_flash": "flash", + "renesas_rz_qspi_spibsc": "flash", + "renesas_rz_qspi_xspi": "flash", "renesas_smartbond_flash_controller": "flash", + "sifli_sf32lb_mpi_qspi_nor": "flash", "silabs_gecko_flash_controller": "flash", + "silabs_series2_flash_controller": "flash", "silabs_si32_flash_controller": "flash", + "silabs_siwx91x_flash_controller": "flash", "st_stm32_flash_controller": "flash", "st_stm32_ospi_nor": "flash", "st_stm32_qspi_nor": "flash", @@ -556,6 +738,7 @@ "st_stm32wba_flash_controller": "flash", "telink_b91_flash_controller": "flash", "ti_cc13xx_cc26xx_flash_controller": "flash", + "ti_cc23x0_flash_controller": "flash", "zephyr_mspi_emul_flash": "flash", "zephyr_sim_flash": "flash", # @@ -568,12 +751,24 @@ "renesas_slg47115": "fpga", "xlnx_fpga": "fpga", # + # fuel_gauge/axp2101 + "x_powers_axp2101_fuel_gauge": "fuel_gauge/axp2101", + # # fuel_gauge/bq27z746 "ti_bq27z746": "fuel_gauge/bq27z746", # + # fuel_gauge/bq40z50 + "ti_bq40z50": "fuel_gauge/bq40z50", + # # fuel_gauge/composite "zephyr_fuel_gauge_composite": "fuel_gauge/composite", # + # fuel_gauge/lc709203f + "onnn_lc709203f": "fuel_gauge/lc709203f", + # + # fuel_gauge/ltc2959 + "adi_ltc2959": "fuel_gauge/ltc2959", + # # fuel_gauge/max17048 "maxim_max17048": "fuel_gauge/max17048", # @@ -581,12 +776,16 @@ "sbs_sbs_gauge": "fuel_gauge/sbs_gauge", "sbs_sbs_gauge_new_api": "fuel_gauge/sbs_gauge", # + # fuel_gauge/sy24561 + "silergy_sy24561": "fuel_gauge/sy24561", + # # gnss "gnss_nmea_generic": "gnss", "luatos_air530z": "gnss", "quectel_lc26g": "gnss", "quectel_lc76g": "gnss", "quectel_lc86g": "gnss", + "u_blox_f9p": "gnss", "u_blox_m8": "gnss", "zephyr_gnss_emul": "gnss", # @@ -594,26 +793,35 @@ "adi_ad559x_gpio": "gpio", "adi_adp5585_gpio": "gpio", "adi_max14906_gpio": "gpio", + "adi_max14915_gpio": "gpio", "adi_max14916_gpio": "gpio", + "adi_max14917_gpio": "gpio", "adi_max22017_gpio": "gpio", "adi_max22190_gpio": "gpio", + "adi_max22199_gpio": "gpio", "adi_max32_gpio": "gpio", + "aesc_gpio": "gpio", "altr_pio_1_0": "gpio", "ambiq_gpio_bank": "gpio", "andestech_atcgpio100": "gpio", "arm_cmsdk_gpio": "gpio", + "arm_mmio32_gpio": "gpio", "atmel_sam0_gpio": "gpio", "atmel_sam4l_gpio": "gpio", "atmel_sam_gpio": "gpio", "awinic_aw9523b_gpio": "gpio", + "bflb_bl60x_70x_gpio": "gpio", + "bflb_bl61x_gpio": "gpio", "brcm_bcm2711_gpio": "gpio", "brcm_brcmstb_gpio": "gpio", "brcm_iproc_gpio": "gpio", "cypress_cy8c95xx_gpio_port": "gpio", "cypress_psoc6_gpio": "gpio", "efinix_sapphire_gpio": "gpio", + "ene_kb106x_gpio": "gpio", "ene_kb1200_gpio": "gpio", "espressif_esp32_gpio": "gpio", + "espressif_esp32_lpgpio": "gpio", "fcs_fxl6408": "gpio", "gaisler_grgpio": "gpio", "gd_gd32_gpio": "gpio", @@ -622,6 +830,7 @@ "infineon_xmc4xxx_gpio": "gpio", "intel_gpio": "gpio", "intel_sedi_gpio": "gpio", + "ite_it51xxx_gpio": "gpio", "ite_it8801_gpio": "gpio", "ite_it8xxx2_gpio": "gpio", "ite_it8xxx2_gpio_v2": "gpio", @@ -638,10 +847,13 @@ "microchip_mcp23s18": "gpio", "microchip_mec5_gpio": "gpio", "microchip_mpfs_gpio": "gpio", + "microchip_port_g1_gpio": "gpio", + "microchip_sam_pio4": "gpio", "microchip_xec_gpio": "gpio", "microchip_xec_gpio_v2": "gpio", "neorv32_gpio": "gpio", "nordic_npm1300_gpio": "gpio", + "nordic_npm1304_gpio": "gpio", "nordic_npm2100_gpio": "gpio", "nordic_npm6001_gpio": "gpio", "nordic_nrf_gpio": "gpio", @@ -656,27 +868,35 @@ "nxp_kinetis_gpio": "gpio", "nxp_lpc11u6x_gpio": "gpio", "nxp_lpc_gpio_port": "gpio", + "nxp_pca6408": "gpio", + "nxp_pca6416": "gpio", "nxp_pca9538": "gpio", "nxp_pca9539": "gpio", "nxp_pca9554": "gpio", "nxp_pca9555": "gpio", "nxp_pca95xx": "gpio", + "nxp_pcal6408": "gpio", "nxp_pcal6408a": "gpio", + "nxp_pcal6416": "gpio", "nxp_pcal6416a": "gpio", "nxp_pcal6524": "gpio", "nxp_pcal6534": "gpio", + "nxp_pcal9538": "gpio", + "nxp_pcal9539": "gpio", + "nxp_pcal9722": "gpio", "nxp_pcf857x": "gpio", - "nxp_s32_gpio": "gpio", "nxp_sc18im704_gpio": "gpio", + "nxp_siul2_gpio": "gpio", "openisa_rv32m1_gpio": "gpio", "quicklogic_eos_s3_gpio": "gpio", - "raspberrypi_pico_gpio": "gpio", + "raspberrypi_pico_gpio_port": "gpio", "raspberrypi_rp1_gpio": "gpio", "realtek_rts5912_gpio": "gpio", - "renesas_ra_gpio": "gpio", "renesas_ra_gpio_ioport": "gpio", "renesas_rcar_gpio": "gpio", + "renesas_rx_gpio": "gpio", "renesas_rz_gpio": "gpio", + "renesas_rza2m_gpio": "gpio", "renesas_rzt2m_gpio": "gpio", "renesas_smartbond_gpio": "gpio", "richtek_rt1718s": "gpio", @@ -685,18 +905,25 @@ "semtech_sx1509b": "gpio", "sensry_sy1xx_gpio": "gpio", "sifive_gpio0": "gpio", + "sifli_sf32lb_gpio": "gpio", "silabs_gecko_gpio_port": "gpio", + "silabs_gpio": "gpio", "silabs_si32_gpio": "gpio", + "silabs_siwx91x_gpio": "gpio", + "silabs_siwx91x_gpio_uulp": "gpio", "snps_creg_gpio": "gpio", "snps_designware_gpio": "gpio", + "st_mfxstm32l152": "gpio", "st_stm32_gpio": "gpio", "st_stmpe1600": "gpio", "telink_b91_gpio": "gpio", - "ti_ads114s0x_gpio": "gpio", + "ti_ads1x4s0x_gpio": "gpio", "ti_cc13xx_cc26xx_gpio": "gpio", + "ti_cc23x0_gpio": "gpio", "ti_cc32xx_gpio": "gpio", "ti_davinci_gpio": "gpio", "ti_lmp90xxx_gpio": "gpio", + "ti_mspm0_gpio": "gpio", "ti_sn74hc595": "gpio", "ti_stellaris_gpio": "gpio", "ti_tca6424a": "gpio", @@ -715,6 +942,7 @@ # # hdlc_rcp_if "nxp_hdlc_rcp_if": "hdlc_rcp_if", + "spi_hdlc_rcp_if": "hdlc_rcp_if", "uart_hdlc_rcp_if": "hdlc_rcp_if", # # hwinfo @@ -741,6 +969,7 @@ "atmel_sam_i2c_twihs": "i2c", "atmel_sam_i2c_twim": "i2c", "brcm_iproc_i2c": "i2c", + "cdns_i2c": "i2c", "ene_kb1200_i2c": "i2c", "espressif_esp32_i2c": "i2c", "fsl_imx21_i2c": "i2c", @@ -748,11 +977,14 @@ "gpio_i2c": "i2c", "gpio_i2c_switch": "i2c", "infineon_cat1_i2c": "i2c", + "infineon_cat1_i2c_pdl": "i2c", "infineon_xmc4xxx_i2c": "i2c", "intel_sedi_i2c": "i2c", "ite_enhance_i2c": "i2c", + "ite_it51xxx_i2c": "i2c", "ite_it8xxx2_i2c": "i2c", "litex_i2c": "i2c", + "litex_litei2c": "i2c", "microchip_mpfs_i2c": "i2c", "microchip_xec_i2c": "i2c", "microchip_xec_i2c_v2": "i2c", @@ -760,27 +992,38 @@ "nuvoton_npcx_i2c_ctrl": "i2c", "nuvoton_npcx_i2c_port": "i2c", "nuvoton_numaker_i2c": "i2c", + "nxp_ii2c": "i2c", "nxp_kinetis_i2c": "i2c", "nxp_lpc11u6x_i2c": "i2c", "nxp_lpc_i2c": "i2c", "nxp_lpi2c": "i2c", "nxp_sc18im704_i2c": "i2c", "openisa_rv32m1_lpi2c": "i2c", + "realtek_rts5912_i2c": "i2c", + "renesas_ra_i2c_sci": "i2c", + "renesas_ra_i2c_sci_b": "i2c", "renesas_ra_iic": "i2c", "renesas_rcar_i2c": "i2c", + "renesas_rx_i2c": "i2c", + "renesas_rz_iic": "i2c", + "renesas_rz_riic": "i2c", "renesas_smartbond_i2c": "i2c", + "sensry_sy1xx_i2c": "i2c", "sifive_i2c0": "i2c", "silabs_gecko_i2c": "i2c", + "silabs_i2c": "i2c", "st_stm32_i2c_v1": "i2c", "st_stm32_i2c_v2": "i2c", "telink_b91_i2c": "i2c", "ti_cc13xx_cc26xx_i2c": "i2c", + "ti_cc23x0_i2c": "i2c", "ti_cc32xx_i2c": "i2c", "ti_omap_i2c": "i2c", "ti_tca9544a": "i2c", "ti_tca9546a": "i2c", "ti_tca9548a": "i2c", "vnd_i2c": "i2c", + "wch_i2c": "i2c", "xlnx_xps_iic_2_00_a": "i2c", "xlnx_xps_iic_2_1": "i2c", "zephyr_i2c_emul_controller": "i2c", @@ -789,26 +1032,38 @@ "zephyr_i2c_target_eeprom": "i2c/target", # # i2s + "ambiq_i2s": "i2s", "atmel_sam_ssc": "i2s", "espressif_esp32_i2s": "i2s", "nxp_lpc_i2s": "i2s", "nxp_mcux_i2s": "i2s", + "renesas_ra_i2s_ssie": "i2s", + "silabs_siwx91x_i2s": "i2s", "st_stm32_i2s": "i2s", + "st_stm32_sai": "i2s", "vnd_i2s": "i2s", # # i3c + "adi_max32_i3c": "i3c", "cdns_i3c": "i3c", + "ite_it51xxx_i3cm": "i3c", + "ite_it51xxx_i3cs": "i3c", "nuvoton_npcx_i3c": "i3c", "nxp_mcux_i3c": "i3c", + "renesas_ra_i3c": "i3c", + "snps_designware_i3c": "i3c", "st_stm32_i3c": "i3c", "vnd_i3c": "i3c", # # ieee802154 "atmel_rf2xx": "ieee802154", "decawave_dw1000": "ieee802154", + "espressif_esp32_ieee802154": "ieee802154", "nordic_nrf_ieee802154": "ieee802154", "nxp_kw41z_ieee802154": "ieee802154", "nxp_mcr20a": "ieee802154", + "nxp_mcxw_ieee802154": "ieee802154", + "st_stm32wba_ieee802154": "ieee802154", "telink_b91_zb": "ieee802154", "ti_cc1200": "ieee802154", "ti_cc13xx_cc26xx_ieee802154": "ieee802154", @@ -819,8 +1074,11 @@ # input "adc_keys": "input", "analog_axis": "input", + "arduino_modulino_buttons": "input", + "chipsemi_chsc5x": "input", "chipsemi_chsc6x": "input", "cirque_pinnacle": "input", + "cypress_cy8cmbr3xxx": "input", "espressif_esp32_touch": "input", "focaltech_ft5336": "input", "futaba_sbus": "input", @@ -830,17 +1088,27 @@ "gpio_qdec": "input", "hynitron_cst816s": "input", "ilitek_ili2132a": "input", + "ite_it51xxx_kbd": "input", "ite_it8801_kbd": "input", "ite_it8xxx2_kbd": "input", "microchip_cap12xx": "input", "microchip_xec_kbd": "input", "nintendo_nunchuk": "input", "nuvoton_npcx_kbd": "input", + "nxp_mcux_kpp": "input", "pixart_pat912x": "input", "pixart_paw32xx": "input", "pixart_pmw3610": "input", + "realtek_rts5912_kbd": "input", + "renesas_ra_ctsu": "input", + "renesas_ra_ctsu_button": "input", + "renesas_ra_ctsu_slider": "input", + "renesas_ra_ctsu_wheel": "input", + "renesas_rx_ctsu": "input", "sitronix_cf1133": "input", + "st_stm32_tsc": "input", "st_stmpe811": "input", + "vishay_vs1838b": "input", "xptek_xpt2046": "input", "zephyr_input_sdl_touch": "input", "zephyr_native_linux_evdev": "input", @@ -853,12 +1121,14 @@ "atmel_sam0_eic": "interrupt_controller", "gaisler_irqmp": "interrupt_controller", "gd_gd32_exti": "interrupt_controller", + "hazard3_hazard3_intc": "interrupt_controller", "infineon_xmc4xxx_intc": "interrupt_controller", "intel_ace_intc": "interrupt_controller", "intel_cavs_intc": "interrupt_controller", "intel_ioapic": "interrupt_controller", "intel_loapic": "interrupt_controller", "intel_vt_d": "interrupt_controller", + "ite_it51xxx_wuc": "interrupt_controller", "ite_it8xxx2_wuc": "interrupt_controller", "litex_vexriscv_intc0": "interrupt_controller", "mediatek_adsp_intc": "interrupt_controller", @@ -867,10 +1137,12 @@ "nuvoton_npcx_miwu": "interrupt_controller", "nxp_irqsteer_intc": "interrupt_controller", "nxp_pint": "interrupt_controller", - "nxp_s32_siul2_eirq": "interrupt_controller", "nxp_s32_wkpu": "interrupt_controller", + "nxp_siul2_eirq": "interrupt_controller", "openisa_rv32m1_intmux": "interrupt_controller", - "renesas_ra_interrupt_controller_unit": "interrupt_controller", + "renesas_rx_icu": "interrupt_controller", + "renesas_rz_ext_irq": "interrupt_controller", + "riscv_clic": "interrupt_controller", "shared_irq": "interrupt_controller", "sifive_plic_1_0_0": "interrupt_controller", "snps_arcv2_intc": "interrupt_controller", @@ -878,6 +1150,7 @@ "st_stm32wb0_gpio_intc": "interrupt_controller", "swerv_pic": "interrupt_controller", "ti_vim": "interrupt_controller", + "wch_exti": "interrupt_controller", "wch_pfic": "interrupt_controller", # # ipm @@ -893,17 +1166,19 @@ "xlnx_zynqmp_ipi_mailbox": "ipm", "zephyr_mbox_ipm": "ipm", # - # kscan - "zephyr_kscan_input": "kscan", - # # led + "arduino_modulino_buttons_leds": "led", + "dac_leds": "led", "gpio_leds": "led", "holtek_ht16k33": "led", "issi_is31fl3194": "led", "issi_is31fl3216a": "led", "issi_is31fl3733": "led", + "leds_group_multicolor": "led", "microchip_xec_bbled": "led", "nordic_npm1300_led": "led", + "nordic_npm1304_led": "led", + "nxp_pca9533": "led", "nxp_pca9633": "led", "onnn_ncp5623": "led", "pwm_leds": "led", @@ -920,6 +1195,7 @@ # # led_strip "apa_apa102": "led_strip", + "arduino_modulino_pixels": "led_strip", "greeled_lpd8803": "led_strip", "greeled_lpd8806": "led_strip", "ti_tlc5971": "led_strip", @@ -928,14 +1204,18 @@ "worldsemi_ws2812_i2s": "led_strip", "worldsemi_ws2812_rpi_pico_pio": "led_strip", "worldsemi_ws2812_spi": "led_strip", + "worldsemi_ws2812_uart": "led_strip", # # lora "reyax_rylrxxx": "lora", - "semtech_sx1272": "lora", - "semtech_sx1276": "lora", + # + # lora/loramac_node + "semtech_sx1272": "lora/loramac_node", + "semtech_sx1276": "lora/loramac_node", # # mbox "andestech_mbox_plic_sw": "mbox", + "arm_mhuv3": "mbox", "espressif_mbox_esp32": "mbox", "linaro_ivshmem_mbox": "mbox", "nordic_mbox_nrf_ipc": "mbox", @@ -948,13 +1228,18 @@ "nxp_mbox_imx_mu": "mbox", "nxp_mbox_mailbox": "mbox", "nxp_s32_mru": "mbox", + "renesas_ra_ipc_mbox": "mbox", + "renesas_rz_mhu_mbox": "mbox", "st_mbox_stm32_hsem": "mbox", + "ti_omap_mailbox": "mbox", + "ti_secure_proxy": "mbox", # # mdio "adi_adin2111_mdio": "mdio", "atmel_sam_mdio": "mdio", "espressif_esp32_mdio": "mdio", "infineon_xmc4xxx_mdio": "mdio", + "intel_igc_mdio": "mdio", "litex_liteeth_mdio": "mdio", "microchip_lan865x_mdio": "mdio", "nxp_enet_mdio": "mdio", @@ -963,30 +1248,40 @@ "nxp_s32_gmac_mdio": "mdio", "nxp_s32_netc_emdio": "mdio", "renesas_ra_mdio": "mdio", - "smsc_lan91c111_mdio": "mdio", + "sensry_sy1xx_mdio": "mdio", "snps_dwcxgmac_mdio": "mdio", "st_stm32_mdio": "mdio", + "xlnx_axi_ethernet_1_00_a_mdio": "mdio", "zephyr_mdio_gpio": "mdio", # # memc + "adi_max32_hpb": "memc", "atmel_sam_smc": "memc", + "bflb_bl61x_psram": "memc", "mspi_aps6404l": "memc", + "mspi_aps_z8": "memc", "nxp_imx_flexspi": "memc", "nxp_imx_flexspi_s27ks0641": "memc", "nxp_imx_flexspi_w956a8mbya": "memc", "nxp_s32_qspi": "memc", + "nxp_xspi": "memc", + "nxp_xspi_psram": "memc", "renesas_ra_sdram": "memc", "renesas_smartbond_nor_psram": "memc", "sifive_fu740_c000_ddr": "memc", + "silabs_siwx91x_qspi_memory": "memc", "st_stm32_fmc": "memc", "st_stm32_fmc_nor_psram": "memc", "st_stm32_fmc_sdram": "memc", + "st_stm32_ospi_psram": "memc", + "st_stm32_xspi_psram": "memc", "st_stm32h7_fmc": "memc", # # mfd "adi_ad559x": "mfd", "adi_adp5585": "mfd", "adi_max22017": "mfd", + "adi_maxq10xx": "mfd", "awinic_aw9523b": "mfd", "infineon_tle9104": "mfd", "ite_it8801_altctrl": "mfd", @@ -994,16 +1289,21 @@ "maxim_ds3231_mfd": "mfd", "maxim_max20335": "mfd", "maxim_max31790": "mfd", + "microchip_sam_flexcom": "mfd", + "motorola_mc146818_mfd": "mfd", "nordic_npm1300": "mfd", + "nordic_npm1304": "mfd", "nordic_npm2100": "mfd", "nordic_npm6001": "mfd", "nuvoton_nct38xx": "mfd", "nxp_lp_flexcomm": "mfd", + "nxp_pca9422": "mfd", + "nxp_pf1550": "mfd", "rohm_bd8lb600fs": "mfd", - "x_powers_axp192": "mfd", # # mipi_dbi "nxp_lcdic": "mipi_dbi", + "nxp_mipi_dbi_dcnano_lcdif": "mipi_dbi", "nxp_mipi_dbi_flexio_lcdif": "mipi_dbi", "renesas_smartbond_mipi_dbi": "mipi_dbi", "st_stm32_fmc_mipi_dbi": "mipi_dbi", @@ -1013,6 +1313,7 @@ # mipi_dsi "nxp_imx_mipi_dsi": "mipi_dsi", "nxp_mipi_dsi_2l": "mipi_dsi", + "nxp_mipi_dsi_dwc": "mipi_dsi", "renesas_ra_mipi_dsi": "mipi_dsi", "st_stm32_mipi_dsi": "mipi_dsi", "vnd_mipi_dsi": "mipi_dsi", @@ -1022,6 +1323,8 @@ # # misc/ethos_u "arm_ethos_u": "misc/ethos_u", + "nuvoton_numaker_npu": "misc/ethos_u", + "renesas_ra_npu": "misc/ethos_u", # # misc/ft8xx "ftdi_ft800": "misc/ft8xx", @@ -1029,12 +1332,22 @@ # misc/grove_lcd_rgb "seeed_grove_lcd_rgb": "misc/grove_lcd_rgb", # + # misc/interconn/renesas_elc + "renesas_ra_elc": "misc/interconn/renesas_elc", + # # misc/mcux_flexio "nxp_flexio": "misc/mcux_flexio", # # misc/nordic_vpr_launcher "nordic_nrf_vpr_coprocessor": "misc/nordic_vpr_launcher", # + # misc/nxp_imx93_mediamix + "nxp_imx93_mediamix": "misc/nxp_imx93_mediamix", + # + # misc/nxp_rtxxx_dsp_ctrl + "nxp_rt600_dsp_ctrl": "misc/nxp_rtxxx_dsp_ctrl", + "nxp_rt700_dsp_ctrl_hifi4": "misc/nxp_rtxxx_dsp_ctrl", + # # misc/nxp_s32_emios "nxp_s32_emios": "misc/nxp_s32_emios", # @@ -1044,6 +1357,15 @@ # misc/renesas_ra_external_interrupt "renesas_ra_external_interrupt": "misc/renesas_ra_external_interrupt", # + # misc/renesas_rx_dtc + "renesas_rx_dtc": "misc/renesas_rx_dtc", + # + # misc/renesas_rx_external_interrupt + "renesas_rx_external_interrupt": "misc/renesas_rx_external_interrupt", + # + # misc/stm32n6_axisram + "st_stm32n6_ramcfg": "misc/stm32n6_axisram", + # # misc/timeaware_gpio "intel_timeaware_gpio": "misc/timeaware_gpio", # @@ -1053,11 +1375,12 @@ # modem "nordic_nrf91_slm": "modem", "quectel_bg95": "modem", + "quectel_bg96": "modem", "quectel_bg9x": "modem", "quectel_eg25_g": "modem", - "simcom_sim7080": "modem", + "quectel_eg800q": "modem", + "simcom_a76xx": "modem", "sqn_gm02s": "modem", - "swir_hl7800": "modem", "telit_me310g1": "modem", "telit_me910g1": "modem", "u_blox_lara_r6": "modem", @@ -1065,10 +1388,24 @@ "u_blox_sara_r5": "modem", "wnc_m14a2a": "modem", # + # modem/hl78xx + "swir_hl7800": "modem/hl78xx", + "swir_hl7800_offload": "modem/hl78xx", + "swir_hl7812": "modem/hl78xx", + "swir_hl7812_offload": "modem/hl78xx", + # + # modem/simcom/sim7080 + "simcom_sim7080": "modem/simcom/sim7080", + # # mspi "ambiq_mspi_controller": "mspi", + "snps_designware_ssi": "mspi", "zephyr_mspi_emul_controller": "mspi", # + # opamp + "nxp_opamp": "opamp", + "nxp_opamp_fast": "opamp", + # # pcie/controller "brcm_brcmstb_pcie": "pcie/controller", # @@ -1086,6 +1423,7 @@ "nuvoton_npcx_peci": "peci", # # pinctrl + "ene_kb106x_pinctrl": "pinctrl", "ene_kb1200_pinctrl": "pinctrl", "infineon_xmc4xxx_pinctrl": "pinctrl", "ite_it8xxx2_pinctrl_func": "pinctrl", @@ -1099,12 +1437,19 @@ "realtek_rts5912_pinctrl": "pinctrl", "sensry_sy1xx_pinctrl": "pinctrl", "sifive_pinctrl": "pinctrl", + "sifli_sf32lb52x_pinmux": "pinctrl", "silabs_dbus_pinctrl": "pinctrl", + "silabs_siwx91x_pinctrl": "pinctrl", "snps_emsdp_pinctrl": "pinctrl", "telink_b91_pinctrl": "pinctrl", "ti_cc13xx_cc26xx_pinctrl": "pinctrl", + "ti_cc23x0_pinctrl": "pinctrl", "ti_cc32xx_pinctrl": "pinctrl", "ti_k3_pinctrl": "pinctrl", + "ti_mspm0_pinctrl": "pinctrl", + "wch_00x_afio": "pinctrl", + "wch_20x_30x_afio": "pinctrl", + "wch_afio": "pinctrl", "xlnx_pinctrl_zynq": "pinctrl", "xlnx_pinctrl_zynqmp": "pinctrl", # @@ -1112,6 +1457,7 @@ "renesas_rcar_pfc": "pinctrl/renesas/rcar", # # pinctrl/renesas/rz + "renesas_rza2m_pinctrl": "pinctrl/renesas/rz", "renesas_rzt2m_pinctrl": "pinctrl/renesas/rz", # # pm_cpu_ops @@ -1120,38 +1466,53 @@ # # power_domain "intel_adsp_power_domain": "power_domain", + "nordic_nrfs_gdpwr": "power_domain", + "nordic_nrfs_swext": "power_domain", "nxp_scu_pd": "power_domain", "power_domain_gpio": "power_domain", "power_domain_gpio_monitor": "power_domain", + "power_domain_soc_state_change": "power_domain", + "silabs_siwx91x_power_domain": "power_domain", + "ti_sci_pm_domain": "power_domain", # # ps2 "microchip_xec_ps2": "ps2", "nuvoton_npcx_ps2_channel": "ps2", "nuvoton_npcx_ps2_ctrl": "ps2", # + # psi5 + "nxp_s32_psi5": "psi5", + # # ptp_clock "nxp_enet_ptp_clock": "ptp_clock", + "nxp_netc_ptp_clock": "ptp_clock", # # pwm "adi_max32_pwm": "pwm", + "ambiq_ctimer_pwm": "pwm", + "ambiq_timer_pwm": "pwm", "atmel_sam0_tc_pwm": "pwm", "atmel_sam0_tcc_pwm": "pwm", "atmel_sam_pwm": "pwm", + "ene_kb106x_pwm": "pwm", "ene_kb1200_pwm": "pwm", "espressif_esp32_ledc": "pwm", "espressif_esp32_mcpwm": "pwm", "fsl_imx27_pwm": "pwm", "gd_gd32_pwm": "pwm", - "infineon_cat1_pwm": "pwm", + "infineon_tcpwm_pwm": "pwm", "infineon_xmc4xxx_ccu4_pwm": "pwm", "infineon_xmc4xxx_ccu8_pwm": "pwm", "intel_blinky_pwm": "pwm", + "ite_it51xxx_pwm": "pwm", "ite_it8801_pwm": "pwm", "ite_it8xxx2_pwm": "pwm", "litex_pwm": "pwm", "maxim_max31790_pwm": "pwm", + "microchip_tcc_g1_pwm": "pwm", "microchip_xec_pwm": "pwm", "microchip_xec_pwmbbled": "pwm", + "neorv32_pwm": "pwm", "nordic_nrf_sw_pwm": "pwm", "nuvoton_npcx_pwm": "pwm", "nuvoton_numaker_pwm": "pwm", @@ -1167,14 +1528,24 @@ "nxp_sctimer_pwm": "pwm", "openisa_rv32m1_tpm": "pwm", "raspberrypi_pico_pwm": "pwm", + "realtek_rts5912_pwm": "pwm", "renesas_pwm_rcar": "pwm", "renesas_ra_pwm": "pwm", + "renesas_rx_mtu_pwm": "pwm", + "renesas_rz_gpt_pwm": "pwm", + "renesas_rz_mtu_pwm": "pwm", "sifive_pwm0": "pwm", "silabs_gecko_pwm": "pwm", + "silabs_letimer_pwm": "pwm", + "silabs_siwx91x_pwm": "pwm", + "silabs_timer_pwm": "pwm", "st_stm32_pwm": "pwm", "telink_b91_pwm": "pwm", "ti_cc13xx_cc26xx_timer_pwm": "pwm", + "ti_cc23x0_lgpt_pwm": "pwm", + "ti_mspm0_timer_pwm": "pwm", "vnd_pwm": "pwm", + "wch_gptm_pwm": "pwm", "xlnx_xps_timer_1_00_a_pwm": "pwm", "zephyr_fake_pwm": "pwm", # @@ -1185,30 +1556,39 @@ "mps_mpm54304": "regulator", "nordic_npm1100": "regulator", "nordic_npm1300_regulator": "regulator", + "nordic_npm1304_regulator": "regulator", "nordic_npm2100_regulator": "regulator", "nordic_npm6001_regulator": "regulator", "nxp_pca9420": "regulator", + "nxp_pca9422_regulator": "regulator", + "nxp_pf1550_regulator": "regulator", "nxp_vref": "regulator", + "nxp_vrefv1": "regulator", "raspberrypi_core_supply_regulator": "regulator", "regulator_fixed": "regulator", "regulator_gpio": "regulator", "renesas_smartbond_regulator": "regulator", - "x_powers_axp192_regulator": "regulator", "zephyr_fake_regulator": "regulator", # # reset "aspeed_ast10x0_reset": "reset", "gd_gd32_rctl": "reset", "intel_socfpga_reset": "reset", + "microchip_mpfs_reset": "reset", + "microchip_rstc_g1_reset": "reset", "nuvoton_npcx_rst": "reset", "nuvoton_numaker_rst": "reset", "nxp_lpc_syscon_reset": "reset", + "nxp_mrcc_reset": "reset", "nxp_rstctl": "reset", "raspberrypi_pico_reset": "reset", + "reset_mmio": "reset", + "sifli_sf32lb_rcc_rctl": "reset", "st_stm32_rcc_rctl": "reset", # # retained_mem "nordic_nrf_gpregret": "retained_mem", + "silabs_buram": "retained_mem", "zephyr_retained_ram": "retained_mem", "zephyr_retained_reg": "retained_mem", # @@ -1216,39 +1596,58 @@ "ambiq_am1805": "rtc", "ambiq_rtc": "rtc", "atmel_sam_rtc": "rtc", + "epson_rx8130ce_rtc": "rtc", "infineon_cat1_rtc": "rtc", "infineon_xmc4xxx_rtc": "rtc", "maxim_ds1307": "rtc", + "maxim_ds1337": "rtc", "maxim_ds3231_rtc": "rtc", "microcrystal_rv3028": "rtc", + "microcrystal_rv3032": "rtc", "microcrystal_rv8803": "rtc", "microcrystal_rv_8263_c8": "rtc", "motorola_mc146818": "rtc", "nuvoton_numaker_rtc": "rtc", "nxp_irtc": "rtc", + "nxp_pcf2123": "rtc", + "nxp_pcf85063a": "rtc", "nxp_pcf8523": "rtc", "nxp_pcf8563": "rtc", "raspberrypi_pico_rtc": "rtc", + "realtek_rts5912_rtc": "rtc", + "renesas_ra_rtc": "rtc", "renesas_smartbond_rtc": "rtc", + "silabs_siwx91x_rtc": "rtc", "st_stm32_rtc": "rtc", + "ti_bq32002": "rtc", + "ti_mspm0_rtc": "rtc", "zephyr_fake_rtc": "rtc", + "zephyr_rtc_counter": "rtc", "zephyr_rtc_emul": "rtc", # # sdhc + "adi_max32_sdhc": "sdhc", + "ambiq_sdio": "sdhc", "atmel_sam_hsmci": "sdhc", "cdns_sdhc": "sdhc", "espressif_esp32_sdhc_slot": "sdhc", "infineon_cat1_sdhc_sdio": "sdhc", "intel_emmc_host": "sdhc", + "microchip_sama7g5_sdmmc": "sdhc", "nxp_imx_usdhc": "sdhc", "nxp_lpc_sdif": "sdhc", "renesas_ra_sdhc": "sdhc", "renesas_rcar_mmc": "sdhc", + "st_stm32_sdio": "sdhc", + "xlnx_versal_8_9a": "sdhc", "zephyr_sdhc_spi_slot": "sdhc", # # sensor/a01nyub "dfrobot_a01nyub": "sensor/a01nyub", # + # sensor/adi/ad2s1210 + "adi_ad2s1210": "sensor/adi/ad2s1210", + # # sensor/adi/adltc2990 "adi_adltc2990": "sensor/adi/adltc2990", # @@ -1271,6 +1670,12 @@ # sensor/adi/adxl372 "adi_adxl372": "sensor/adi/adxl372", # + # sensor/adi/max32664c + "maxim_max32664c": "sensor/adi/max32664c", + # + # sensor/als31300 + "allegro_als31300": "sensor/als31300", + # # sensor/amd_sb_tsi "amd_sb_tsi": "sensor/amd_sb_tsi", # @@ -1362,6 +1767,9 @@ "bosch_bmp388": "sensor/bosch/bmp388", "bosch_bmp390": "sensor/bosch/bmp388", # + # sensor/broadcom/afbr_s50 + "brcm_afbr_s50": "sensor/broadcom/afbr_s50", + # # sensor/current_amp "current_sense_amplifier": "sensor/current_amp", # @@ -1377,6 +1785,9 @@ # sensor/espressif/pcnt_esp32 "espressif_esp32_pcnt": "sensor/espressif/pcnt_esp32", # + # sensor/everlight/als_pt19 + "everlight_als_pt19": "sensor/everlight/als_pt19", + # # sensor/explorir_m "gss_explorir_m": "sensor/explorir_m", # @@ -1414,6 +1825,9 @@ # sensor/infineon/xmc4xxx_temp "infineon_xmc4xxx_temp": "sensor/infineon/xmc4xxx_temp", # + # sensor/ite/ite_tach_it51xxx + "ite_it51xxx_tach": "sensor/ite/ite_tach_it51xxx", + # # sensor/ite/ite_tach_it8xxx2 "ite_it8xxx2_tach": "sensor/ite/ite_tach_it8xxx2", # @@ -1423,6 +1837,12 @@ # sensor/jedec/jc42 "jedec_jc_42_4_temp": "sensor/jedec/jc42", # + # sensor/liteon/ltr329 + "liteon_ltr329": "sensor/liteon/ltr329", + # + # sensor/liteon/ltrf216a + "liteon_ltrf216a": "sensor/liteon/ltrf216a", + # # sensor/lm35 "lm35": "sensor/lm35", # @@ -1432,9 +1852,6 @@ # sensor/lm77 "lm77": "sensor/lm77", # - # sensor/ltrf216a - "ltr_f216a": "sensor/ltrf216a", - # # sensor/maxim/ds18b20 "maxim_ds18b20": "sensor/maxim/ds18b20", "maxim_ds18s20": "sensor/maxim/ds18b20", @@ -1467,11 +1884,15 @@ # sensor/maxim/max6675 "maxim_max6675": "sensor/maxim/max6675", # + # sensor/mb7040 + "maxbotix_mb7040": "sensor/mb7040", + # # sensor/meas/ms5607 "meas_ms5607": "sensor/meas/ms5607", # # sensor/meas/ms5837 - "meas_ms5837": "sensor/meas/ms5837", + "meas_ms5837_02ba": "sensor/meas/ms5837", + "meas_ms5837_30ba": "sensor/meas/ms5837", # # sensor/melexis/mlx90394 "melexis_mlx90394": "sensor/melexis/mlx90394", @@ -1491,14 +1912,18 @@ # sensor/microchip/mcp970x "microchip_mcp970x": "sensor/microchip/mcp970x", # + # sensor/microchip/mtch9010 + "microchip_mtch9010": "sensor/microchip/mtch9010", + # # sensor/microchip/tcn75a "microchip_tcn75a": "sensor/microchip/tcn75a", # # sensor/nct75 "onnn_nct75": "sensor/nct75", # - # sensor/nordic/npm1300_charger - "nordic_npm1300_charger": "sensor/nordic/npm1300_charger", + # sensor/nordic/npm13xx_charger + "nordic_npm1300_charger": "sensor/nordic/npm13xx_charger", + "nordic_npm1304_charger": "sensor/nordic/npm13xx_charger", # # sensor/nordic/npm2100_vbat "nordic_npm2100_vbat": "sensor/nordic/npm2100_vbat", @@ -1541,9 +1966,18 @@ # sensor/nxp/nxp_kinetis_temp "nxp_kinetis_temperature": "sensor/nxp/nxp_kinetis_temp", # + # sensor/nxp/nxp_lpadc_temp40 + "nxp_lpadc_temp40": "sensor/nxp/nxp_lpadc_temp40", + # + # sensor/nxp/nxp_pmc_tmpsns + "nxp_pmc_tmpsns": "sensor/nxp/nxp_pmc_tmpsns", + # # sensor/nxp/nxp_tempmon "nxp_tempmon": "sensor/nxp/nxp_tempmon", # + # sensor/nxp/nxp_tmpsns + "nxp_tmpsns": "sensor/nxp/nxp_tmpsns", + # # sensor/nxp/p3t1755 "nxp_p3t1755": "sensor/nxp/p3t1755", # @@ -1553,12 +1987,40 @@ # sensor/nxp/qdec_nxp_s32 "nxp_qdec_s32": "sensor/nxp/qdec_nxp_s32", # + # sensor/nxp/qdec_tpm + "nxp_tpm_qdec": "sensor/nxp/qdec_tpm", + # + # sensor/omron/2smpb_02e + "omron_2smpb_02e": "sensor/omron/2smpb_02e", + # + # sensor/omron/d6f + "omron_d6f_p0001": "sensor/omron/d6f", + "omron_d6f_p0010": "sensor/omron/d6f", + # + # sensor/pixart/paa3905 + "pixart_paa3905": "sensor/pixart/paa3905", + # + # sensor/pixart/paj7620 + "pixart_paj7620": "sensor/pixart/paj7620", + # + # sensor/pixart/pat9136 + "pixart_pat9136": "sensor/pixart/pat9136", + # # sensor/pms7003 "plantower_pms7003": "sensor/pms7003", # + # sensor/pni/rm3100 + "pni_rm3100": "sensor/pni/rm3100", + # + # sensor/pzem004t + "peacefair_pzem004t": "sensor/pzem004t", + # # sensor/qdec_sam "atmel_sam_tc_qdec": "sensor/qdec_sam", # + # sensor/realtek/rts5912 + "realtek_rts5912_tach": "sensor/realtek/rts5912", + # # sensor/renesas/hs300x "renesas_hs300x": "sensor/renesas/hs300x", # @@ -1571,9 +2033,15 @@ # sensor/rohm/bd8lb600fs "rohm_bd8lb600fs_diagnostics": "sensor/rohm/bd8lb600fs", # + # sensor/rohm/bh1730 + "rohm_bh1730": "sensor/rohm/bh1730", + # # sensor/rohm/bh1750 "rohm_bh1750": "sensor/rohm/bh1750", # + # sensor/rohm/bh1790 + "rohm_bh1790": "sensor/rohm/bh1790", + # # sensor/rpi_pico_temp "raspberrypi_pico_temp": "sensor/rpi_pico_temp", # @@ -1643,6 +2111,9 @@ # sensor/st/iis3dhhc "st_iis3dhhc": "sensor/st/iis3dhhc", # + # sensor/st/iis3dwb + "st_iis3dwb": "sensor/st/iis3dwb", + # # sensor/st/ism330dhcx "st_ism330dhcx": "sensor/st/ism330dhcx", # @@ -1702,7 +2173,8 @@ "st_lsm6dso16is": "sensor/st/lsm6dso16is", # # sensor/st/lsm6dsv16x - "st_lsm6dsv16x": "sensor/st/lsm6dsv16x", + "DT_DRV_COMPAT_LSM6DSV16X": "sensor/st/lsm6dsv16x", + "DT_DRV_COMPAT_LSM6DSV32X": "sensor/st/lsm6dsv16x", # # sensor/st/lsm9ds0_gyro "st_lsm9ds0_gyro": "sensor/st/lsm9ds0_gyro", @@ -1713,6 +2185,9 @@ # sensor/st/lsm9ds1 "st_lsm9ds1": "sensor/st/lsm9ds1", # + # sensor/st/lsm9ds1_mag + "st_lsm9ds1_mag": "sensor/st/lsm9ds1_mag", + # # sensor/st/qdec_stm32 "st_stm32_qdec": "sensor/st/qdec_stm32", # @@ -1745,18 +2220,32 @@ # sensor/sx9500 "semtech_sx9500": "sensor/sx9500", # + # sensor/tach_gpio + "zephyr_tach_gpio": "sensor/tach_gpio", + # + # sensor/tdk/icm40627 + "invensense_icm40627": "sensor/tdk/icm40627", + # # sensor/tdk/icm42605 "invensense_icm42605": "sensor/tdk/icm42605", # - # sensor/tdk/icm42670 - "invensense_icm42670p": "sensor/tdk/icm42670", - "invensense_icm42670s": "sensor/tdk/icm42670", + # sensor/tdk/icm4268x + "invensense_icm42688": "sensor/tdk/icm4268x", + "invensense_icm4268x": "sensor/tdk/icm4268x", # - # sensor/tdk/icm42688 - "invensense_icm42688": "sensor/tdk/icm42688", + # sensor/tdk/icm42x70 + "invensense_icm42370p": "sensor/tdk/icm42x70", + "invensense_icm42670p": "sensor/tdk/icm42x70", + "invensense_icm42670s": "sensor/tdk/icm42x70", # - # sensor/tdk/icp10125 - "invensense_icp10125": "sensor/tdk/icp10125", + # sensor/tdk/icm45686 + "invensense_icm45686": "sensor/tdk/icm45686", + # + # sensor/tdk/icp101xx + "invensense_icp101xx": "sensor/tdk/icp101xx", + # + # sensor/tdk/icp201xx + "invensense_icp201xx": "sensor/tdk/icp201xx", # # sensor/tdk/mpu6050 "invensense_mpu6050": "sensor/tdk/mpu6050", @@ -1776,17 +2265,19 @@ # sensor/ti/ina219 "ti_ina219": "sensor/ti/ina219", # - # sensor/ti/ina226 - "ti_ina226": "sensor/ti/ina226", - # - # sensor/ti/ina23x - "ti_ina230": "sensor/ti/ina23x", - "ti_ina236": "sensor/ti/ina23x", - "ti_ina237": "sensor/ti/ina23x", + # sensor/ti/ina2xx + "ti_ina226": "sensor/ti/ina2xx", + "ti_ina228": "sensor/ti/ina2xx", + "ti_ina230": "sensor/ti/ina2xx", + "ti_ina236": "sensor/ti/ina2xx", + "ti_ina237": "sensor/ti/ina2xx", # # sensor/ti/ina3221 "ti_ina3221": "sensor/ti/ina3221", # + # sensor/ti/ina7xx + "ti_ina7xx": "sensor/ti/ina7xx", + # # sensor/ti/lm95234 "national_lm95234": "sensor/ti/lm95234", # @@ -1796,6 +2287,9 @@ # sensor/ti/ti_hdc "ti_hdc": "sensor/ti/ti_hdc", # + # sensor/ti/ti_hdc302x + "ti_hdc302x": "sensor/ti/ti_hdc302x", + # # sensor/ti/tmag5170 "ti_tmag5170": "sensor/ti/tmag5170", # @@ -1815,8 +2309,11 @@ # sensor/ti/tmp114 "ti_tmp114": "sensor/ti/tmp114", # - # sensor/ti/tmp116 - "ti_tmp116": "sensor/ti/tmp116", + # sensor/ti/tmp11x + "ti_tmp11x": "sensor/ti/tmp11x", + # + # sensor/ti/tmp435 + "ti_tmp435": "sensor/ti/tmp435", # # sensor/tsic_xx6 "ist_tsic_xx6": "sensor/tsic_xx6", @@ -1830,6 +2327,12 @@ # sensor/vishay/vcnl4040 "vishay_vcnl4040": "sensor/vishay/vcnl4040", # + # sensor/vishay/veml6031 + "vishay_veml6031": "sensor/vishay/veml6031", + # + # sensor/vishay/veml6046 + "vishay_veml6046": "sensor/vishay/veml6046", + # # sensor/vishay/veml7700 "vishay_veml7700": "sensor/vishay/veml7700", # @@ -1839,37 +2342,66 @@ # sensor/wsen/wsen_hids_2525020210002 "we_wsen_hids_2525020210002": "sensor/wsen/wsen_hids_2525020210002", # + # sensor/wsen/wsen_isds_2536030320001 + "we_wsen_isds_2536030320001": "sensor/wsen/wsen_isds_2536030320001", + # + # sensor/wsen/wsen_itds_2533020201601 + "we_wsen_itds_2533020201601": "sensor/wsen/wsen_itds_2533020201601", + # + # sensor/wsen/wsen_pads_2511020213301 + "we_wsen_pads_2511020213301": "sensor/wsen/wsen_pads_2511020213301", + # + # sensor/wsen/wsen_pdms_25131308XXX05 + "we_wsen_pdms_25131308xxx05": "sensor/wsen/wsen_pdms_25131308XXX05", + # # sensor/wsen/wsen_pdus_25131308XXXXX "we_wsen_pdus_25131308xxxxx": "sensor/wsen/wsen_pdus_25131308XXXXX", # + # sensor/wsen/wsen_tids_2521020222501 + "we_wsen_tids_2521020222501": "sensor/wsen/wsen_tids_2521020222501", + # + # sensor/xbr818 + "phosense_xbr818": "sensor/xbr818", + # + # sent + "nxp_s32_sent": "sent", + # # serial "SBSA_COMPAT": "serial", "adi_max32_uart": "serial", + "aesc_uart": "serial", "altr_jtag_uart": "serial", "altr_uart": "serial", + "ambiq_uart": "serial", "arm_cmsdk_uart": "serial", "arm_pl011": "serial", "atmel_sam0_uart": "serial", "atmel_sam_uart": "serial", "atmel_sam_usart": "serial", + "bflb_uart": "serial", "brcm_bcm2711_aux_uart": "serial", "cdns_uart": "serial", "cypress_psoc6_uart": "serial", "efinix_sapphire_uart0": "serial", + "ene_kb106x_uart": "serial", "ene_kb1200_uart": "serial", + "espressif_esp32_lpuart": "serial", "espressif_esp32_uart": "serial", "espressif_esp32_usb_serial": "serial", "gaisler_apbuart": "serial", "gd_gd32_usart": "serial", "infineon_cat1_uart": "serial", + "infineon_cat1_uart_pdl": "serial", "infineon_xmc4xxx_uart": "serial", "intel_lw_uart": "serial", "intel_sedi_uart": "serial", + "ite_it51xxx_uart": "serial", "ite_it8xxx2_uart": "serial", "litex_uart": "serial", "lowrisc_opentitan_uart": "serial", "microchip_coreuart": "serial", "microchip_mec5_uart": "serial", + "microchip_sercom_g1_uart": "serial", "microchip_xec_uart": "serial", "neorv32_uart": "serial", "nordic_nrf_uart": "serial", @@ -1891,35 +2423,47 @@ "realtek_rts5912_uart": "serial", "renesas_ra8_uart_sci_b": "serial", "renesas_ra_sci_uart": "serial", - "renesas_ra_uart_sci": "serial", "renesas_rcar_hscif": "serial", "renesas_rcar_scif": "serial", + "renesas_rx_uart_sci": "serial", + "renesas_rx_uart_sci_qemu": "serial", + "renesas_rz_sci_b_uart": "serial", + "renesas_rz_sci_uart": "serial", "renesas_rz_scif_uart": "serial", + "renesas_rza2m_scif_uart": "serial", "renesas_rzt2m_uart": "serial", "renesas_smartbond_uart": "serial", "segger_rtt_uart": "serial", "sensry_sy1xx_uart": "serial", "sifive_uart0": "serial", + "sifli_sf32lb_usart": "serial", "silabs_eusart_uart": "serial", "silabs_gecko_leuart": "serial", "silabs_gecko_uart": "serial", "silabs_gecko_usart": "serial", "silabs_si32_usart": "serial", + "silabs_usart_uart": "serial", "snps_hostlink_uart": "serial", "st_stm32_uart": "serial", "telink_b91_uart": "serial", "ti_cc13xx_cc26xx_uart": "serial", + "ti_cc23x0_uart": "serial", "ti_cc32xx_uart": "serial", "ti_msp432p4xx_uart": "serial", + "ti_mspm0_uart": "serial", "ti_stellaris_uart": "serial", + "virtio_console": "serial", "vnd_serial": "serial", "wch_usart": "serial", "xen_hvc_consoleio": "serial", "xlnx_xps_uartlite_1_00_a": "serial", "xlnx_xuartps": "serial", "zephyr_native_posix_uart": "serial", + "zephyr_native_pty_uart": "serial", "zephyr_native_tty_uart": "serial", "zephyr_nus_uart": "serial", + "zephyr_uart_bitbang": "serial", + "zephyr_uart_bridge": "serial", "zephyr_uart_emul": "serial", # # sip_svc @@ -1938,18 +2482,23 @@ "arm_pl022": "spi", "atmel_sam0_spi": "spi", "atmel_sam_spi": "spi", + "cdns_spi": "spi", "cypress_psoc6_spi": "spi", + "egis_et171_spi": "spi", "espressif_esp32_spi": "spi", "gaisler_spimctrl": "spi", "gd_gd32_spi": "spi", "infineon_cat1_spi": "spi", + "infineon_cat1_spi_pdl": "spi", "infineon_xmc4xxx_spi": "spi", "intel_penwell_spi": "spi", "intel_sedi_spi": "spi", + "ite_it51xxx_spi": "spi", "ite_it8xxx2_spi": "spi", "litex_spi": "spi", "litex_spi_litespi": "spi", "lowrisc_opentitan_spi": "spi", + "microchip_mec5_qspi": "spi", "microchip_mpfs_qspi": "spi", "microchip_mpfs_spi": "spi", "microchip_xec_qmspi": "spi", @@ -1961,20 +2510,28 @@ "nxp_imx_ecspi": "spi", "nxp_lpc_spi": "spi", "nxp_s32_spi": "spi", + "nxp_sc18is606_spi": "spi", "opencores_spi_simple": "spi", "openisa_rv32m1_lpspi": "spi", "raspberrypi_pico_spi_pio": "spi", "renesas_ra8_spi_b": "spi", "renesas_ra_spi": "spi", + "renesas_rx_rspi": "spi", + "renesas_rz_rspi": "spi", + "renesas_rz_spi": "spi", "renesas_smartbond_spi": "spi", "sifive_spi0": "spi", "silabs_eusart_spi": "spi", + "silabs_gspi": "spi", "silabs_usart_spi": "spi", "snps_designware_spi": "spi", "st_stm32_spi": "spi", "telink_b91_spi": "spi", "ti_cc13xx_cc26xx_spi": "spi", + "ti_cc23x0_spi": "spi", + "ti_omap_mcspi": "spi", "vnd_spi": "spi", + "wch_spi": "spi", "xlnx_xps_spi_2_00_a": "spi", "zephyr_spi_bitbang": "spi", "zephyr_spi_emul_controller": "spi", @@ -1984,16 +2541,20 @@ # # stepper "zephyr_fake_stepper": "stepper", - "zephyr_gpio_stepper": "stepper", + "zephyr_h_bridge_stepper": "stepper", # # stepper/adi_tmc "adi_tmc2209": "stepper/adi_tmc", - "adi_tmc5041": "stepper/adi_tmc", + "adi_tmc50xx": "stepper/adi_tmc", + # + # stepper/allegro + "allegro_a4979": "stepper/allegro", # # stepper/ti - "ti_drv8424": "stepper/ti", + "ti_drv84xx": "stepper/ti", # # syscon + "bflb_efuse": "syscon", "syscon": "syscon", # # tee/optee @@ -2001,35 +2562,35 @@ # # timer "ambiq_stimer": "timer", - "andestech_machine_timer": "timer", "atmel_sam0_rtc": "timer", "gaisler_gptimer": "timer", + "infineon_cat1_lp_timer": "timer", "intel_adsp_timer": "timer", "intel_hpet": "timer", + "ite_it51xxx_timer": "timer", "ite_it8xxx2_timer": "timer", "litex_timer0": "timer", - "lowrisc_machine_timer": "timer", - "microchip_mec5_ktimer": "timer", + "microchip_sam_pit64b": "timer", "microchip_xec_rtos_timer": "timer", - "neorv32_machine_timer": "timer", - "niosv_machine_timer": "timer", - "nuclei_systimer": "timer", "nuvoton_npcx_itim_timer": "timer", "nxp_gpt_hw_timer": "timer", - "nxp_kinetis_lptmr": "timer", "nxp_lptmr": "timer", "nxp_os_timer": "timer", "openisa_rv32m1_lptmr": "timer", "realtek_rts5912_rtmr": "timer", + "renesas_ra_ulpt_timer": "timer", "renesas_rcar_cmt": "timer", - "scr_machine_timer": "timer", - "sifive_clint0": "timer", + "renesas_rx_timer_cmt": "timer", + "renesas_rz_gtm_os_timer": "timer", + "renesas_rza2m_ostm": "timer", + "riscv_machine_timer": "timer", "silabs_gecko_burtc": "timer", "st_stm32_lptim": "timer", "sy1xx_sys_timer": "timer", - "telink_machine_timer": "timer", "ti_am654_timer": "timer", "ti_cc13xx_cc26xx_rtc_timer": "timer", + "ti_cc23x0_rtc_timer": "timer", + "ti_cc23x0_systim_timer": "timer", "wch_systick": "timer", "xlnx_ttcps": "timer", # @@ -2037,12 +2598,13 @@ "diodes_pi3usb9201": "usb/bc12", # # usb/device - "atmel_sam0_usb": "usb/device", "atmel_sam_usbc": "usb/device", "atmel_sam_usbhs": "usb/device", # # usb/udc + "adi_max32_usbhs": "usb/udc", "ambiq_usb": "usb/udc", + "atmel_sam0_usb": "usb/udc", "ite_it82xx2_usb": "usb/udc", "nordic_nrf_usbd": "usb/udc", "nuvoton_numaker_usbd": "usb/udc", @@ -2061,6 +2623,10 @@ # # usb/uhc "maxim_max3421e_spi": "usb/uhc", + "nxp_uhc_ehci": "usb/uhc", + "nxp_uhc_ip3516hs": "usb/uhc", + "nxp_uhc_khci": "usb/uhc", + "nxp_uhc_ohci": "usb/uhc", "zephyr_uhc_virtual": "usb/uhc", # # usb_c/ppc @@ -2069,6 +2635,7 @@ # # usb_c/tcpc "nuvoton_numaker_tcpc": "usb_c/tcpc", + "onnn_fusb307_tcpc": "usb_c/tcpc", "parade_ps8xxx": "usb_c/tcpc", "richtek_rt1715": "usb_c/tcpc", "st_stm32_ucpd": "usb_c/tcpc", @@ -2082,6 +2649,7 @@ "aptina_mt9m114": "video", "espressif_esp32_lcd_cam": "video", "galaxycore_gc2145": "video", + "himax_hm01b0": "video", "nxp_imx_csi": "video", "nxp_mipi_csi2rx": "video", "nxp_video_smartdma": "video", @@ -2089,10 +2657,21 @@ "ovti_ov5640": "video", "ovti_ov7670": "video", "ovti_ov7725": "video", + "ovti_ov9655": "video", + "renesas_ra_ceu": "video", + "sony_imx335": "video", + "st_mipid02": "video", "st_stm32_dcmi": "video", - "zephyr_sw_generator": "video", + "st_stm32_dcmipp": "video", + "st_stm32_jpeg": "video", + "st_stm32_venc": "video", "zephyr_video_emul_imager": "video", "zephyr_video_emul_rx": "video", + "zephyr_video_sw_generator": "video", + # + # virtio + "virtio_mmio": "virtio", + "virtio_pci": "virtio", # # virtualization "qemu_ivshmem": "virtualization", @@ -2113,7 +2692,9 @@ "andestech_atcwdt200": "watchdog", "arm_cmsdk_watchdog": "watchdog", "atmel_sam0_watchdog": "watchdog", + "atmel_sam4l_watchdog": "watchdog", "atmel_sam_watchdog": "watchdog", + "ene_kb106x_watchdog": "watchdog", "ene_kb1200_watchdog": "watchdog", "espressif_esp32_watchdog": "watchdog", "espressif_esp32_xt_wdt": "watchdog", @@ -2123,31 +2704,45 @@ "infineon_xmc4xxx_watchdog": "watchdog", "intel_adsp_watchdog": "watchdog", "intel_tco_wdt": "watchdog", + "ite_it51xxx_watchdog": "watchdog", "ite_it8xxx2_watchdog": "watchdog", "litex_watchdog": "watchdog", "lowrisc_opentitan_aontimer": "watchdog", "microchip_xec_watchdog": "watchdog", "nordic_npm1300_wdt": "watchdog", + "nordic_npm1304_wdt": "watchdog", "nordic_npm2100_wdt": "watchdog", "nordic_npm6001_wdt": "watchdog", "nuvoton_npcx_watchdog": "watchdog", "nuvoton_numaker_wwdt": "watchdog", + "nxp_cop": "watchdog", + "nxp_ewm": "watchdog", "nxp_fs26_wdog": "watchdog", "nxp_imx_wdog": "watchdog", "nxp_kinetis_wdog": "watchdog", "nxp_lpc_wwdt": "watchdog", + "nxp_rtwdog": "watchdog", "nxp_s32_swt": "watchdog", "nxp_wdog32": "watchdog", "raspberrypi_pico_watchdog": "watchdog", + "realtek_rts5912_watchdog": "watchdog", + "renesas_rx_iwdt": "watchdog", + "renesas_rz_wdt": "watchdog", "renesas_smartbond_watchdog": "watchdog", "sifive_wdt": "watchdog", + "sifli_sf32lb_wdt": "watchdog", "silabs_gecko_wdog": "watchdog", + "silabs_siwx91x_wdt": "watchdog", "snps_designware_watchdog": "watchdog", "st_stm32_watchdog": "watchdog", "st_stm32_window_watchdog": "watchdog", "ti_cc13xx_cc26xx_watchdog": "watchdog", + "ti_cc23x0_wdt": "watchdog", "ti_cc32xx_watchdog": "watchdog", + "ti_j7_rti_wdt": "watchdog", "ti_tps382x": "watchdog", + "wch_iwdg": "watchdog", + "xlnx_versal_wwdt": "watchdog", "xlnx_xps_timebase_wdt_1_00_a": "watchdog", # # wifi/esp32/src @@ -2166,6 +2761,9 @@ # wifi/nxp "nxp_wifi": "wifi/nxp", # + # wifi/siwx91x + "silabs_siwx91x_wifi": "wifi/siwx91x", + # # wifi/winc1500 "atmel_winc1500": "wifi/winc1500", } diff --git a/ports/zephyr-cp/cptools/cpbuild.py b/ports/zephyr-cp/cptools/cpbuild.py index ef836b3df8af3..edaf020c264a0 100644 --- a/ports/zephyr-cp/cptools/cpbuild.py +++ b/ports/zephyr-cp/cptools/cpbuild.py @@ -1,15 +1,14 @@ import asyncio -import inspect +import atexit +import hashlib +import json import logging import os import pathlib -import shlex -import time -import hashlib -import atexit -import json import re -import sys +import tempfile +import time +from typing import Optional logger = logging.getLogger(__name__) @@ -111,7 +110,14 @@ def _create_semaphore(): max_track = 0 -async def run_command(command, working_directory, description=None, check_hash=[], extradeps=[]): +async def run_command( + command, + working_directory, + description=None, + check_hash=[], + extradeps=[], + responsefile: Optional[pathlib.Path] = None, +): """ Runs a command asynchronously. The command should ideally be a list of strings and pathlib.Path objects. If all of the paths haven't been modified since the last @@ -124,26 +130,39 @@ async def run_command(command, working_directory, description=None, check_hash=[ Paths in check_hash are hashed before and after the command. If the hash is the same, then the old mtimes are reset. This is helpful if a command may produce - the same result and you don't want the rest of the build impacted. + the same result and you don't want the rest of the build impacted + + responsefile is used to store the command line arguments if they are too long for the OS. + The arguments will be replaced with @ and tried again. + If None, commands that are too long will fail. """ paths = [] + responsefile_contents = None if isinstance(command, list): for i, part in enumerate(command): if isinstance(part, pathlib.Path): paths.append(part) part = part.relative_to(working_directory, walk_up=True) - # if isinstance(part, list): command[i] = str(part) - command = " ".join(command) + command_string = " ".join(command) + + # When on windows, use a responsefile if the command string is >= 8192 + if responsefile is not None and os.name == "nt" and len(command_string) >= 8192: + # Escape backslashes + responsefile_contents = "\n".join(part.replace("\\", "\\\\") for part in command[1:]) + responsefile.write_text(responsefile_contents) + command_string = f"{command[0]} -v @{responsefile}" + else: + command_string = command - command_hash = hashlib.sha3_256(command.encode("utf-8")) + command_hash = hashlib.sha3_256(command_string.encode("utf-8")) command_hash.update(str(working_directory).encode("utf-8")) command_hash = command_hash.hexdigest() # If a command is run multiple times, then wait for the first one to continue. Don't run it again. if command_hash in ALREADY_RUN: - logger.debug(f"Already running {command_hash} {command}") + logger.debug(f"Already running {command_hash} {command_string}") await ALREADY_RUN[command_hash].wait() return ALREADY_RUN[command_hash] = asyncio.Event() @@ -169,7 +188,7 @@ async def run_command(command, working_directory, description=None, check_hash=[ run_reason = f"{p.relative_to(working_directory, walk_up=True)} is newer" break if nothing_newer: - logger.debug(f"Nothing newer {command[-32:]}") + logger.debug(f"Nothing newer {command_string[-32:]}") ALREADY_RUN[command_hash].set() return else: @@ -196,7 +215,7 @@ async def run_command(command, working_directory, description=None, check_hash=[ track = tracks.pop() start_time = time.perf_counter_ns() // 1000 process = await asyncio.create_subprocess_shell( - command, + command_string, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd=working_directory, @@ -242,22 +261,25 @@ async def run_command(command, working_directory, description=None, check_hash=[ raise cancellation if description: logger.info(f"{description} ({run_reason})") - logger.debug(command) + logger.debug(command_string) else: - logger.info(f"{command} ({run_reason})") + logger.info(f"{command_string} ({run_reason})") if old_newest_file == newest_file: logger.error("No files were modified by the command.") raise RuntimeError() else: if command_hash in LAST_BUILD_TIMES: del LAST_BUILD_TIMES[command_hash] + logger.error(command_string) + if responsefile_contents: + logger.error(f"Response file contents:\n{responsefile_contents}") + logger.error(f"Return code: {process.returncode}") if stdout: logger.info(stdout.decode("utf-8").strip()) if stderr: logger.warning(stderr.decode("utf-8").strip()) if not stdout and not stderr: logger.warning("No output") - logger.error(command) if cancellation: raise cancellation raise RuntimeError() @@ -335,8 +357,8 @@ async def preprocess( ): output_file.parent.mkdir(parents=True, exist_ok=True) depfile = output_file.parent / (output_file.name + ".d") - if depfile.exists(): - pass + responsefile = output_file.parent / (output_file.name + ".rsp") + await run_command( [ self.c_compiler, @@ -354,6 +376,7 @@ async def preprocess( description=f"Preprocess {source_file.relative_to(self.srcdir)} -> {output_file.relative_to(self.builddir)}", working_directory=self.srcdir, check_hash=[output_file], + responsefile=responsefile, ) async def compile( @@ -365,6 +388,7 @@ async def compile( output_file = self.builddir / output_file output_file.parent.mkdir(parents=True, exist_ok=True) depfile = output_file.with_suffix(".d") + responsefile = output_file.with_suffix(".rsp") extradeps = [] if depfile.exists(): depfile_contents = depfile.read_text().split() @@ -375,25 +399,30 @@ async def compile( extradeps.append(pathlib.Path(dep)) else: extradeps.append(self.srcdir / dep) + await run_command( - [self.c_compiler, self.cflags, "-MMD", "-c", source_file, *flags, "-o", output_file], + [ + self.c_compiler, + self.cflags, + "-MMD", + "-c", + source_file, + *flags, + "-o", + output_file, + ], description=f"Compile {source_file.relative_to(self.srcdir)} -> {output_file.relative_to(self.builddir)}", working_directory=self.srcdir, extradeps=extradeps, + responsefile=responsefile, ) async def archive(self, objects: list[pathlib.Path], output_file: pathlib.Path): output_file.parent.mkdir(parents=True, exist_ok=True) - # Do one file at a time so that we don't have a long command line. run_command - # should skip unchanged files ok. - input_files = output_file.with_suffix(output_file.suffix + ".input_files") - input_file_content = "\n".join(str(p) for p in objects) - # Windows paths have \ as separator but ar wants them as / (like UNIX) - input_file_content = input_file_content.replace("\\", "/") - input_files.write_text(input_file_content) + responsefile = output_file.with_suffix(".rsp") await run_command( - [self.ar, "rvs", output_file, f"@{input_files}"], + [self.ar, "rvs", output_file, *objects], description=f"Create archive {output_file.relative_to(self.srcdir)}", working_directory=self.srcdir, - extradeps=objects, + responsefile=responsefile, ) diff --git a/ports/zephyr-cp/cptools/gen_compat2driver.py b/ports/zephyr-cp/cptools/gen_compat2driver.py index 0cb6a16f9da54..1e529072dab4a 100644 --- a/ports/zephyr-cp/cptools/gen_compat2driver.py +++ b/ports/zephyr-cp/cptools/gen_compat2driver.py @@ -2,7 +2,7 @@ mapping = {} -drivers = pathlib.Path("lib/zephyr/drivers") +drivers = pathlib.Path("zephyr/drivers") for p in drivers.glob("**/*.c"): for line in p.open(): if line.startswith("#define DT_DRV_COMPAT"): diff --git a/ports/zephyr-cp/cptools/zephyr2cp.py b/ports/zephyr-cp/cptools/zephyr2cp.py index cd0e3a6f2aade..071334161b94c 100644 --- a/ports/zephyr-cp/cptools/zephyr2cp.py +++ b/ports/zephyr-cp/cptools/zephyr2cp.py @@ -1,14 +1,16 @@ import logging import pathlib -import cpbuild -from devicetree import dtlib +import cpbuild import yaml - from compat2driver import COMPAT_TO_DRIVER +from devicetree import dtlib logger = logging.getLogger(__name__) +# GPIO flags defined here: include/zephyr/dt-bindings/gpio/gpio.h +GPIO_ACTIVE_LOW = 1 << 0 + MANUAL_COMPAT_TO_DRIVER = { "renesas_ra_nv_flash": "flash", } @@ -82,6 +84,26 @@ "D12", "D13", ], + "arducam,dvp-20pin-connector": [ + "SCL", + "SDA", + "VS", + "HS", + "PCLK", + "XCLK", + "D7", + "D6", + "D5", + "D4", + "D3", + "D2", + "D1", + "D0", + "PEN", + "PDN", + "GPIO0", + "GPIO1", + ], "renesas,ra-gpio-mipi-header": [ "IIC_SDA", "DISP_BLEN", @@ -89,6 +111,60 @@ "DISP_INT", "DISP_RST", ], + "renesas,ra-parallel-graphics-header": [ + "DISP_BLEN", + "IIC_SDA", + "DISP_INT", + "IIC_SCL", + "DISP_RST", + "LCDC_TCON0", + "LCDC_CLK", + "LCDC_TCON2", + "LCDC_TCON1", + "LCDC_EXTCLK", + "LCDC_TCON3", + "LCDC_DATA01", + "LCDC_DATA00", + "LCDC_DATA03", + "LCDC_DATA02", + "LCDC_DATA05", + "LCDC_DATA04", + "LCDC_DATA07", + "LCDC_DATA16", + "LCDC_DATA09", + "LCDC_DATA08", + "LCDC_DATA11", + "LCDC_DATA10", + "LCDC_DATA13", + "LCDC_DATA12", + "LCDC_DATA15", + "LCDC_DATA14", + "LCDC_DATA17", + "LCDC_DATA16", + "LCDC_DATA19", + "LCDC_DATA18", + "LCDC_DATA21", + "LCDC_DATA20", + "LCDC_DATA23", + "LCDC_DATA22", + ], + "st,stm32-dcmi-camera-fpu-330zh": [ + "SCL", + "SDA", + "RESET", + "PEN", + "VS", + "HS", + "PCLK", + "D7", + "D6", + "D5", + "D4", + "D3", + "D2", + "D1", + "D0", + ], } @@ -139,6 +215,7 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 flashes = [] rams = [] status_led = None + status_led_inverted = False path2chosen = {} chosen2path = {} usb_num_endpoint_pairs = 0 @@ -247,6 +324,7 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 props = led.props ioport = props["gpios"]._markers[1][2] num = int.from_bytes(props["gpios"].value[4:8], "big") + flags = int.from_bytes(props["gpios"].value[8:12], "big") if "label" in props: if (ioport, num) not in board_names: board_names[(ioport, num)] = [] @@ -257,6 +335,7 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 if "led0" in node2alias[led]: board_names[(ioport, num)].append("LED") status_led = (ioport, num) + status_led_inverted = flags & GPIO_ACTIVE_LOW board_names[(ioport, num)].extend(node2alias[led]) if "gpio-keys" in compatible: @@ -316,8 +395,12 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 header = board_dir / "mpconfigboard.h" if status_led: status_led = f"#define MICROPY_HW_LED_STATUS (&pin_{status_led})\n" + status_led_inverted = ( + f"#define MICROPY_HW_LED_STATUS_INVERTED ({'1' if status_led_inverted else '0'})\n" + ) else: status_led = "" + status_led_inverted = "" ram_list = [] ram_externs = [] max_size = 0 @@ -339,6 +422,7 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 #define MICROPY_HW_MCU_NAME "{soc_name}" #define CIRCUITPY_RAM_DEVICE_COUNT {len(rams)} {status_led} +{status_led_inverted} """ if not header.exists() or header.read_text() != new_header_content: header.write_text(new_header_content) @@ -384,8 +468,7 @@ def zephyr_dts_to_cp_board(builddir, zephyrbuilddir): # noqa: C901 MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); """ - if not board_c.exists() or new_board_c_content != board_c.read_text(): - board_c.write_text(new_board_c_content) + board_c.write_text(new_board_c_content) board_info["source_files"] = [board_c] board_info["cflags"] = ("-I", board_dir) board_info["flash_count"] = len(flashes) diff --git a/ports/zephyr-cp/prj.conf b/ports/zephyr-cp/prj.conf index f769d7dc6b819..bd693bb897ea8 100644 --- a/ports/zephyr-cp/prj.conf +++ b/ports/zephyr-cp/prj.conf @@ -14,7 +14,7 @@ CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_THREAD_STACK_INFO=y CONFIG_STACK_SENTINEL=y CONFIG_DEBUG_THREAD_INFO=y -CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO=y CONFIG_USB_DEVICE_STACK=n diff --git a/ports/zephyr-cp/zephyr-config/west.yml b/ports/zephyr-cp/zephyr-config/west.yml index 01712e864e0db..3eb38f7bea63b 100644 --- a/ports/zephyr-cp/zephyr-config/west.yml +++ b/ports/zephyr-cp/zephyr-config/west.yml @@ -2,6 +2,6 @@ manifest: projects: - name: zephyr url: https://github.com/adafruit/zephyr - revision: circuitpython + revision: circuitpython-v4.3.0 clone-depth: 100 import: true