Skip to content

feat: Add lilygo_t_display_p4 board support#56

Merged
wujiangang merged 13 commits into
espressif:masterfrom
Llgok:master
Jun 3, 2026
Merged

feat: Add lilygo_t_display_p4 board support#56
wujiangang merged 13 commits into
espressif:masterfrom
Llgok:master

Conversation

@Llgok

@Llgok Llgok commented May 8, 2026

Copy link
Copy Markdown
Contributor

Description

Adapt to the new board lilygo_t_display_p4
Refer to the lilygo_t_display_p4 README for usage instructions.

Related

N/A

Testing

Compiled successfully, flashed and tested, everything works properly. Packaged firmware file: [T-Display-P4][edge_agent]_firmware


Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@CLAassistant

CLAassistant commented May 8, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@laride

laride commented May 11, 2026

Copy link
Copy Markdown
Collaborator

sha=fd45798d41c1b8f9e4d133fb0797041fa0853ebc

@laride

laride commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Thank you for your PR! We are currently going through our internal merge process.

@laride laride added dev board support Add support for new dev board PR-Sync-Merge labels May 11, 2026
@Llgok

Llgok commented May 11, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for your PR! We are currently going through our internal merge process.

@laride
Hello, I have a question about adding the audio driver and would like to confirm a possible modification approach.

Currently, the ES8311 audio initialization on lilygo_t_display_p4 does not go through the i2s peripheral defined in board_peripherals.yaml. Instead, I initialize I2S/I2C through a third-party board-level driver on my side, and then expose audio_dac/audio_adc as custom devices in setup_device.cpp.

At the moment, when lua_module_board_manager.c retrieves audio codec parameters, it depends on periph_i2s_config_t by default. This means CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT must be enabled and an I2S peripheral must be configured. However, doing so would cause Board Manager to initialize I2S again, which conflicts with the lilygo_device_driver library.

I would like to modify lua_module_board_manager.c as follows:

  1. Only reference periph_i2s_config_t when CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT is enabled.
  2. When the audio_codec data interface is I2S but i2s_cfg.name == NULL, allow it to use a custom/external initialized codec path.
  3. Return the default sample_rate / channels / bits_per_sample from dev_audio_codec_config_t.

This would allow ES8311 DAC to work with audio.new_output() without using board_peripherals.yaml to initialize I2S.

Would this approach be acceptable, or do you have a better suggestion?

@laride

laride commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Hello, I have a question about adding the audio driver and would like to confirm a possible modification approach.

Currently, the ES8311 audio initialization on lilygo_t_display_p4 does not go through the i2s peripheral defined in board_peripherals.yaml. Instead, I initialize I2S/I2C through a third-party board-level driver on my side, and then expose audio_dac/audio_adc as custom devices in setup_device.cpp.

At the moment, when lua_module_board_manager.c retrieves audio codec parameters, it depends on periph_i2s_config_t by default. This means CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT must be enabled and an I2S peripheral must be configured. However, doing so would cause Board Manager to initialize I2S again, which conflicts with the lilygo_device_driver library.

I would like to modify lua_module_board_manager.c as follows:

1. Only reference `periph_i2s_config_t` when `CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT` is enabled.

2. When the `audio_codec` data interface is I2S but `i2s_cfg.name == NULL`, allow it to use a custom/external initialized codec path.

3. Return the default `sample_rate / channels / bits_per_sample` from `dev_audio_codec_config_t`.

This would allow ES8311 DAC to work with audio.new_output() without using board_peripherals.yaml to initialize I2S.

Would this approach be acceptable, or do you have a better suggestion?

@LiuCodee @TDA-2030 PTAL

I noticed that this PR introduces a new Python file to handle a development board with a different configuration variant. We may need to discuss within this PR how similar scenarios should be handled going forward.

@Llgok

Llgok commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Hello, I have a question about adding the audio driver and would like to confirm a possible modification approach.
Currently, the ES8311 audio initialization on lilygo_t_display_p4 does not go through the i2s peripheral defined in board_peripherals.yaml. Instead, I initialize I2S/I2C through a third-party board-level driver on my side, and then expose audio_dac/audio_adc as custom devices in setup_device.cpp.
At the moment, when lua_module_board_manager.c retrieves audio codec parameters, it depends on periph_i2s_config_t by default. This means CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT must be enabled and an I2S peripheral must be configured. However, doing so would cause Board Manager to initialize I2S again, which conflicts with the lilygo_device_driver library.
I would like to modify lua_module_board_manager.c as follows:

1. Only reference `periph_i2s_config_t` when `CONFIG_ESP_BOARD_PERIPH_I2S_SUPPORT` is enabled.

