From db18e541ea4faabf82b7e266f4b574d8f384e465 Mon Sep 17 00:00:00 2001 From: Moises Trovo Date: Sun, 20 Sep 2026 12:03:45 +0100 Subject: [PATCH] espressif: add ESP32-S3-BOX-3 board definition Add ports/espressif/boards/espressif_esp32s3_box_3/ (five files). The BOX-3 shares the BOX's SoC, flash and LCD bus, but differs in four ways established from esp-bsp and on hardware: - Backlight is GPIO47, not 45. The BOX firmware PWMs GPIO45, which is I2S LRCK here, so the screen stays dark. - The panel reset is active HIGH. FourWire assumes active low and would leave the panel in reset, so board_init() drives GPIO48 and FourWire gets reset=None. - The panel needs the esp-bsp vendor init sequence; neither the BOX's 6-command sequence nor the generic ILI9341 one lights it. - PSRAM is 16MB, not 8MB. pins.c mirrors the BOX layout, differing only where the hardware does: LCD_CTRL(GPIO45) is LCD_BACKLIGHT(GPIO47), and I2S_LRCK moves 47 -> 45. Serves the ILI9341/GT911 revision; the ST7789/TT21100 revision is a known gap. Verified on hardware: board_id, pin aliases, 16MB PSRAM, panel and audio. --- .../boards/espressif_esp32s3_box_3/board.c | 97 +++++++++++++++++++ .../espressif_esp32s3_box_3/mpconfigboard.h | 10 ++ .../espressif_esp32s3_box_3/mpconfigboard.mk | 14 +++ .../boards/espressif_esp32s3_box_3/pins.c | 61 ++++++++++++ .../boards/espressif_esp32s3_box_3/sdkconfig | 14 +++ 5 files changed, 196 insertions(+) create mode 100644 ports/espressif/boards/espressif_esp32s3_box_3/board.c create mode 100644 ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.h create mode 100644 ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.mk create mode 100644 ports/espressif/boards/espressif_esp32s3_box_3/pins.c create mode 100644 ports/espressif/boards/espressif_esp32s3_box_3/sdkconfig diff --git a/ports/espressif/boards/espressif_esp32s3_box_3/board.c b/ports/espressif/boards/espressif_esp32s3_box_3/board.c new file mode 100644 index 00000000000..20426b4bef4 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_box_3/board.c @@ -0,0 +1,97 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Moises Trovo +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "common-hal/microcontroller/Pin.h" +#include "py/mphal.h" +#include "driver/gpio.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" + +// esp-bsp bsp/esp-box-3/esp-box-3.c vendor_specific_init[], with SWRESET +// prepended and MADCTL set to 0xC8 for CircuitPython's landscape orientation. +// The BSP's own 0x08 is portrait; it also calls +// esp_lcd_panel_mirror(panel, true, true), which CircuitPython folds into +// MADCTL. If the image is ever mirrored or rotated, 0x36 is the knob. +uint8_t display_init_sequence[] = { + 0x01, 0x80, 0x96, // SWRESET, delay 150ms + 0xC8, 0x03, 0xFF, 0x93, 0x42, // vendor unlock + 0xC0, 0x02, 0x0E, 0x0E, // power control + 0xC5, 0x01, 0xD0, // VCOM + 0xC1, 0x01, 0x02, + 0xB4, 0x01, 0x02, + 0xE0, 0x0F, 0x00, 0x03, 0x08, 0x06, 0x13, 0x09, 0x39, 0x39, 0x48, 0x02, 0x0A, 0x08, 0x17, 0x17, 0x0F, // positive gamma + 0xE1, 0x0F, 0x00, 0x28, 0x29, 0x01, 0x0D, 0x03, 0x3F, 0x33, 0x52, 0x04, 0x0F, 0x0E, 0x37, 0x38, 0x0F, // negative gamma + 0xB1, 0x02, 0x00, 0x1B, + 0x36, 0x01, 0xC8, // MADCTL: landscape, BGR + 0x3A, 0x01, 0x55, // COLMOD: 16bpp + 0xB7, 0x01, 0x06, + 0x11, 0x80, 0x78, // SLPOUT, delay 120ms + 0x29, 0x80, 0x78, // DISPON, delay 120ms +}; + +void board_init(void) { + // The panel reset (GPIO48, shared with the touch controller) is ACTIVE + // HIGH. FourWire assumes active low and leaves the pin high, which holds + // this panel in reset forever with no error. So assert it here, release + // it low, and hand FourWire reset = None. + common_hal_never_reset_pin(&pin_GPIO48); + config_pin_as_output_with_level(GPIO_NUM_48, true); + mp_hal_delay_ms(10); + config_pin_as_output_with_level(GPIO_NUM_48, false); + mp_hal_delay_ms(120); + + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO7, &pin_GPIO6, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO4), // LCD_DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // LCD_CS + mp_const_none, // reset managed above, opposite polarity + 40000000, // Baudrate. BSP uses 40MHz; 24MHz is the fallback. + 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 + 240, // Height + 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_GPIO47, // 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 +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.h b/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.h new file mode 100644 index 00000000000..9ded82db172 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Moises Trovo +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-S3-Box-3" +#define MICROPY_HW_MCU_NAME "ESP32S3" diff --git a/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.mk new file mode 100644 index 00000000000..dbbee619732 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_box_3/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x7015 +USB_PRODUCT = "ESP32-S3-Box-3" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 16MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/espressif_esp32s3_box_3/pins.c b/ports/espressif/boards/espressif_esp32s3_box_3/pins.c new file mode 100644 index 00000000000..ce1230f17d5 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_box_3/pins.c @@ -0,0 +1,61 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Moises Trovo +// 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 + + // PMOD connector 1 (dock). IO2/IO6 are the USB D+/D- pair (GPIO20/GPIO19) + // and are not aliased. + { MP_ROM_QSTR(MP_QSTR_G42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_G39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_G40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_G21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_G38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_G41), MP_ROM_PTR(&pin_GPIO41) }, + + // PMOD connector 2 (dock) + { MP_ROM_QSTR(MP_QSTR_G13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_G12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_G44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_G14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_G43), MP_ROM_PTR(&pin_GPIO43) }, + + // LCD & touch + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_CTP_INT), MP_ROM_PTR(&pin_GPIO3) }, + + // Audio + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_I2S_CODEC_DSDIN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ADC_SDOUT), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_PA_CTRL), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_MUTE_STATUS), MP_ROM_PTR(&pin_GPIO1) }, + + // Internal I2C bus (codec, touch, IMU, AHT30) + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO18) }, + + // Dock I2C bus + { MP_ROM_QSTR(MP_QSTR_SCL2), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SDA2), MP_ROM_PTR(&pin_GPIO41) }, + + // Boot button, also usable as a software button + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + + { 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/espressif_esp32s3_box_3/sdkconfig b/ports/espressif/boards/espressif_esp32s3_box_3/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_box_3/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