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 01/78] 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 02/78] 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 03/78] 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 04/78] 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 05/78] 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 06/78] 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 07/78] 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 08/78] 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 09/78] 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 10/78] 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 11/78] 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 12/78] 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 13/78] 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 d78a9c7ba0b481c5d10ff6ce70874876560900a3 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 17 Jun 2025 17:24:03 -0400 Subject: [PATCH 14/78] 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 06f7192cba388a3da683387a959c8bc1a73f2e82 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 9 Sep 2025 21:24:03 -0400 Subject: [PATCH 15/78] 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 dd0e10d6f45398683627f268eb6ad060044887d6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 21 Sep 2025 11:49:58 -0400 Subject: [PATCH 16/78] 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 3d22d521fe8d5a6c62adb1857b838166d1cf747f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 29 Sep 2025 20:15:51 -0400 Subject: [PATCH 17/78] 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 18/78] 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 19/78] 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 20/78] 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 21/78] 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 22/78] 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 23/78] 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 24/78] 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 25/78] 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 26/78] 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 27/78] 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 28/78] 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 29/78] 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 30/78] [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 31/78] [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 32/78] 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 33/78] 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 34/78] 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 35/78] 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 36/78] 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 37/78] 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 38/78] 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 39/78] 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 40/78] 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 41/78] 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 42/78] 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 43/78] 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 44/78] 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 45/78] 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 46/78] 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 47/78] 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 48/78] 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 49/78] 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 50/78] 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 51/78] 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 52/78] 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 53/78] 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 54/78] 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 55/78] 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 56/78] 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 57/78] 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 58/78] 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 59/78] 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 60/78] 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 61/78] 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 62/78] 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 63/78] 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 64/78] 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 65/78] 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 66/78] 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 67/78] 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 68/78] 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 69/78] 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 70/78] 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 71/78] 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 72/78] 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 73/78] 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 74/78] 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 75/78] 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 76/78] 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 77/78] 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 78/78] 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