2. When the `audio_codec` data interface is I2S but `i2s_cfg.name == NULL`, allow it to use a custom/external initialized codec path.

3. Return the default `sample_rate / channels / bits_per_sample` from `dev_audio_codec_config_t`.

This would allow ES8311 DAC to work with audio.new_output() without using board_peripherals.yaml to initialize I2S.
Would this approach be acceptable, or do you have a better suggestion?

@LiuCodee @TDA-2030 PTAL

I noticed that this PR introduces a new Python file to handle a development board with a different configuration variant. We may need to discuss within this PR how similar scenarios should be handled going forward.

@laride
lilygo_t_display_p4/gen_bmgr_config_codes.py is a dedicated wrapper script for the lilygo_t_display_p4 board: it calls the official esp_board_manager/gen_bmgr_config_codes.py to generate board-level code, and then additionally appends lilygo_t_display_p4's own Kconfig.projbuild menu. The gen_bmgr_config_codes script under esp_board_manager is responsible for general YAML parsing and code generation, while my dedicated script only sets default parameters for lilygo_t_display_p4 and supplements the board-specific Kconfig.

@laride

laride commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the clarification. We would prefer to have a more generic solution for this kind of scenario, so that similar cases from other vendors can follow a unified approach and documentation in the future.

In addition, if we customize this Python script for a specific board, it becomes difficult for us to add build coverage for the board in CI. This would also prevent these boards from being integrated into the online flashing workflow.

The Board Manager engineers are currently discussing a suitable long-term solution for handling this type of board-specific customization. Because of that, this PR may need some more time before it can be merged.

@Llgok

Llgok commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

@laride
Thank you for your detailed explanation.

I will patiently wait for the results of your discussion regarding the long-term generic solution. Once you have finalized the unified approach and clarified the required adjustments, please feel free to let me know, and I will modify or update the implementation accordingly based on the new requirements.

@laride

laride commented May 18, 2026

Copy link
Copy Markdown
Collaborator

ESP Board Manager is currently exploring improvements for supporting multiple LCDs and other differentiated peripherals through amend patches. Please refer to the documentation here: EN / 中文.

If you have further questions or suggestions, feel free to discuss them with us.

@Llgok

Llgok commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

Okay, thank you for the explanation. I will notify you once I have made the revisions on my end.

@Llgok

Llgok commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

@laride
Hello, I have made the modifications for the above issues. Please check them.

@laride

laride commented May 21, 2026

Copy link
Copy Markdown
Collaborator

PTAL @LiuCodee @TDA-2030

@LiuCodee

Copy link
Copy Markdown

Hi @Llgok thanks again for the contribution. Splitting power_ctrl / display_lcd / lcd_brightness into separate devices is already a clear improvement over the original one-shot TDisplayP4Driver::Init() approach.

Before we merge, I'd like to discuss the LCD part with you.

Right now display_lcd is declared as type: custom, but it reuses the standard display_lcd name and returns a dev_display_lcd_handles_t*, while the actual MIPI DSI bring-up happens entirely inside the third-party lilygo_device_driver. From Board Manager's point of view, this is an opaque device that just "looks like" a standard display_lcd.

Our suggestion is to keep everything LCD-related (display_lcd / lcd_brightness / multi-LCD auto-detection) on the standard Board Manager path. For the multi-LCD case you can refer to esp32_s3_lcd_ev_board, which also has "panel control lines hanging off an IO expander" — it solves it with a standard display_lcd + gpio_expander device combination, no custom needed.

Before you start refactoring, we'd like to confirm one thing first: are there any current limitations on the Board Manager side that forced you to go with custom? For example, runtime panel auto-detection, a power-on sequence that has to go through XL9535, a backlight path driven via XL9535 / panel registers, or MIPI DSI parameters not being fully expressible in the YAML schema, etc.

If it's a Board Manager capability gap, we'd rather fix it there directly, so future boards with similar hardware can use the standard path. Looking forward to your reply.

@Llgok

Llgok commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

@LiuCodee
The main reason is that the T-Display-P4 board is equipped with two types of screens. If configured through the Board Manager, a single board might require four folders (two screens + T-Display-P4 v1.0 and v2.0) for management — meaning four separate firmwares would need to be generated. Is this configuration approach recommended by Espressif? Additionally, the backlight control methods differ between the two screens: one screen is controlled via PWM, while the other is controlled through internal screen commands. Furthermore, XL9535 power configuration is required before power-on. For convenience, I am currently using lilygo_device_driver to perform a unified initialization. If we need to configure each type separately, I could change it to a four-folder management approach. So, should I modify it to a version that fully uses the Board Manager configuration?

@LiuCodee

Copy link
Copy Markdown

