Skip to content
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
seijikun opened this issue Feb 29, 2024 · 1 comment
Closed
3 tasks done
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@seijikun
Copy link
Contributor

seijikun commented Feb 29, 2024

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

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) in esp_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.

  1. Create empty project with main loop
  2. Initialize psram
  3. Setup LCD exactly as is done here from line 47 to to (including) line 121.
  4. Put esp to sleep using 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.

IMG_20240229_220103214_MFNR
IMG_20240229_220126949_HDR

@seijikun seijikun added the Type: Bug bugs in IDF label Feb 29, 2024
@github-actions github-actions bot changed the title [ESP32S3] [esp_lcd rgb] PSRAM Framebuffers are not flushed after allocation [ESP32S3] [esp_lcd rgb] PSRAM Framebuffers are not flushed after allocation (IDFGH-12243) Feb 29, 2024
@espressif-bot espressif-bot added the Status: Opened Issue is new label Feb 29, 2024
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.
@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Mar 1, 2024
@seijikun
Copy link
Contributor Author

seijikun commented Mar 1, 2024

Single-file reproducible example for the record:
(Using Makerfabs ESP32-S3 Parallel 4.3" TFT with Touch)

#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);
    }
}

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: In Progress Work is in progress labels Mar 4, 2024
espressif-bot pushed a commit that referenced this issue Mar 7, 2024
Flush PSRAM framebuffers after allocation to avoid visual corruption.

Merges #13294
Closes #13293
espressif-bot pushed a commit that referenced this issue Mar 13, 2024
Flush PSRAM framebuffers after allocation to avoid visual corruption.

Merges #13294
Closes #13293
espressif-bot pushed a commit that referenced this issue Mar 13, 2024
Flush PSRAM framebuffers after allocation to avoid visual corruption.

Merges #13294
Closes #13293
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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants