Skip to content

Commit c6ae68a

Browse files
committed
Init older M5Stack Tab5 display
Fixes #10666
1 parent 15956af commit c6ae68a

File tree

1 file changed

+370
-0
lines changed
  • ports/espressif/boards/m5stack_tab5

1 file changed

+370
-0
lines changed

ports/espressif/boards/m5stack_tab5/board.c

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,375 @@
55
// SPDX-License-Identifier: MIT
66

77
#include "supervisor/board.h"
8+
#include "mpconfigboard.h"
9+
#include "shared-bindings/board/__init__.h"
10+
#include "shared-bindings/busio/I2C.h"
11+
#include "shared-bindings/microcontroller/Pin.h"
12+
#include "shared-bindings/mipidsi/Bus.h"
13+
#include "shared-bindings/mipidsi/Display.h"
14+
#include "shared-module/displayio/__init__.h"
15+
#include "shared-module/framebufferio/__init__.h"
16+
#include "shared-module/framebufferio/FramebufferDisplay.h"
17+
#include "ports/espressif/common-hal/microcontroller/Pin.h"
18+
19+
// Statically allocate the MIPI DSI bus (only one DSI bus on ESP32-P4)
20+
static mipidsi_bus_obj_t board_mipidsi_bus;
21+
22+
// ILI9881C initialization sequence
23+
static const uint8_t ili9881c_init_sequence[] = {
24+
0xff, 0x03, 0x98, 0x81, 0x00,
25+
0x01, 0x80, 0x78, // software reset
26+
// CMD_Page 1
27+
0xff, 0x03, 0x98, 0x81, 0x01,
28+
0xb7, 0x01, 0x03, // set 2 lane
29+
// CMD Page 0
30+
0xff, 0x03, 0x98, 0x81, 0x00,
31+
0x11, 0x80, 0x0a, // out of sleep
32+
0x36, 0x01, 0x00, // madctl
33+
0x3a, 0x01, 0x55, // colmod
34+
// CMD_Page 3
35+
0xff, 0x03, 0x98, 0x81, 0x03,
36+
0x01, 0x01, 0x00,
37+
0x02, 0x01, 0x00,
38+
0x03, 0x01, 0x73,
39+
0x04, 0x01, 0x00,
40+
0x05, 0x01, 0x00,
41+
0x06, 0x01, 0x08,
42+
0x07, 0x01, 0x00,
43+
0x08, 0x01, 0x00,
44+
0x09, 0x01, 0x1b,
45+
0x0a, 0x01, 0x01,
46+
0x0b, 0x01, 0x01,
47+
0x0c, 0x01, 0x0d,
48+
0x0d, 0x01, 0x01,
49+
0x0e, 0x01, 0x01,
50+
0x0f, 0x01, 0x26,
51+
0x10, 0x01, 0x26,
52+
0x11, 0x01, 0x00,
53+
0x12, 0x01, 0x00,
54+
0x13, 0x01, 0x02,
55+
0x14, 0x01, 0x00,
56+
0x15, 0x01, 0x00,
57+
0x16, 0x01, 0x00,
58+
0x17, 0x01, 0x00,
59+
0x18, 0x01, 0x00,
60+
0x19, 0x01, 0x00,
61+
0x1a, 0x01, 0x00,
62+
0x1b, 0x01, 0x00,
63+
0x1c, 0x01, 0x00,
64+
0x1d, 0x01, 0x00,
65+
0x1e, 0x01, 0x40,
66+
0x1f, 0x01, 0x00,
67+
0x20, 0x01, 0x06,
68+
0x21, 0x01, 0x01,
69+
0x22, 0x01, 0x00,
70+
0x23, 0x01, 0x00,
71+
0x24, 0x01, 0x00,
72+
0x25, 0x01, 0x00,
73+
0x26, 0x01, 0x00,
74+
0x27, 0x01, 0x00,
75+
0x28, 0x01, 0x33,
76+
0x29, 0x01, 0x03,
77+
0x2a, 0x01, 0x00,
78+
0x2b, 0x01, 0x00,
79+
0x2c, 0x01, 0x00,
80+
0x2d, 0x01, 0x00,
81+
0x2e, 0x01, 0x00,
82+
0x2f, 0x01, 0x00,
83+
0x30, 0x01, 0x00,
84+
0x31, 0x01, 0x00,
85+
0x32, 0x01, 0x00,
86+
0x33, 0x01, 0x00,
87+
0x34, 0x01, 0x00,
88+
0x35, 0x01, 0x00,
89+
0x36, 0x01, 0x00,
90+
0x37, 0x01, 0x00,
91+
0x38, 0x01, 0x00,
92+
0x39, 0x01, 0x00,
93+
0x3a, 0x01, 0x00,
94+
0x3b, 0x01, 0x00,
95+
0x3c, 0x01, 0x00,
96+
0x3d, 0x01, 0x00,
97+
0x3e, 0x01, 0x00,
98+
0x3f, 0x01, 0x00,
99+
0x40, 0x01, 0x00,
100+
0x41, 0x01, 0x00,
101+
0x42, 0x01, 0x00,
102+
0x43, 0x01, 0x00,
103+
0x44, 0x01, 0x00,
104+
0x50, 0x01, 0x01,
105+
0x51, 0x01, 0x23,
106+
0x52, 0x01, 0x45,
107+
0x53, 0x01, 0x67,
108+
0x54, 0x01, 0x89,
109+
0x55, 0x01, 0xab,
110+
0x56, 0x01, 0x01,
111+
0x57, 0x01, 0x23,
112+
0x58, 0x01, 0x45,
113+
0x59, 0x01, 0x67,
114+
0x5a, 0x01, 0x89,
115+
0x5b, 0x01, 0xab,
116+
0x5c, 0x01, 0xcd,
117+
0x5d, 0x01, 0xef,
118+
0x5e, 0x01, 0x11,
119+
0x5f, 0x01, 0x02,
120+
0x60, 0x01, 0x00,
121+
0x61, 0x01, 0x07,
122+
0x62, 0x01, 0x06,
123+
0x63, 0x01, 0x0e,
124+
0x64, 0x01, 0x0f,
125+
0x65, 0x01, 0x0c,
126+
0x66, 0x01, 0x0d,
127+
0x67, 0x01, 0x02,
128+
0x68, 0x01, 0x02,
129+
0x69, 0x01, 0x02,
130+
0x6a, 0x01, 0x02,
131+
0x6b, 0x01, 0x02,
132+
0x6c, 0x01, 0x02,
133+
0x6d, 0x01, 0x02,
134+
0x6e, 0x01, 0x02,
135+
0x6f, 0x01, 0x02,
136+
0x70, 0x01, 0x02,
137+
0x71, 0x01, 0x02,
138+
0x72, 0x01, 0x02,
139+
0x73, 0x01, 0x05,
140+
0x74, 0x01, 0x01,
141+
0x75, 0x01, 0x02,
142+
0x76, 0x01, 0x00,
143+
0x77, 0x01, 0x07,
144+
0x78, 0x01, 0x06,
145+
0x79, 0x01, 0x0e,
146+
0x7a, 0x01, 0x0f,
147+
0x7b, 0x01, 0x0c,
148+
0x7c, 0x01, 0x0d,
149+
0x7d, 0x01, 0x02,
150+
0x7e, 0x01, 0x02,
151+
0x7f, 0x01, 0x02,
152+
0x80, 0x01, 0x02,
153+
0x81, 0x01, 0x02,
154+
0x82, 0x01, 0x02,
155+
0x83, 0x01, 0x02,
156+
0x84, 0x01, 0x02,
157+
0x85, 0x01, 0x02,
158+
0x86, 0x01, 0x02,
159+
0x87, 0x01, 0x02,
160+
0x88, 0x01, 0x02,
161+
0x89, 0x01, 0x05,
162+
0x8a, 0x01, 0x01,
163+
// CMD_Page 4
164+
0xff, 0x03, 0x98, 0x81, 0x04,
165+
0x38, 0x01, 0x01,
166+
0x39, 0x01, 0x00,
167+
0x6c, 0x01, 0x15,
168+
0x6e, 0x01, 0x1a,
169+
0x6f, 0x01, 0x25,
170+
0x3a, 0x01, 0xa4,
171+
0x8d, 0x01, 0x20,
172+
0x87, 0x01, 0xba,
173+
0x3b, 0x01, 0x98,
174+
// CMD_Page 1
175+
0xff, 0x03, 0x98, 0x81, 0x01,
176+
0x22, 0x01, 0x0a,
177+
0x31, 0x01, 0x00,
178+
0x50, 0x01, 0x6b,
179+
0x51, 0x01, 0x66,
180+
0x53, 0x01, 0x73,
181+
0x55, 0x01, 0x8b,
182+
0x60, 0x01, 0x1b,
183+
0x61, 0x01, 0x01,
184+
0x62, 0x01, 0x0c,
185+
0x63, 0x01, 0x00,
186+
// Gamma P
187+
0xa0, 0x01, 0x00,
188+
0xa1, 0x01, 0x15,
189+
0xa2, 0x01, 0x1f,
190+
0xa3, 0x01, 0x13,
191+
0xa4, 0x01, 0x11,
192+
0xa5, 0x01, 0x21,
193+
0xa6, 0x01, 0x17,
194+
0xa7, 0x01, 0x1b,
195+
0xa8, 0x01, 0x6b,
196+
0xa9, 0x01, 0x1e,
197+
0xaa, 0x01, 0x2b,
198+
0xab, 0x01, 0x5d,
199+
0xac, 0x01, 0x19,
200+
0xad, 0x01, 0x14,
201+
0xae, 0x01, 0x4b,
202+
0xaf, 0x01, 0x1d,
203+
0xb0, 0x01, 0x27,
204+
0xb1, 0x01, 0x49,
205+
0xb2, 0x01, 0x5d,
206+
0xb3, 0x01, 0x39,
207+
// Gamma N
208+
0xc0, 0x01, 0x00,
209+
0xc1, 0x01, 0x01,
210+
0xc2, 0x01, 0x0c,
211+
0xc3, 0x01, 0x11,
212+
0xc4, 0x01, 0x15,
213+
0xc5, 0x01, 0x28,
214+
0xc6, 0x01, 0x1b,
215+
0xc7, 0x01, 0x1c,
216+
0xc8, 0x01, 0x62,
217+
0xc9, 0x01, 0x1c,
218+
0xca, 0x01, 0x29,
219+
0xcb, 0x01, 0x60,
220+
0xcc, 0x01, 0x16,
221+
0xcd, 0x01, 0x17,
222+
0xce, 0x01, 0x4a,
223+
0xcf, 0x01, 0x23,
224+
0xd0, 0x01, 0x24,
225+
0xd1, 0x01, 0x4f,
226+
0xd2, 0x01, 0x5f,
227+
0xd3, 0x01, 0x39,
228+
// CMD_Page 0
229+
0xff, 0x03, 0x98, 0x81, 0x00,
230+
0x35, 0x00,
231+
0xfe, 0x00,
232+
0x29, 0x00,
233+
};
234+
235+
// I2C addresses
236+
#define GOODIX_TOUCH_ADDRESS 0x14
237+
#define ST7123_ADDRESS 0x55
238+
#define I2C_DEV_ADDR_PI4IOE1 0x43
239+
240+
// PI4IOE GPIO expander registers
241+
#define PI4IO_REG_CHIP_RESET 0x01
242+
#define PI4IO_REG_IO_DIR 0x03
243+
#define PI4IO_REG_OUT_SET 0x05
244+
#define PI4IO_REG_OUT_H_IM 0x07
245+
#define PI4IO_REG_PULL_SEL 0x0D
246+
#define PI4IO_REG_PULL_EN 0x0B
247+
248+
void board_init(void) {
249+
// Initialize I2C for GPIO expander and display detection
250+
busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0);
251+
252+
// Initialize PI4IOE GPIO expander to control LCD reset
253+
uint8_t write_buf[2];
254+
255+
common_hal_busio_i2c_try_lock(i2c);
256+
257+
// Chip reset
258+
write_buf[0] = PI4IO_REG_CHIP_RESET;
259+
write_buf[1] = 0xFF;
260+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
261+
262+
// Set IO direction (bit 7 as output for LCD reset)
263+
write_buf[0] = PI4IO_REG_IO_DIR;
264+
write_buf[1] = 0b01111111;
265+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
266+
267+
// Set output high-impedance mode
268+
write_buf[0] = PI4IO_REG_OUT_H_IM;
269+
write_buf[1] = 0b00000000;
270+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
271+
272+
// Set pull select
273+
write_buf[0] = PI4IO_REG_PULL_SEL;
274+
write_buf[1] = 0b01111111;
275+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
276+
277+
// Enable pull resistors
278+
write_buf[0] = PI4IO_REG_PULL_EN;
279+
write_buf[1] = 0b01111111;
280+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
281+
282+
// Set output state (including LCD reset)
283+
write_buf[0] = PI4IO_REG_OUT_SET;
284+
write_buf[1] = 0b01110110;
285+
common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2);
286+
287+
// Small delay for reset to take effect
288+
mp_hal_delay_ms(100);
289+
290+
// Probe I2C bus to detect which display is present
291+
bool has_goodix = common_hal_busio_i2c_probe(i2c, GOODIX_TOUCH_ADDRESS);
292+
bool has_st7123 = common_hal_busio_i2c_probe(i2c, ST7123_ADDRESS);
293+
294+
common_hal_busio_i2c_unlock(i2c);
295+
296+
// Configure display parameters based on detected hardware
297+
uint32_t bus_frequency;
298+
uint32_t pixel_clock_frequency;
299+
const uint8_t *init_sequence;
300+
size_t init_sequence_len;
301+
uint32_t hsync_pulse_width, hsync_back_porch, hsync_front_porch;
302+
uint32_t vsync_pulse_width, vsync_back_porch, vsync_front_porch;
303+
304+
if (has_goodix) {
305+
// ILI9881C display with Goodix touch
306+
bus_frequency = 730000000;
307+
pixel_clock_frequency = 60000000;
308+
init_sequence = ili9881c_init_sequence;
309+
init_sequence_len = sizeof(ili9881c_init_sequence);
310+
hsync_pulse_width = 40;
311+
hsync_back_porch = 140;
312+
hsync_front_porch = 40;
313+
vsync_pulse_width = 4;
314+
vsync_back_porch = 20;
315+
vsync_front_porch = 20;
316+
} else if (has_st7123) {
317+
// ST7123 display
318+
bus_frequency = 965000000;
319+
pixel_clock_frequency = 70000000;
320+
init_sequence = NULL; // ST7123 doesn't use init sequence
321+
init_sequence_len = 0;
322+
hsync_pulse_width = 2;
323+
hsync_back_porch = 40;
324+
hsync_front_porch = 40;
325+
vsync_pulse_width = 2;
326+
vsync_back_porch = 8;
327+
vsync_front_porch = 220;
328+
329+
// Not tested now
330+
return;
331+
} else {
332+
return;
333+
}
334+
335+
// Initialize the statically allocated MIPI DSI bus
336+
board_mipidsi_bus.base.type = &mipidsi_bus_type;
337+
common_hal_mipidsi_bus_construct(&board_mipidsi_bus, bus_frequency, 2); // 2 lanes
338+
339+
// Allocate display bus for the display object
340+
primary_display_bus_t *display_bus_obj = allocate_display_bus_or_raise();
341+
mipidsi_display_obj_t *display = &display_bus_obj->mipidsi;
342+
display->base.type = &mipidsi_display_type;
343+
344+
common_hal_mipidsi_display_construct(
345+
display,
346+
&board_mipidsi_bus, // Use statically allocated bus
347+
init_sequence,
348+
init_sequence_len,
349+
0, // virtual_channel
350+
720, // width
351+
1280, // height
352+
0, // rotation
353+
16, // color_depth
354+
&pin_GPIO22, // backlight_pin (LCD_BL)
355+
0.1f, // brightness
356+
60, // native_frames_per_second
357+
true, // backlight_on_high
358+
hsync_pulse_width,
359+
hsync_back_porch,
360+
hsync_front_porch,
361+
vsync_pulse_width,
362+
vsync_back_porch,
363+
vsync_front_porch,
364+
pixel_clock_frequency
365+
);
366+
367+
// Create framebuffer display
368+
framebufferio_framebufferdisplay_obj_t *fb_display = &allocate_display()->framebuffer_display;
369+
fb_display->base.type = &framebufferio_framebufferdisplay_type;
370+
371+
common_hal_framebufferio_framebufferdisplay_construct(
372+
fb_display,
373+
MP_OBJ_FROM_PTR(display),
374+
0, // rotation
375+
true // auto_refresh
376+
);
377+
}
8378

9379
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

0 commit comments

Comments
 (0)