Hi @Llgok , thanks a lot for the detailed explanation. I spent some time reading lilygo_device_driver/src/device/t_display_p4 and want to sync up what we found, hopefully it helps narrow down the blockers.

Looking at t_display_p4_driver.cpp and t_display_p4_config.h, the only real runtime variant within a single firmware is the LCD panel (Hi8561 vs RM69A10). The two screens share the same DSI lane / bit rate / DPI clock; the differences are concentrated in the panel chip, resolution and video timing — all of which can be re-applied at the lcd_dsi_panel_factory_entry_t stage based on the detection result, without wrapping a vendor driver at the board layer.

A concrete reference is m5stack_tab5 in Board Manager v0.5.12 (will be released later today): display_lcd explicitly depends on lcd_touch via the newly added depends_on, lcd_touch probes multiple I2C addresses (i2c_addr: [..., ...]), and the panel factory then picks the right panel driver and overrides the corresponding timing based on the effective address. That gives you runtime detection of the "two LCD + touch combinations" you described.

The XL9535 power-up sequence can also be expressed with the standard gpio_expander. dev_gpio_expander sets the direction and drives the default level for every listed pin during init, so Power_EN_3V3 / Power_EN_5V0 / Screen_RST / Touch_RST / Vcca_EN can all be described entirely in YAML:

- name: gpio_expander_xl9535
  chip: xl9535
  type: gpio_expander
  config:
    max_pins: 18
    output_io_mask:        [0, 2, 3, 6, 10]
    output_io_level_mask:  [1, 1, 1, 1, 1]
  peripherals:
    - name: i2c_port0
      i2c_addr: [0x20]
  dependencies:
    espressif/esp_io_expander_xl9535: "*"

Then display_lcd / lcd_touch / lcd_brightness all declare depends_on: gpio_expander_xl9535, and Board Manager guarantees the expander is initialized and the pin levels are driven before any of those devices run.

For backlight, Board Manager currently only has the ledc_ctrl type, so the Hi8561 path can use it directly. For the RM69A10 AMOLED brightness, a reasonable interim approach is the standard ESP-IDF esp_lcd_panel_set_brightness() (provided the panel driver registers a set_brightness callback — see esp_lcd_panel_st7789.c as a reference). I'm not entirely sure how this should be wired into esp-claw's upper layer though, so that part needs a call from your side. On our end, we'll evaluate adding a dedicated dev_lcd_brightness device type in bmgr that unifies the ledc path and a panel path (forwarding to the standard API).

Would you be open to refactoring along the m5stack_tab5 (v0.5.12) pattern? If you hit anything the current bmgr abstraction can't express along the way, please let us know — that input is very valuable for us to improve bmgr. Happy to review intermediate versions as well. Thanks again for your patience!

@Llgok

Llgok commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

@LiuCodee
Thank you for your review. I'm happy to refactor according to the m5stack_tab5 (v0.5.12) pattern. Please give me a moment, and I will modify my code and submit it again.

@Llgok

Llgok commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

@LiuCodee
Hello, I have already made modifications according to the ESP Board Manager v0.5.12 version. Could you please check if it's okay now?

@LiuCodee

Copy link
Copy Markdown

Hi @Llgok , thanks for the substantial refactor!

One note: the Hi8561 touch case (raw i2c_master_dev_handle_t instead of esp_lcd_panel_io_i2c) does look like something the current dev_lcd_touch abstraction can't cover — for now the esp_board_device_set_ops() override seems to be the only viable workaround. We'll look into extending Board Manager to support this kind of touch natively in a future release. Thanks for surfacing this — it's a very valuable data point for us.

Minor non-blocking suggestion: esp_lcd_rm69a10.c exposes a standalone esp_lcd_panel_rm69a10_set_brightness() but doesn't wire it into the panel vtable's set_brightness callback (see esp_lcd_panel_st7789.c for reference). Registering it there would make the standard esp_lcd_panel_set_brightness() API work for RM69A10 too, so once Board Manager grows a generic brightness device that forwards to the standard API, this board would benefit without any further changes.

From the Board Manager side I don't see anything else worth blocking on in this version. Deferring the final merge decision to the esp-claw maintainers.

@Llgok

Llgok commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

@LiuCodee
Hello, I have already modified the esp_lcd_hi8561 and esp_lcd_rm69a10 parts as required, following the approach used in esp_lcd_st7789.

@laride

laride commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

sha=5006ff71ff394c53ad544c251081887b6f030881

@laride

laride commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

sha=4a1ec98076fe9bcc6da09506ff0c6a54dc5d1117

@wujiangang wujiangang merged commit 4a1ec98 into espressif:master Jun 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants