-
Notifications
You must be signed in to change notification settings - Fork 352
Introduce RGB/DPI driver #2415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce RGB/DPI driver #2415
Conversation
Georges760
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see this PR, I was considering working on this need.
|
I've tested this on a 7" with an EK9716 display controller, and it appears to be working. Board used: https://www.aliexpress.com/item/1005005560920555.html I've not done any kind of exhaustive tests - just run the lcd_dpi.rs from the example directories (with pins modified for the above board). The example code results in the screen going through various colors. On my device, it appears to flicker fairly intensely. Changing the clock to 40 & 50 Mhz seems to help with the flicker a bit. Using 33 Mhz results in interesting artifacts on 2/3 of the display. In any case, this MR has my vote! Getting this into main would be a tremendous step forward! |
Curious, in addition to the pins, did you also update the frame timings? |
|
please forgive the horrible video and my silly commentary (also, apologies for using YouTube) - https://www.youtube.com/shorts/tHPwoWvb11o Also, I had to turn on the backlight to actually see the screen. The flicker could be from the backlight, or not using ledc to dim it... or, or or ... I confess, I'm so new to rust, I'm still fighting with the borrow checker, but I am excited as can be to get this working! |
I suppose it can't be helped for this example since every single frame is a different color. Trying to see it on video was a lost cause to begin with haha. Would need a different example, one that alternates between two colors once a second.
This is where I need to write some documentation.
I'm glad this helped! Just to be sure about the flickering, try changing the example to only draw on color and see if it still flickers. dpi.send(false, dma_buf).map_err(|e| e.0).unwrap();to this dpi.send(true, dma_buf).map_err(|e| e.0).unwrap(); |
|
I can add to the review that I've tried this on the 4.3" cheap yellow board, at 800x480, and it looks wonderful. The 4.3" uses a ST7262. The "flicker" i'd reported is definitely not flicker, but the backlight being a bit over-powered. |
590b5fa to
e4a9fa8
Compare
e4a9fa8 to
f7c9e3f
Compare
|
@MabezDev as requested, the example now runs on the official devkit. |
MabezDev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for porting the example to the official devkit ❤️, unfortunately the devkit we have in the office is an older rev and the example isn't working.
I think we can still merge this as is for now, given that you have it tested, and we'll get a new rev of the board for testing later down the line.
jessebraham
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with the comment regarding #[non_exhaustive] on the Config struct, but otherwise changes LGTM I think
MabezDev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
|
@Dominaezzz I can't find the example any longer in the latest examples folder, did it move?
@jgtaylor I also want to use ST7262, does the example work as is or did it require any changes? |
|
It was moved. https://github.com/esp-rs/esp-hal/blob/main/qa-test/src/bin/lcd_dpi.rs Also, note that I changed the example after jgtaylor's comment. So you'll need to update the |
I just remembered, the CPU load could be minimised by using DMA memcpy. It'll need some tuning to get right. |
By 'bounce buffers' do you mean to render using slint at real time as the display is being fed with data using a small memory area of only several lines? |
Bounce buffers work for both. The former would be ideal but I'm not sure if Slint will actually draw the screen fast enough to keep up with the LCD_CAM. Maybe with a bit of a head start it could work. Code execution will impact the DMA from PSRAM to internal RAM, but if the bounce buffer is large enough, any slow downs should be absorbed by the buffer. I did get this to work with on the idf side, so it's certainly feasible. esp-hal is currently not exposing the DMA interrupts yet so you'll need the PAC to do this rn. |
Oh boy, that sounds complex... |
|
It is complex indeed.
@ MabezDev is the team lead, he's the one that needs convincing. |
|
I've been working on trying to implement a My latest effort has been to look into how it's done in the Sadly, unless I become a Rust expert very soon (improbable), I will merely continue to bang my head on my keyboard as I very, very, slowly get good 😀 |
Given the tremendous amount of work we have ahead of us trying to get a stable release out, I would not get your hopes up. This is completely outside the scope of our current focus. Will probably be faster for you to implement it yourself and submit a PR. |
|
@jessebraham thanks for the update and setting expectations.
I wish I knew how to implement something like this. #2083 looks like way beyond my understanding of esp32. I'm more on the application programming side.
Can we ask for it to be considered for next release then? As I stated on the issue, it opens up large set of applications that are currently blocked from esp-hal. I think there's a strong justification for implementing it. |
|
The esp-idf code snippet that bjeorn posted looks like it would do the trick. |
When we have published the Right now, we need to focus on creating a product that paying customers are able to use so that we can continue to justify an entire team of engineers being paid to work on this project. We have been discussing and planning this release for months already, so we need to focus on the scope of work which we have already committed to. Realistically, our current plans will likely take us until late spring or early summer to complete. The community is welcome to contribute unstable drivers in the meantime and we will of course be happy to review them. |
|
Great to hear 1.0.0 is on the horizon! I wasn't aware of that. Speaking of paying customers, I believe there's a significant commercial opportunity in GUI based embedded systems, and with Slint available (looks like they are building their revenue stream mostly around that) Rust seems to have the potential to become the easiest language for developing such applications. Anyway, I'll try sometime soon to take a stab at implementing this myself, maybe I'll be able to get something working. Thanks! |
|
@Dominaezzz @yanshay Hi guys! I figured our how to get full draw on 480x480 display with Rust no_std using |
|
Nice! Glad you were able to get DMA from PSRAM to keep up with the LCD_CAM. I'm a little surprised that the LCD pixels don't significantly discharge whilst the frame buffer is being prepared, perhaps I underestimate how fast the game update is. For what you're doing, game of life, you'd probably be able to fit the entire frame buffer in internal RAM using a technique like #2238 . |
|
@Dominaezzz @yanshay I've got no_std Slint working for 480x480 version: Code requires some polish, plus touch support. Yet, it's drawing :-) |
That's great! What board is it exactly and what display does it use? I have some 800x480 device, would this code work as is assuming it's the same display interface and just draw on part of the screen? |
|
Touch is now working with FT5x06. @yanshay 480x480 (GC9503CV) sub board is different from 800x480 (ST7262E43). 800x480 does not require that display initialization dance. RGB interface should be the same. According to ESP-BSP it should be simpler to get it running. |
|
I tried to get something working with the device I have (800x480). Just sending data to screen w/o slint for now. IMG_8827-2.movOne thing that seemed strange to me, this is the FrameTiming I had to use to get the original example to work well. |
|
Those black dots is caused by bandwidth issues, the DMA isn't able to keep up when using psram. To fix/mitigate this, make sure psram is running at max speed, drop the DPI frequency to make it less demanding and increase the blank porches as much as you can. This will buy the DMA enough time to access psram. No that 830 doesn't make sense, there's a good chance you haven't specified the porches correctly. |
I know in the past it was possible to control the psram max speed (I actually added that), but later I remember esp-hal chose the high speed by default per chip type and I can't find an option to configure it. Is it available somewhere? The PSRAM seems to me to be Octal (because with Quad it's even worse). Maybe I can modify the code to take advantage of that to get higher speed that isn't utilized with current code? I tried everything you recommended and to me it seems that it's indeed the PSRAM throughput but I can't find how to improve on that and I'm sure it's possible because it is a common device used by other c++ applications w/o issues, and there's not enough memory to do that with only standard RAM.
I tried reducing frequency (using the original example that's working well). It worked inconsistently at lower speed.
Aren't the blank porches at end of line? So if I see black dots on the same line it won't help?
The thing is that with 800, the right column pixel is flashing and not stable (in the original example that work, unrelated to PSRAM). Maybe it's because the display is shifted left for some reason due to configuration. If I use 801 its already showing good. I couldn't eliminate it and seems like data is missing for the last pixel. Maybe a dma configuration issue of missing one byte?
This is what I have from the datasheet: This how I mapped to code: Most values don't have any meaningful effect, except |
I'm not sure
If it's octal and running at 80MHz, then it's at max speed (probably).
Yeah, which is why I'm kinda surprised that it worked for @georgik
At the end and at the start. During this time while the LCD_CAM isn't drawing pixels, the DMA can fill up its channel buffer from PSRAM.
Yes, shifting happens when the DMA can't keep up and the LCD_CAM marches onward with black pixels. This makes then out of sync.
Max out all the blanking periods like this. config.timing = FrameTiming {
horizontal_active_width: 800,
horizontal_total_width: 800 + 48 + 48 + 8,
horizontal_blank_front_porch: 48 + 8,
vertical_active_height: 480,
vertical_total_height: 480 + 12 + 12 + 8,
vertical_blank_front_porch: 12 + 8,
hsync_width: 8
vsync_width: 8,
hsync_position: 0, // This should almost always be 0
};If this doesn't work then I'm out of easy ideas. |
|
Thanks, that config didn't work. I found the psramconfig struct has some settings: I guess the only relevant one is the
Do you mean to say that direct from PSRAM to RGB isn't supposed to work? |
No, I'm saying esp-hal is missing features to make it work reliably. |
Is it #2083 ? Or something in addition to that? |
|
There's more stuff. Take a look at these
There are lots of little things that can be done to improve it. |
|
I just tried #2083 and it didn't help. It is so unfortunate that |
|
@yanshay Do you happen to have the code with blue screen public? I've finally got 800x480 board for testing. |
The If you want, I could also push the repo to GitHub. Please let me know how it goes. My board is BTW @Dominaezzz - I've been thinking, would it be possible to use a fast SDCard instead of the PSRAM? |
|
(I never thought this PR's comment section would extend this long. At some point this topic should go into a discussion) SD Card -> DPI, is theoretically possible, you'll just need to juggle the DMA descriptors accordingly. SD Cards can't do read/write at the same time so I think you'll largely be stuck with read only workflows, unless you're fine with putting in some loading screens 😄 I can't speak on SD Card wear, but I'm not optimistic from the rumors I've heard. I suppose you could always acquire a high quality one. SD Card in SPI mode won't be fast enough for the display. 25MHz (at 1 bit per cycle) won't keep up with the 16MHz (at 16 bits per cycle) needed for the display. There's also the optional of getting an external ram chip, separate from the built in one but I've never looked into this. It would not conflict with flash as it's a different bus. |



Thank you for your contribution!
We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:
Submission Checklist 📝
cargo xtask fmt-packagescommand to ensure that all changed code is formatted correctly.CHANGELOG.mdin the proper section.Extra:
Pull Request Details 📖
Description
Add a driver for the RGB mode of the LCD_CAM peripheral. Closes #2081.
I've called it
DpisinceRgbis a generic name (though I don't mind renaming it if anyone insists). TheI8080driver has similar opinionated name.I've opened this early as a formal request for one of the maintainers to acquire a devkit that can run the example.Makerfabs MaTouch_ESP32-S3 Parallel TFT with Touch 4.3"
(I tried using the espressif devkit linked in the issue but the initialization code is buried deep in esp-bsp and it would complicate the example with bitbanging SPI over an I2C gpio expander)The example runs on the official espressif devkit ESP32-S3-LCD-EV-Board.
Testing
HIL test and example