mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 10:47:19 +02:00
feat(esp_lcd): rgb add callback when bounce buffer finish
This commit is contained in:
@ -99,14 +99,25 @@ typedef bool (*esp_lcd_rgb_panel_vsync_cb_t)(esp_lcd_panel_handle_t panel, const
|
|||||||
*/
|
*/
|
||||||
typedef bool (*esp_lcd_rgb_panel_bounce_buf_fill_cb_t)(esp_lcd_panel_handle_t panel, void *bounce_buf, int pos_px, int len_bytes, void *user_ctx);
|
typedef bool (*esp_lcd_rgb_panel_bounce_buf_fill_cb_t)(esp_lcd_panel_handle_t panel, void *bounce_buf, int pos_px, int len_bytes, void *user_ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prototype for the function to be called when the bounce buffer finish copying the entire frame.
|
||||||
|
*
|
||||||
|
* @param[in] panel LCD panel handle, returned from `esp_lcd_new_rgb_panel`
|
||||||
|
* @param[in] edata Panel event data, fed by driver
|
||||||
|
* @param[in] user_ctx User data, passed from `esp_lcd_rgb_panel_register_event_callbacks()`
|
||||||
|
* @return Whether a high priority task has been waken up by this function
|
||||||
|
*/
|
||||||
|
typedef bool (*esp_lcd_rgb_panel_bounce_buf_finish_cb_t)(esp_lcd_panel_handle_t panel, const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Group of supported RGB LCD panel callbacks
|
* @brief Group of supported RGB LCD panel callbacks
|
||||||
* @note The callbacks are all running under ISR environment
|
* @note The callbacks are all running under ISR environment
|
||||||
* @note When CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
|
* @note When CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
esp_lcd_rgb_panel_vsync_cb_t on_vsync; /*!< VSYNC event callback */
|
esp_lcd_rgb_panel_vsync_cb_t on_vsync; /*!< VSYNC event callback */
|
||||||
esp_lcd_rgb_panel_bounce_buf_fill_cb_t on_bounce_empty; /*!< Bounce buffer empty callback. */
|
esp_lcd_rgb_panel_bounce_buf_fill_cb_t on_bounce_empty; /*!< Bounce buffer empty callback. */
|
||||||
|
esp_lcd_rgb_panel_bounce_buf_finish_cb_t on_bounce_frame_finish; /*!< Bounce buffer finish callback. */
|
||||||
} esp_lcd_rgb_panel_event_callbacks_t;
|
} esp_lcd_rgb_panel_event_callbacks_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,6 +109,7 @@ struct esp_rgb_panel_t {
|
|||||||
gdma_channel_handle_t dma_chan; // DMA channel handle
|
gdma_channel_handle_t dma_chan; // DMA channel handle
|
||||||
esp_lcd_rgb_panel_vsync_cb_t on_vsync; // VSYNC event callback
|
esp_lcd_rgb_panel_vsync_cb_t on_vsync; // VSYNC event callback
|
||||||
esp_lcd_rgb_panel_bounce_buf_fill_cb_t on_bounce_empty; // callback used to fill a bounce buffer rather than copying from the frame buffer
|
esp_lcd_rgb_panel_bounce_buf_fill_cb_t on_bounce_empty; // callback used to fill a bounce buffer rather than copying from the frame buffer
|
||||||
|
esp_lcd_rgb_panel_bounce_buf_finish_cb_t on_bounce_frame_finish; // callback used to notify when the bounce buffer finish copying the entire frame
|
||||||
void *user_ctx; // Reserved user's data of callback functions
|
void *user_ctx; // Reserved user's data of callback functions
|
||||||
int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
|
int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
|
||||||
int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
|
int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
|
||||||
@ -360,12 +361,16 @@ esp_err_t esp_lcd_rgb_panel_register_event_callbacks(esp_lcd_panel_handle_t pane
|
|||||||
if (callbacks->on_bounce_empty) {
|
if (callbacks->on_bounce_empty) {
|
||||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_bounce_empty), ESP_ERR_INVALID_ARG, TAG, "on_bounce_empty callback not in IRAM");
|
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_bounce_empty), ESP_ERR_INVALID_ARG, TAG, "on_bounce_empty callback not in IRAM");
|
||||||
}
|
}
|
||||||
|
if (callbacks->on_bounce_frame_finish) {
|
||||||
|
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(callbacks->on_bounce_frame_finish), ESP_ERR_INVALID_ARG, TAG, "on_bounce_frame_finish callback not in IRAM");
|
||||||
|
}
|
||||||
if (user_ctx) {
|
if (user_ctx) {
|
||||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
|
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
|
||||||
}
|
}
|
||||||
#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE
|
#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE
|
||||||
rgb_panel->on_vsync = callbacks->on_vsync;
|
rgb_panel->on_vsync = callbacks->on_vsync;
|
||||||
rgb_panel->on_bounce_empty = callbacks->on_bounce_empty;
|
rgb_panel->on_bounce_empty = callbacks->on_bounce_empty;
|
||||||
|
rgb_panel->on_bounce_frame_finish = callbacks->on_bounce_frame_finish;
|
||||||
rgb_panel->user_ctx = user_ctx;
|
rgb_panel->user_ctx = user_ctx;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -889,7 +894,9 @@ static IRAM_ATTR bool lcd_rgb_panel_fill_bounce_buffer(esp_rgb_panel_t *panel, u
|
|||||||
if (panel->num_fbs == 0) {
|
if (panel->num_fbs == 0) {
|
||||||
if (panel->on_bounce_empty) {
|
if (panel->on_bounce_empty) {
|
||||||
// We don't have a frame buffer here; we need to call a callback to refill the bounce buffer
|
// We don't have a frame buffer here; we need to call a callback to refill the bounce buffer
|
||||||
need_yield = panel->on_bounce_empty(&panel->base, buffer, panel->bounce_pos_px, panel->bb_size, panel->user_ctx);
|
if (panel->on_bounce_empty(&panel->base, buffer, panel->bounce_pos_px, panel->bb_size, panel->user_ctx)) {
|
||||||
|
need_yield = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We do have frame buffer; copy from there.
|
// We do have frame buffer; copy from there.
|
||||||
@ -910,6 +917,11 @@ static IRAM_ATTR bool lcd_rgb_panel_fill_bounce_buffer(esp_rgb_panel_t *panel, u
|
|||||||
if (panel->bounce_pos_px >= panel->fb_size / bytes_per_pixel) {
|
if (panel->bounce_pos_px >= panel->fb_size / bytes_per_pixel) {
|
||||||
panel->bounce_pos_px = 0;
|
panel->bounce_pos_px = 0;
|
||||||
panel->bb_fb_index = panel->cur_fb_index;
|
panel->bb_fb_index = panel->cur_fb_index;
|
||||||
|
if (panel->on_bounce_frame_finish) {
|
||||||
|
if (panel->on_bounce_frame_finish(&panel->base, NULL, panel->user_ctx)) {
|
||||||
|
need_yield = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (panel->num_fbs > 0) {
|
if (panel->num_fbs > 0) {
|
||||||
// Preload the next bit of buffer from psram
|
// Preload the next bit of buffer from psram
|
||||||
|
Reference in New Issue
Block a user