Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
370 changes: 370 additions & 0 deletions ports/espressif/boards/m5stack_tab5/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,375 @@
// SPDX-License-Identifier: MIT

#include "supervisor/board.h"
#include "mpconfigboard.h"
#include "shared-bindings/board/__init__.h"
#include "shared-bindings/busio/I2C.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/mipidsi/Bus.h"
#include "shared-bindings/mipidsi/Display.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/framebufferio/__init__.h"
#include "shared-module/framebufferio/FramebufferDisplay.h"
#include "ports/espressif/common-hal/microcontroller/Pin.h"

// Statically allocate the MIPI DSI bus (only one DSI bus on ESP32-P4)
static mipidsi_bus_obj_t board_mipidsi_bus;

// ILI9881C initialization sequence
static const uint8_t ili9881c_init_sequence[] = {
0xff, 0x03, 0x98, 0x81, 0x00,
0x01, 0x80, 0x78, // software reset
// CMD_Page 1
0xff, 0x03, 0x98, 0x81, 0x01,
0xb7, 0x01, 0x03, // set 2 lane
// CMD Page 0
0xff, 0x03, 0x98, 0x81, 0x00,
0x11, 0x80, 0x0a, // out of sleep
0x36, 0x01, 0x00, // madctl
0x3a, 0x01, 0x55, // colmod
// CMD_Page 3
0xff, 0x03, 0x98, 0x81, 0x03,
0x01, 0x01, 0x00,
0x02, 0x01, 0x00,
0x03, 0x01, 0x73,
0x04, 0x01, 0x00,
0x05, 0x01, 0x00,
0x06, 0x01, 0x08,
0x07, 0x01, 0x00,
0x08, 0x01, 0x00,
0x09, 0x01, 0x1b,
0x0a, 0x01, 0x01,
0x0b, 0x01, 0x01,
0x0c, 0x01, 0x0d,
0x0d, 0x01, 0x01,
0x0e, 0x01, 0x01,
0x0f, 0x01, 0x26,
0x10, 0x01, 0x26,
0x11, 0x01, 0x00,
0x12, 0x01, 0x00,
0x13, 0x01, 0x02,
0x14, 0x01, 0x00,
0x15, 0x01, 0x00,
0x16, 0x01, 0x00,
0x17, 0x01, 0x00,
0x18, 0x01, 0x00,
0x19, 0x01, 0x00,
0x1a, 0x01, 0x00,
0x1b, 0x01, 0x00,
0x1c, 0x01, 0x00,
0x1d, 0x01, 0x00,
0x1e, 0x01, 0x40,
0x1f, 0x01, 0x00,
0x20, 0x01, 0x06,
0x21, 0x01, 0x01,
0x22, 0x01, 0x00,
0x23, 0x01, 0x00,
0x24, 0x01, 0x00,
0x25, 0x01, 0x00,
0x26, 0x01, 0x00,
0x27, 0x01, 0x00,
0x28, 0x01, 0x33,
0x29, 0x01, 0x03,
0x2a, 0x01, 0x00,
0x2b, 0x01, 0x00,
0x2c, 0x01, 0x00,
0x2d, 0x01, 0x00,
0x2e, 0x01, 0x00,
0x2f, 0x01, 0x00,
0x30, 0x01, 0x00,
0x31, 0x01, 0x00,
0x32, 0x01, 0x00,
0x33, 0x01, 0x00,
0x34, 0x01, 0x00,
0x35, 0x01, 0x00,
0x36, 0x01, 0x00,
0x37, 0x01, 0x00,
0x38, 0x01, 0x00,
0x39, 0x01, 0x00,
0x3a, 0x01, 0x00,
0x3b, 0x01, 0x00,
0x3c, 0x01, 0x00,
0x3d, 0x01, 0x00,
0x3e, 0x01, 0x00,
0x3f, 0x01, 0x00,
0x40, 0x01, 0x00,
0x41, 0x01, 0x00,
0x42, 0x01, 0x00,
0x43, 0x01, 0x00,
0x44, 0x01, 0x00,
0x50, 0x01, 0x01,
0x51, 0x01, 0x23,
0x52, 0x01, 0x45,
0x53, 0x01, 0x67,
0x54, 0x01, 0x89,
0x55, 0x01, 0xab,
0x56, 0x01, 0x01,
0x57, 0x01, 0x23,
0x58, 0x01, 0x45,
0x59, 0x01, 0x67,
0x5a, 0x01, 0x89,
0x5b, 0x01, 0xab,
0x5c, 0x01, 0xcd,
0x5d, 0x01, 0xef,
0x5e, 0x01, 0x11,
0x5f, 0x01, 0x02,
0x60, 0x01, 0x00,
0x61, 0x01, 0x07,
0x62, 0x01, 0x06,
0x63, 0x01, 0x0e,
0x64, 0x01, 0x0f,
0x65, 0x01, 0x0c,
0x66, 0x01, 0x0d,
0x67, 0x01, 0x02,
0x68, 0x01, 0x02,
0x69, 0x01, 0x02,
0x6a, 0x01, 0x02,
0x6b, 0x01, 0x02,
0x6c, 0x01, 0x02,
0x6d, 0x01, 0x02,
0x6e, 0x01, 0x02,
0x6f, 0x01, 0x02,
0x70, 0x01, 0x02,
0x71, 0x01, 0x02,
0x72, 0x01, 0x02,
0x73, 0x01, 0x05,
0x74, 0x01, 0x01,
0x75, 0x01, 0x02,
0x76, 0x01, 0x00,
0x77, 0x01, 0x07,
0x78, 0x01, 0x06,
0x79, 0x01, 0x0e,
0x7a, 0x01, 0x0f,
0x7b, 0x01, 0x0c,
0x7c, 0x01, 0x0d,
0x7d, 0x01, 0x02,
0x7e, 0x01, 0x02,
0x7f, 0x01, 0x02,
0x80, 0x01, 0x02,
0x81, 0x01, 0x02,
0x82, 0x01, 0x02,
0x83, 0x01, 0x02,
0x84, 0x01, 0x02,
0x85, 0x01, 0x02,
0x86, 0x01, 0x02,
0x87, 0x01, 0x02,
0x88, 0x01, 0x02,
0x89, 0x01, 0x05,
0x8a, 0x01, 0x01,
// CMD_Page 4
0xff, 0x03, 0x98, 0x81, 0x04,
0x38, 0x01, 0x01,
0x39, 0x01, 0x00,
0x6c, 0x01, 0x15,
0x6e, 0x01, 0x1a,
0x6f, 0x01, 0x25,
0x3a, 0x01, 0xa4,
0x8d, 0x01, 0x20,
0x87, 0x01, 0xba,
0x3b, 0x01, 0x98,
// CMD_Page 1
0xff, 0x03, 0x98, 0x81, 0x01,
0x22, 0x01, 0x0a,
0x31, 0x01, 0x00,
0x50, 0x01, 0x6b,
0x51, 0x01, 0x66,
0x53, 0x01, 0x73,
0x55, 0x01, 0x8b,
0x60, 0x01, 0x1b,
0x61, 0x01, 0x01,
0x62, 0x01, 0x0c,
0x63, 0x01, 0x00,
// Gamma P
0xa0, 0x01, 0x00,
0xa1, 0x01, 0x15,
0xa2, 0x01, 0x1f,
0xa3, 0x01, 0x13,
0xa4, 0x01, 0x11,
0xa5, 0x01, 0x21,
0xa6, 0x01, 0x17,
0xa7, 0x01, 0x1b,
0xa8, 0x01, 0x6b,
0xa9, 0x01, 0x1e,
0xaa, 0x01, 0x2b,
0xab, 0x01, 0x5d,
0xac, 0x01, 0x19,
0xad, 0x01, 0x14,
0xae, 0x01, 0x4b,
0xaf, 0x01, 0x1d,
0xb0, 0x01, 0x27,
0xb1, 0x01, 0x49,
0xb2, 0x01, 0x5d,
0xb3, 0x01, 0x39,
// Gamma N
0xc0, 0x01, 0x00,
0xc1, 0x01, 0x01,
0xc2, 0x01, 0x0c,
0xc3, 0x01, 0x11,
0xc4, 0x01, 0x15,
0xc5, 0x01, 0x28,
0xc6, 0x01, 0x1b,
0xc7, 0x01, 0x1c,
0xc8, 0x01, 0x62,
0xc9, 0x01, 0x1c,
0xca, 0x01, 0x29,
0xcb, 0x01, 0x60,
0xcc, 0x01, 0x16,
0xcd, 0x01, 0x17,
0xce, 0x01, 0x4a,
0xcf, 0x01, 0x23,
0xd0, 0x01, 0x24,
0xd1, 0x01, 0x4f,
0xd2, 0x01, 0x5f,
0xd3, 0x01, 0x39,
// CMD_Page 0
0xff, 0x03, 0x98, 0x81, 0x00,
0x35, 0x00,
0xfe, 0x00,
0x29, 0x00,
};

