-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
[ESP32S3] [esp_lcd rgb] PSRAM Framebuffers are not flushed after allocation (IDFGH-12243) #13293
Closed
3 tasks done
Labels
Resolution: NA
Issue resolution is unavailable
Status: Done
Issue is done internally
Type: Bug
bugs in IDF
Comments
seijikun
added a commit
to seijikun/esp-idf
that referenced
this issue
Feb 29, 2024
calloc not only allocates but allo zero's the buffer. We have to make sure this is properly committed to the PSRAM, otherwise all sorts of visual corruption happen.
seijikun
added a commit
to seijikun/esp-idf
that referenced
this issue
Feb 29, 2024
calloc not only allocates but aslo zero's the buffer. We have to make sure this is properly committed to the PSRAM, otherwise all sorts of visual corruption happen.
seijikun
added a commit
to seijikun/esp-idf
that referenced
this issue
Feb 29, 2024
Framebuffers are allocated using calloc, which also zero's the buffer. This zeroing is done by the CPU and thus uses the CPU's writeback cache for the PSRAM. If the framebuffer is not flushed after allocation, the DMA hardware is going to read stale data and push that to the display hardware.
Single-file reproducible example for the record: #include <freertos/FreeRTOS.h>
#include <esp_log.h>
#include <esp_heap_caps.h>
#include <hal/gpio_types.h>
#include <esp_err.h>
#include <esp_psram.h>
#include <esp_lcd_panel_interface.h>
#include <esp_lcd_panel_rgb.h>
#include <freertos/timers.h>
void app_main(void) {
esp_psram_init();
size_t w = 800;
size_t h = 480;
size_t _r0 = 45;
size_t _r1 = 48;
size_t _r2 = 47;
size_t _r3 = 21;
size_t _r4 = 14;
size_t _g0 = 5;
size_t _g1 = 6;
size_t _g2 = 7;
size_t _g3 = 15;
size_t _g4 = 16;
size_t _g5 = 4;
size_t _b0 = 8;
size_t _b1 = 3;
size_t _b2 = 46;
size_t _b3 = 9;
size_t _b4 = 1;
size_t hsync_polarity = 0;
size_t hsync_front_porch = 8;
size_t hsync_pulse_width = 4;
size_t hsync_back_porch = 8;
size_t vsync_polarity = 0;
size_t vsync_front_porch = 8;
size_t vsync_pulse_width = 4;
size_t vsync_back_porch = 8;
size_t de_idle_high = 0;
size_t pclk_active_neg = 1;
size_t pclk_idle_high = 0;
esp_lcd_rgb_panel_config_t *_panel_config = (esp_lcd_rgb_panel_config_t *)heap_caps_calloc(1, sizeof(esp_lcd_rgb_panel_config_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
_panel_config->clk_src = LCD_CLK_SRC_PLL160M;
_panel_config->timings.pclk_hz = 16000000;
_panel_config->timings.h_res = w;
_panel_config->timings.v_res = h;
// The following parameters should refer to LCD spec
_panel_config->timings.hsync_pulse_width = hsync_pulse_width;
_panel_config->timings.hsync_back_porch = hsync_back_porch;
_panel_config->timings.hsync_front_porch = hsync_front_porch;
_panel_config->timings.vsync_pulse_width = vsync_pulse_width;
_panel_config->timings.vsync_back_porch = vsync_back_porch;
_panel_config->timings.vsync_front_porch = vsync_front_porch;
_panel_config->timings.flags.hsync_idle_low = (hsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.vsync_idle_low = (vsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.de_idle_high = de_idle_high;
_panel_config->timings.flags.pclk_active_neg = pclk_active_neg;
_panel_config->timings.flags.pclk_idle_high = pclk_idle_high;
_panel_config->data_width = 16; // RGB565 in parallel mode, thus 16bit in width
//panel_config->bits_per_pixel = 16;
_panel_config->sram_trans_align = 8;
_panel_config->psram_trans_align = 64;
_panel_config->hsync_gpio_num = 39;
_panel_config->vsync_gpio_num = 41;
_panel_config->de_gpio_num = 40;
_panel_config->pclk_gpio_num = 42;
_panel_config->data_gpio_nums[0] = _g3;
_panel_config->data_gpio_nums[1] = _g4;
_panel_config->data_gpio_nums[2] = _g5;
_panel_config->data_gpio_nums[3] = _r0;
_panel_config->data_gpio_nums[4] = _r1;
_panel_config->data_gpio_nums[5] = _r2;
_panel_config->data_gpio_nums[6] = _r3;
_panel_config->data_gpio_nums[7] = _r4;
_panel_config->data_gpio_nums[8] = _b0;
_panel_config->data_gpio_nums[9] = _b1;
_panel_config->data_gpio_nums[10] = _b2;
_panel_config->data_gpio_nums[11] = _b3;
_panel_config->data_gpio_nums[12] = _b4;
_panel_config->data_gpio_nums[13] = _g0;
_panel_config->data_gpio_nums[14] = _g1;
_panel_config->data_gpio_nums[15] = _g2;
_panel_config->disp_gpio_num = GPIO_NUM_NC;
_panel_config->flags.disp_active_low = 0;
_panel_config->flags.refresh_on_demand = 0;
_panel_config->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM
esp_lcd_panel_handle_t panel_handle;
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(_panel_config, &panel_handle));
ESP_ERROR_CHECK(panel_handle->reset(panel_handle));
ESP_ERROR_CHECK(panel_handle->init(panel_handle));
while(true) {
vTaskDelay(10);
}
} |
DarkZeros
pushed a commit
to DarkZeros/esp-idf
that referenced
this issue
May 3, 2024
Flush PSRAM framebuffers after allocation to avoid visual corruption. Merges espressif#13294 Closes espressif#13293
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Resolution: NA
Issue resolution is unavailable
Status: Done
Issue is done internally
Type: Bug
bugs in IDF
Answers checklist.
IDF version.
v5.1
Espressif SoC revision.
esp32s3 (revision v0.2)
Operating System used.
Linux
How did you build your project?
I used Rust with esp-idf-sys.
Esp-idf v5.1
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32-S3-WROOM-1-N16R8
Power Supply used.
USB
What is the expected behavior?
After finalizing setup of the lcd component with
esp_lcd_panel_init()
, I expect the framebuffer to be completely zero'd.Meaning that the TFT shows a black blank screen.
What is the actual behavior?
The screen is corrupt at the bottom because the last bytes are stuck in the CPU cache, not yet committed to the framebuffer (in PSRAM).
In this state, there further is a high chance that the entire handling gets corrupted. I've had cases where screen position
(0, 0)
inesp_lcd_panel_draw_bitmap()
is somewhere in the middle of the screen. As well as lines shifted against each other. (Second picture)Steps to reproduce.
vTaskDelay()
Debug Logs.
No response
More Information.
Unfortunately, I can't update ESP-IDF to anything newer than that because it doesn't build in that environment.
However, I inspected the code and saw the problem is still there.
The text was updated successfully, but these errors were encountered: