Driving tall LCD (720x1280) with DPI peripheral

fcipaq
Posts: 13
Joined: Fri May 31, 2024 7:02 pm

Driving tall LCD (720x1280) with DPI peripheral

Postby fcipaq » Wed Mar 11, 2026 8:54 pm

Hi,

I designed a small PCB around an ESP32-P4 to which I want to attach a 720x1280 parallel (DPI/RGB) LCD. However, I had to find out that the maximum vertical resolution is 1024 (since the register LCD_CAM_LCD_VT_HEIGHT is 10 bits wide) minus the sync overhead. Now, I have been poking in the LCD driver and I thought, maybe it's possible to scan out the buffer in two halves:
First half would have a vertical front porch but no back porch, and no vsync pulse. Then, once the scanout is complete and the ISR is called, the vertical timing could be updated to have no front porch, but a regular back porch and vsync pulse using lcd_ll_set_vertical_timing. This means from the LCD peripheral's perspective, it's actually scanning out two 640-pixel-tall screens. I'm a little worried about timing though. Running an ISR midframe in time might be challenging.
Does that make any sense?

Thanks for any input.

P.S.: I've already confirmed that the display is quite happy with the max. bandwidth of 40 MHz - it's running at 40ish fps.

fcipaq
Posts: 13
Joined: Fri May 31, 2024 7:02 pm

Re: Driving tall LCD (720x1280) with DPI peripheral

Postby fcipaq » Sun Mar 22, 2026 2:52 pm

In answer to my own question: It is possible, but there are some major caveats.

Espressif's chpi designers made LCD_CAM_LCD_HT_WIDTH 12 bits wide and LCD_CAM_LCD_VT_HEIGHT 10 bits wide. This leaves you with a theoretical maximum resolution of 4096 x 1024. I don't know why they didn't go with 2048 x 2048, but they must have had their reasons. It's possible to scan out only a portion of the height. For example, you can scan out half of it, which is 640 pixels in my case. In the ISR, you can reprogram the vertical timing in the following way: The first half of the screen has a sync pulse and a back porch, but no front porch. The second half has only the front porch enabled. However, servicing LCD_CAM_LCD_VSYNC_INT is too late because the interrupt occurs after VSYNC is complete. You definitely want to prevent that for the first half of the frame. You can wait for LCD_CAM_LCD_TRANS_DONE_INT, which I believe occurs after all active pixels have been scanned out, but before the blanking regions. Unfortunately, I find the documentation ambiguous.
LCD_CAM_LCD_VSYNC_WIDTH is the width of the VSYNC pulse, plus one, since probably engineers expected that enabling blanking would require at least one line of the sync pulse. Unfortunately, LCD_CAM_LCD_BK_EN enables/disables both vertical and horizontal blanking simultaneously, so horizontal syncing requires vertical syncing to be enabled, too.

What I'm trying to say: No matter how hard you try, after the first part of the frame, at least one line of short vertical syncing will occur. My displays ignored these and did not restart the scanout, but this leaves a visual artifact: a dark line at the position where you restart the scanout (see pictures).
For my project, that's a deal breaker. There is also horizontal and vertical image shifting, which can likely be controlled.

This is just in case someone stumbles across a similar situation.

P.S.: The dev board in the picture is a S3, but all of the register lengths above are taken from the P4's technical reference, so this limitation applies to the P4, too.
Attachments
IMG_5942.jpeg
IMG_5942.jpeg (2.39 MiB) Viewed 135 times
IMG_5941.jpeg
IMG_5941.jpeg (1.66 MiB) Viewed 135 times

fcipaq
Posts: 13
Joined: Fri May 31, 2024 7:02 pm

Re: Driving tall LCD (720x1280) with DPI peripheral

Postby fcipaq » Sat Apr 04, 2026 8:50 pm

Hi, it's me again :)

Turns out I was wrong and it can be done after all!
In fact, when midframe, you must not wait for an IRQ from the RGB state machine but instead rely on the callback from the DMA when the transfer completes. This way, you can interrupt the state machine just in time. However, since you can't disable the back porch, at least a single sync line will still be transmitted. However, when using DE mode, my display does not interpret this as a vsync event and continues the transmission happily. Regarding the pixel clock's frequency, it's really pushing the limits of what the machine can do. Fortunately, the image won't flicker.
If anyone is interested, let me know and I can upload the code. It's a hacky solution, though, and I have no intention (nor do I have the time) of changing that since it's for a single purpose.
And there you have: I've attached a picture of the ESP32-S3 driving a resolution of 720x1280.
golden.jpg
golden.jpg (542.11 KiB) Viewed 55 times
Take care!

Who is online

Users browsing this forum: akashgaur0001, Baidu [Spider] and 5 guests