// I2C addresses
#define GOODIX_TOUCH_ADDRESS 0x14
#define ST7123_ADDRESS 0x55
#define I2C_DEV_ADDR_PI4IOE1 0x43

// PI4IOE GPIO expander registers
#define PI4IO_REG_CHIP_RESET 0x01
#define PI4IO_REG_IO_DIR 0x03
#define PI4IO_REG_OUT_SET 0x05
#define PI4IO_REG_OUT_H_IM 0x07
#define PI4IO_REG_PULL_SEL 0x0D
#define PI4IO_REG_PULL_EN 0x0B

void board_init(void) {
// Initialize I2C for GPIO expander and display detection
busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0);

// Initialize PI4IOE GPIO expander to control LCD reset
uint8_t write_buf[2];

common_hal_busio_i2c_try_lock(i2c);

// Chip reset
write_buf[0] = PI4IO_REG_CHIP_RESET;
write_buf[1] = 0xFF;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Set IO direction (bit 7 as output for LCD reset)
write_buf[0] = PI4IO_REG_IO_DIR;
write_buf[1] = 0b01111111;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Set output high-impedance mode
write_buf[0] = PI4IO_REG_OUT_H_IM;
write_buf[1] = 0b00000000;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Set pull select
write_buf[0] = PI4IO_REG_PULL_SEL;
write_buf[1] = 0b01111111;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Enable pull resistors
write_buf[0] = PI4IO_REG_PULL_EN;
write_buf[1] = 0b01111111;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Set output state (including LCD reset)
write_buf[0] = PI4IO_REG_OUT_SET;
write_buf[1] = 0b01110110;
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);

// Small delay for reset to take effect
mp_hal_delay_ms(100);

// Probe I2C bus to detect which display is present
bool has_goodix = common_hal_busio_i2c_probe(i2c, GOODIX_TOUCH_ADDRESS);
bool has_st7123 = common_hal_busio_i2c_probe(i2c, ST7123_ADDRESS);

common_hal_busio_i2c_unlock(i2c);

// Configure display parameters based on detected hardware
uint32_t bus_frequency;
uint32_t pixel_clock_frequency;
const uint8_t *init_sequence;
size_t init_sequence_len;
uint32_t hsync_pulse_width, hsync_back_porch, hsync_front_porch;
uint32_t vsync_pulse_width, vsync_back_porch, vsync_front_porch;

if (has_goodix) {
// ILI9881C display with Goodix touch
bus_frequency = 730000000;
pixel_clock_frequency = 60000000;
init_sequence = ili9881c_init_sequence;
init_sequence_len = sizeof(ili9881c_init_sequence);
hsync_pulse_width = 40;
hsync_back_porch = 140;
hsync_front_porch = 40;
vsync_pulse_width = 4;
vsync_back_porch = 20;
vsync_front_porch = 20;
} else if (has_st7123) {
// ST7123 display
bus_frequency = 965000000;
pixel_clock_frequency = 70000000;
init_sequence = NULL; // ST7123 doesn't use init sequence
init_sequence_len = 0;
hsync_pulse_width = 2;
hsync_back_porch = 40;
hsync_front_porch = 40;
vsync_pulse_width = 2;
vsync_back_porch = 8;
vsync_front_porch = 220;

// Not tested now
return;
} else {
return;
}

// Initialize the statically allocated MIPI DSI bus
board_mipidsi_bus.base.type = &mipidsi_bus_type;
common_hal_mipidsi_bus_construct(&board_mipidsi_bus, bus_frequency, 2); // 2 lanes

// Allocate display bus for the display object
primary_display_bus_t *display_bus_obj = allocate_display_bus_or_raise();
mipidsi_display_obj_t *display = &display_bus_obj->mipidsi;
display->base.type = &mipidsi_display_type;

common_hal_mipidsi_display_construct(
display,
&board_mipidsi_bus, // Use statically allocated bus
init_sequence,
init_sequence_len,
0, // virtual_channel
720, // width
1280, // height
0, // rotation
16, // color_depth
&pin_GPIO22, // backlight_pin (LCD_BL)
0.1f, // brightness
60, // native_frames_per_second
true, // backlight_on_high
hsync_pulse_width,
hsync_back_porch,
hsync_front_porch,
vsync_pulse_width,
vsync_back_porch,
vsync_front_porch,
pixel_clock_frequency
);

// Create framebuffer display
framebufferio_framebufferdisplay_obj_t *fb_display = &allocate_display()->framebuffer_display;
fb_display->base.type = &framebufferio_framebufferdisplay_type;

common_hal_framebufferio_framebufferdisplay_construct(
fb_display,
MP_OBJ_FROM_PTR(display),
0, // rotation
true // auto_refresh
);
}

// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
4 changes: 4 additions & 0 deletions ports/espressif/boards/m5stack_tab5/pins.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#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

Expand Down Expand Up @@ -124,5 +126,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = {
{ 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)}
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);