-
Notifications
You must be signed in to change notification settings - Fork 57
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
Write bitmap regions of screen from buffer (LVGL) #35
Comments
I briefly went over it but I am not exactly sure what to make of this. That out of the way, my EVE_memWrite_sram_buffer() is not using DMA but direct transfers since it is not meant to be used repeatedly but rather during init or to update assets. void EVE_start_dma_transfer(void) And there is this to end the transfer: static void eve_spi_post_transfer_callback(void) This is the ESP-IDF code I implemented for ESP32-Arduino. Something like this might work: void EVE_push_dma_buffer(uint32_t ftAddress, const uint8_t EVE_dma_buffer, uint32_t length) Of course this needs a basic display list first to actually display a memory region as image. And I just noticed that with the lvgl port the CS pin is handled automatically with no callback. The main difference is that with display lists a buffer with a maximum size of 4k needs to get pushed out once every 17ms or more, I usually implement 20ms. Since I am mixing transfers modes, DMA for the buffer, non DMA for small reads to check touch for example, |
Hi, thank your your clear explanation. Nick |
No, CS can not be left high, this is the reset for the state machine of any SPI device and in case of the EVE chips the first three bytes after the CS to low transition are always the address to write to. |
Hi Rudolph,
I get this error: However the display is turned on, displaying a white/gray background and that's it.
This is the callback function and the altered TFT_WriteBitmap
I can see TFT_WriteBitmap is called once to draw 800 pixel width and 6 pixels height. Do you have any idea on what is going wrong? |
EVE_LVGL_Test_ESP32_PlatformIO.zip Here you have the whole package built from your latest master source and Arduino example, which worked before modifications. |
I just wanted to comment briefly here as the person who did the ESP32 SPI DMA port for LVGL (and much of the DMA rework in LVGL for the ESP32), at one point this was working quite well (in the FTxx bitmap mode it uses to work with LVGL). I was getting 12-14 FPS for full screen refreshes using DMA Quad SPI. But I have been away from that project for quite some time and they historically have a habit of breaking things since I don't think they test on all supported boards, etc... They did a big reorg a while back that I was not involved with. Unfortunately, I don't think I will have to time to revisit it anytime soon but I just wanted to point out that yes, it did work and was quite stable and running at the full speed of the DMA bus (and in my setup, actually a little but faster than the FTxx specs). |
Yes, it really has been a while, this was well before I added DMA support for ESP32 and I did it differently since I needed to keep everything working for all the other platforms. Your code builds for me as well, I only have no setup I could test it with right now. The function initForLvgl() is for the V4 version of my library, it can not work like this with V5. When you are not using touch you can remove the EVE_cmd_dl(TAG(... lines. My EVE_init_spi() already sets up two SPI configurations, one for DMA - EVE_spi_device. The lvgl config is here: Well, maybe use this one for the DMA transfers? I can't figure out on the spot what the purpose of all the code there is. |
I can't look at code right now so I apologize if this isn't relevant, but I will just add that the last bit of work I did on this was to use more in-flight DMA transfers via a queue and that had a major increase on performance for ESP32 LVGL. But this of course required really tightly tuned ESP32-specific code using the IDF method of queuing DMA transfers, which also meant it had to be in control of the CS line since the transfers are all offloaded in the background. You can see a before/after demo of DMA queuing here using the LVGL demo: https://www.youtube.com/watch?v=HxO02oeiakw Another thing I'll add is that while these ESP32 LVGL bitmaps transfers are fairly fast, the way LVGL works by sending blocks or a window of bitmap updates is not optimal since the FTxx bitmaps transfer didn't have a way to just update window of the full-screen bitmap. This meant I had to break up a block of updates into separate lines for many single DMA transfers and this is not optimal at all. It's the one missing piece in the FTxx low level API that would have made this really potentially much faster (if you can accept the tradeoffs of using the FTxx this way to use LVGL). |
@davidjade thank you for your insights. Wish I knew ESP-IDF... I'm too far entrenched in the Arduino environment :| @RudolphRiedel I tried to retrieve all the parameters scattered around lvgl_esp32 and put together that SPI configuration they used, however it doesn't appear to work properly, the screen just blinks at init and stays black. With the regular software-driven CS the screen stays grey. There is something not really clear to me in this function you suggested:
EVE_dma_buffer looks like a global array defined in EVE_target.h |
Do you have a logic-analyzer so that you can check what actually is coming out on the SPI? Edit: naming that EVE_dma_buffer was not correct, that was me thinking one step further and removing the original DMA functionality since it no longer is needed. |
From memory, LVGL has it's own buffers (two) that you set up and tell it about that it then writes updates into and then it makes callbacks to let the "driver" know when to flush them to the hardware. LVGL will actively write into the second buffer while the first is being used for DMA flushing. In the LVGL demo code, you should see something like this for the update buffers:
The ESP32 LVGL driver also has a small buffer that is used for managing the SPI transfers as well as using a queue to keep many DMA transfers in-flight. The larger LVGL buffers need to sometimes be broken up into many separate DMA transfers since LVGL will use the buffer for a "window" or rectangular update region and the FTxx bitmaps have no direct way to work that way. The basic hack I implemented for LVGL was to set up a display list with one fullscreen bitmap. Then I figured out I could write directly to the bitmap on the FTxx device using the commands to write directly to the FTxx memory. This bypasses all the FTxx display list commands and allows for direct LVGL memory to FTxx bitmap memory DMA transfers. One thing I would suggest in getting it up and running that I found useful was to reduce the SPI clock speed to rule out that signal corruption is not the issue. Also start with dual SPI vs. jumping straight to quad. I also sometimes had issues with the FTxx setup and not delaying or waiting for the FTxx to be ready to start all these fast direct memory writes. I only had two devices to test on and I think I got somewhat lucky that the Quad SPI eventually ran on a breadboard at full speed without electrical interference. Hope this helps. |
@RudolphRiedel I changed the function as follows, but still nothing displayed
Unfortunately I have a simple scope with just two channels which I used to debug I2C and RS485 but I'm afraid we would need 4 channels to debug SPI. However your example works (see picture below) so hardware reliability is verified. @davidjade interesting hack for FTxxx. |
A 2 channel scope is fine as the question right now is if there even is traffic on the SPI for the lvgl buffers. And I was not even thinking about QSPI, I never needed it so far and most of the architectures my library is supporting could not even use QSPI, only a fraction supports DMA. Well, slow running would be an improvement over not running. |
Dear Rudolph,
I was able to make Arduino PlatformIO example to work on my test bed composed of ESP32 MCU and a Riverdi EVE3 7" display.
I would like to use LVGL (either v7 or v8) with your library. I'm aware of the LVGL ESP32 project, however it is for ESP-IDF and, despite being a derivative of your work, has significant differences which I try to overcome but failed.
I understand that LVGL just need a callback function to draw regions of bitmap from a SRAM buffer
The LVGL ESP32 project achieves this through the functions
FT81x_flush
andTFT_WriteBitmap
below (https://github.com/lvgl/lvgl_esp32_drivers/blob/master/lvgl_tft/FT81x.c).The latter uses a function,
EVE_memWrite_buffer
, for which the closest function in your library isEVE_memWrite_sram_buffer
. However it misses the flag that sends DISP_SPI_SIGNAL_FLUSH to the SPI transaction. The low level function to write to SPI bus (disp_spi_transaction
) is very different fromspi_transfer
, I guess due to being ESP-IDF based.Could you please pointing me to some clues to get it working?
I would be happy to test a prototype function. I guess I can get the screen initialization working.
Thank you,
Nick
The text was updated successfully, but these errors were encountered: