mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
remove(lcd): remove restart support for p4 and s31
This commit is contained in:
@@ -7,3 +7,4 @@ CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y
|
||||
CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y
|
||||
CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y
|
||||
CONFIG_SPIRAM_ECC_ENABLE=y
|
||||
|
||||
@@ -14,6 +14,7 @@ menu "ESP-Driver:LCD Controller Configurations"
|
||||
|
||||
config LCD_RGB_RESTART_IN_VSYNC
|
||||
bool "Always restart RGB LCD transmission in VSYNC"
|
||||
depends on IDF_TARGET_ESP32S3
|
||||
default n
|
||||
help
|
||||
Reset the GDMA channel every VBlank to stop permanent desyncs from happening.
|
||||
|
||||
@@ -527,9 +527,11 @@ esp_err_t esp_lcd_rgb_panel_set_pclk(esp_lcd_panel_handle_t panel, uint32_t freq
|
||||
esp_err_t esp_lcd_rgb_panel_restart(esp_lcd_panel_handle_t panel)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
#if !RGB_LCD_NEEDS_SEPARATE_RESTART_LINK
|
||||
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "restart is not supported on this target");
|
||||
#endif
|
||||
esp_rgb_panel_t *rgb_panel = __containerof(panel, esp_rgb_panel_t, base);
|
||||
ESP_RETURN_ON_FALSE(rgb_panel->flags.stream_mode, ESP_ERR_INVALID_STATE, TAG, "not in stream mode");
|
||||
|
||||
// the underlying restart job will be done in the `LCD_LL_EVENT_VSYNC_END` event handler
|
||||
portENTER_CRITICAL(&rgb_panel->spinlock);
|
||||
rgb_panel->flags.need_restart = true;
|
||||
@@ -1259,7 +1261,8 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// reset the GDMA channel every VBlank to stop permanent desyncs from happening.
|
||||
#if RGB_LCD_NEEDS_SEPARATE_RESTART_LINK
|
||||
// Reset the GDMA channel every VBlank to stop permanent desyncs from happening.
|
||||
// Note that this fix can lead to single-frame desyncs itself, as in: if this interrupt
|
||||
// is late enough, the display will shift as the LCD controller already read out the
|
||||
// first data bytes, and resetting DMA will re-send those. However, the single-frame
|
||||
@@ -1321,6 +1324,7 @@ static IRAM_ATTR void lcd_rgb_panel_try_restart_transmission(esp_rgb_panel_t *pa
|
||||
}
|
||||
|
||||
}
|
||||
#endif // RGB_LCD_NEEDS_SEPARATE_RESTART_LINK
|
||||
|
||||
static void lcd_rgb_panel_start_transmission(esp_rgb_panel_t *rgb_panel)
|
||||
{
|
||||
@@ -1391,10 +1395,12 @@ IRAM_ATTR static void rgb_lcd_default_isr_handler(void *args)
|
||||
// check whether to update the PCLK frequency, it should be safe to update the PCLK frequency in the VSYNC interrupt
|
||||
lcd_rgb_panel_try_update_pclk(rgb_panel);
|
||||
|
||||
#if RGB_LCD_NEEDS_SEPARATE_RESTART_LINK
|
||||
if (rgb_panel->flags.stream_mode) {
|
||||
// check whether to restart the transmission
|
||||
lcd_rgb_panel_try_restart_transmission(rgb_panel);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
// yield if needed
|
||||
|
||||
@@ -215,6 +215,7 @@ esp_err_t esp_lcd_rgb_panel_set_pclk(esp_lcd_panel_handle_t panel, uint32_t freq
|
||||
/**
|
||||
* @brief Restart the LCD transmission
|
||||
*
|
||||
* @note This function is only supported on ESP32-S3.
|
||||
* @note This function can be useful when the LCD controller is out of sync with the DMA because of insufficient bandwidth.
|
||||
* To save the screen from a permanent shift, you can call this function to restart the LCD DMA.
|
||||
* @note This function doesn't restart the DMA immediately but to set a flag internally.
|
||||
@@ -225,7 +226,8 @@ esp_err_t esp_lcd_rgb_panel_set_pclk(esp_lcd_panel_handle_t panel, uint32_t freq
|
||||
* @param[in] panel panel LCD panel handle, returned from `esp_lcd_new_rgb_panel`
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG: Restart the LCD failed because of invalid argument
|
||||
* - ESP_ERR_INVALID_STATE: Restart the LCD failed because the LCD diver is working in refresh-on-demand mode
|
||||
* - ESP_ERR_INVALID_STATE: Restart the LCD failed because the LCD driver is working in refresh-on-demand mode
|
||||
* - ESP_ERR_NOT_SUPPORTED: Restarting the LCD is not supported on this target
|
||||
* - ESP_OK: Restart the LCD successfully
|
||||
*/
|
||||
esp_err_t esp_lcd_rgb_panel_restart(esp_lcd_panel_handle_t panel);
|
||||
|
||||
@@ -219,10 +219,7 @@ TEST_CASE("lcd_rgb_panel_update_pclk", "[lcd]")
|
||||
|
||||
TEST_CASE("lcd_rgb_panel_restart", "[lcd]")
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32S31 // IDF-15960
|
||||
TEST_IGNORE_MESSAGE("Known issue: lcd_rgb_panel_restart underruns on flash-encrypted runners");
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S31
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S3
|
||||
uint8_t *img = malloc(TEST_IMG_SIZE);
|
||||
TEST_ASSERT_NOT_NULL(img);
|
||||
|
||||
@@ -244,6 +241,12 @@ TEST_CASE("lcd_rgb_panel_restart", "[lcd]")
|
||||
printf("delete RGB panel\r\n");
|
||||
TEST_ESP_OK(esp_lcd_panel_del(panel_handle));
|
||||
free(img);
|
||||
#else
|
||||
printf("initialize RGB panel with stream mode\r\n");
|
||||
esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(16, LCD_COLOR_FMT_RGB565, 0, LCD_CLK_SRC_DEFAULT, false, false, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_ERR_NOT_SUPPORTED, esp_lcd_rgb_panel_restart(panel_handle));
|
||||
TEST_ESP_OK(esp_lcd_panel_del(panel_handle));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("lcd_rgb_panel_rotate", "[lcd]")
|
||||
|
||||
@@ -260,7 +260,7 @@ This mode allocates two "bounce buffers" from internal memory and a main frame b
|
||||
|
||||
.. note::
|
||||
|
||||
This mode also faces issues due to limited PSRAM bandwidth. For instance, if your draw buffers are in PSRAM and their contents are copied to the internal frame buffer by CPU Core 1, while CPU Core 0 is performing another memory copy in the DMA EOF ISR, both CPUs will be accessing PSRAM via cache, sharing its bandwidth. This significantly increases the memory copy time in the DMA EOF ISR, causing the driver to fail in switching the bounce buffer promptly, resulting in a screen shift. Although the driver can detect this condition and restart in the LCD's VSYNC interrupt handler, you may still notice flickering on the screen.
|
||||
This mode also faces issues due to limited PSRAM bandwidth. For instance, if your draw buffers are in PSRAM and their contents are copied to the internal frame buffer by CPU Core 1, while CPU Core 0 is performing another memory copy in the DMA EOF ISR, both CPUs will be accessing PSRAM via cache, sharing its bandwidth. This significantly increases the memory copy time in the DMA EOF ISR, causing the driver to fail in switching the bounce buffer promptly, resulting in a screen shift. On ESP32-S3, the driver can detect this condition and restart in the LCD's VSYNC interrupt handler, although you may still notice flickering on the screen.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@@ -305,10 +305,12 @@ Bounce Buffer Only
|
||||
|
||||
This mode is similar to :ref:`bounce_buffer_with_single_psram_frame_buffer`, but there is no PSRAM frame buffer initialized by the LCD driver. Instead, the user supplies a callback function that is responsible for filling the bounce buffers. As this driver does not care where the written pixels come from, this allows for the callback doing e.g., on-the-fly conversion from a smaller, 8-bit-per-pixel PSRAM frame buffer to a 16-bit LCD, or even procedurally generated frame-buffer-less graphics. This option is selected by setting the :cpp:member:`esp_lcd_rgb_panel_config_t::no_fb` flag and supplying a :cpp:member:`esp_lcd_rgb_panel_config_t::bounce_buffer_size_px` value. And then register the :cpp:member:`esp_lcd_rgb_panel_event_callbacks_t::on_bounce_empty` callback by calling :cpp:func:`esp_lcd_rgb_panel_register_event_callbacks`.
|
||||
|
||||
.. note::
|
||||
.. only:: esp32s3
|
||||
|
||||
In a well-designed embedded application, situations where the DMA cannot deliver data as fast as the LCD consumes it should be avoided. However, such scenarios can theoretically occur. In the {IDF_TARGET_NAME} hardware, this results in the LCD outputting dummy bytes while the DMA waits for data. If the DMA were to run in a continuous stream, it could cause a desynchronization between the LCD address from which the DMA reads data and the address from which the LCD peripheral outputs data, leading to a **permanently** shifted image.
|
||||
To prevent this, you can either enable the :ref:`CONFIG_LCD_RGB_RESTART_IN_VSYNC` option, allowing the driver to automatically restart the DMA during the VBlank interrupt, or call :cpp:func:`esp_lcd_rgb_panel_restart` to manually restart the DMA. Note that :cpp:func:`esp_lcd_rgb_panel_restart` does not restart the DMA immediately; instead, the DMA will be restarted at the next VSYNC event.
|
||||
.. note::
|
||||
|
||||
In a well-designed embedded application, situations where the DMA cannot deliver data as fast as the LCD consumes it should be avoided. However, such scenarios can theoretically occur. In the {IDF_TARGET_NAME} hardware, this results in the LCD outputting dummy bytes while the DMA waits for data. If the DMA were to run in a continuous stream, it could cause a desynchronization between the LCD address from which the DMA reads data and the address from which the LCD peripheral outputs data, leading to a **permanently** shifted image.
|
||||
To prevent this, you can either enable the :ref:`CONFIG_LCD_RGB_RESTART_IN_VSYNC` option, allowing the driver to automatically restart the DMA during the VBlank interrupt, or call :cpp:func:`esp_lcd_rgb_panel_restart` to manually restart the DMA. Note that :cpp:func:`esp_lcd_rgb_panel_restart` does not restart the DMA immediately; instead, the DMA will be restarted at the next VSYNC event.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
@@ -260,7 +260,7 @@ bounce buffer 与 PSRAM frame buffer
|
||||
|
||||
.. note::
|
||||
|
||||
由于 PSRAM 带宽不足,此模式还可能存在另一个问题。例如,从 PSRAM 中分配绘图 buffer,且 buffer 中的数据被复制到 CPU 核 1 上的内部 frame buffer 中,此时在 CPU 核 0 上,DMA EOF ISR 也在进行内存复制。这种情况下,两个内核都通过 cache 访问 PSRAM 并共享 PSRAM 的带宽,DMA EOF ISR 复制内存的时间大大增加。驱动程序无法及时切换 bounce buffer,造成 LCD 屏幕移位。尽管驱动程序可以检测到这种情况并在 LCD 的 VSYNC 中断处理程序中执行重新启动,但仍会出现屏幕闪烁现象。
|
||||
由于 PSRAM 带宽不足,此模式还可能存在另一个问题。例如,从 PSRAM 中分配绘图 buffer,且 buffer 中的数据被复制到 CPU 核 1 上的内部 frame buffer 中,此时在 CPU 核 0 上,DMA EOF ISR 也在进行内存复制。这种情况下,两个内核都通过 cache 访问 PSRAM 并共享 PSRAM 的带宽,DMA EOF ISR 复制内存的时间大大增加。驱动程序无法及时切换 bounce buffer,造成 LCD 屏幕移位。在 ESP32-S3 上,驱动程序可以检测到这种情况并在 LCD 的 VSYNC 中断处理程序中执行重新启动,但仍会出现屏幕闪烁现象。
|
||||
|
||||
.. code:: c
|
||||
|
||||
@@ -305,10 +305,12 @@ bounce buffer 与 PSRAM frame buffer
|
||||
|
||||
该模式与 :ref:`bounce_buffer_with_single_psram_frame_buffer` 模式类似,但 LCD 驱动程序不会初始化 PSRAM frame buffer。相反,该模式依赖用户提供的回调函数来填充 bounce buffer。LCD 驱动程序无需指定写入像素的来源,因此回调函数可以执行一些操作:例如,将较小的每像素 8 位 PSRAM frame buffer 即时转换为 16 位 LCD 数据,甚至还可以转换为无 frame buffer 图形。若想选择此模式,可以设置 :cpp:member:`esp_lcd_rgb_panel_config_t::no_fb` 标志并提供 :cpp:member:`esp_lcd_rgb_panel_config_t::bounce_buffer_size_px` 值。然后通过调用 :cpp:func:`esp_lcd_rgb_panel_register_event_callbacks` 注册回调函数 :cpp:member:`esp_lcd_rgb_panel_event_callbacks_t::on_bounce_empty`。
|
||||
|
||||
.. note::
|
||||
.. only:: esp32s3
|
||||
|
||||
虽说在设计良好的嵌入式应用程序中, DMA 传递数据的速度不应该赶不上 LCD 读取数据的速度。但理论上,此种情况还是有可能出现的。在 {IDF_TARGET_NAME} 的硬件中,这种情况会导致 LCD 在 DMA 等待数据时单纯输出 dummy 字节。若以流式传输运行 DMA,则 DMA 会将读取到的数据传输到某个 LCD 地址,同时 LCD 也会将数据输出到某个 LCD 地址,但上述两个地址可能会不同步,导致图像 **永久** 偏移。
|
||||
为防止类似情况发生,可以启用 :ref:`CONFIG_LCD_RGB_RESTART_IN_VSYNC` 选项,以便驱动程序在 VBlank 中断时自动重启 DMA;或者也可以调用 :cpp:func:`esp_lcd_rgb_panel_restart`,手动重启 DMA。请注意,调用 :cpp:func:`esp_lcd_rgb_panel_restart` 不会立即重启 DMA,DMA 只会在下一个 VSYNC 事件中重启。
|
||||
.. note::
|
||||
|
||||
虽说在设计良好的嵌入式应用程序中, DMA 传递数据的速度不应该赶不上 LCD 读取数据的速度。但理论上,此种情况还是有可能出现的。在 {IDF_TARGET_NAME} 的硬件中,这种情况会导致 LCD 在 DMA 等待数据时单纯输出 dummy 字节。若以流式传输运行 DMA,则 DMA 会将读取到的数据传输到某个 LCD 地址,同时 LCD 也会将数据输出到某个 LCD 地址,但上述两个地址可能会不同步,导致图像 **永久** 偏移。
|
||||
为防止类似情况发生,可以启用 :ref:`CONFIG_LCD_RGB_RESTART_IN_VSYNC` 选项,以便驱动程序在 VBlank 中断时自动重启 DMA;或者也可以调用 :cpp:func:`esp_lcd_rgb_panel_restart`,手动重启 DMA。请注意,调用 :cpp:func:`esp_lcd_rgb_panel_restart` 不会立即重启 DMA,DMA 只会在下一个 VSYNC 事件中重启。
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
Reference in New Issue
Block a user