3333#include "esp_private/gpio.h"
3434#include "esp_private/gdma.h"
3535#include "esp_private/gdma_link.h"
36+ #include "esp_private/esp_dma_utils.h"
3637#include "esp_private/periph_ctrl.h"
3738#include "esp_lcd_common.h"
3839#include "soc/lcd_periph.h"
@@ -87,7 +88,7 @@ struct esp_lcd_i80_bus_t {
8788 uint8_t * format_buffer ; // The driver allocates an internal buffer for DMA to do data format transformer
8889 uint8_t * format_buffer_nc ; // Non-cacheable version of format buffer
8990 size_t resolution_hz ; // LCD_CLK resolution, determined by selected clock source
90- size_t num_dma_nodes ; // Number of DMA nodes (descriptors)
91+ size_t max_transfer_bytes ; // Maximum number of bytes that can be transferred in one transaction
9192 gdma_channel_handle_t dma_chan ; // DMA channel handle
9293 gdma_link_list_handle_t dma_link ; // DMA link list handle
9394 size_t int_mem_align ; // Alignment for internal memory
@@ -199,6 +200,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
199200 lcd_ll_enable_interrupt (bus -> hal .dev , LCD_LL_EVENT_TRANS_DONE , false); // disable all interrupts
200201 lcd_ll_clear_interrupt_status (bus -> hal .dev , UINT32_MAX ); // clear pending interrupt
201202 // install DMA service
203+ bus -> max_transfer_bytes = bus_config -> max_transfer_bytes ;
202204 ret = lcd_i80_init_dma_link (bus , bus_config );
203205 ESP_GOTO_ON_ERROR (ret , err , TAG , "install DMA failed" );
204206 // disable RGB-LCD mode
@@ -223,7 +225,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
223225 LIST_INIT (& bus -> device_list ); // initialize device list head
224226 bus -> spinlock = (portMUX_TYPE )portMUX_INITIALIZER_UNLOCKED ;
225227 * ret_bus = bus ;
226- ESP_LOGD (TAG , "new i80 bus(%d) @%p, %zu dma nodes " , bus_id , bus , bus -> num_dma_nodes );
228+ ESP_LOGD (TAG , "new i80 bus(%d) @%p" , bus_id , bus );
227229 return ESP_OK ;
228230
229231err :
@@ -449,7 +451,7 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
449451 esp_lcd_i80_bus_t * bus = next_device -> bus ;
450452 lcd_panel_io_i80_t * cur_device = bus -> cur_device ;
451453 lcd_i80_trans_descriptor_t * trans_desc = NULL ;
452- assert (param_size <= ( bus -> num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE ) && "parameter bytes too long, enlarge max_transfer_bytes" );
454+ assert (param_size <= bus -> max_transfer_bytes && "parameter bytes too long, enlarge max_transfer_bytes" );
453455 assert (param_size <= LCD_I80_IO_FORMAT_BUF_SIZE && "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE" );
454456 uint32_t cmd_cycles = next_device -> lcd_cmd_bits / bus -> bus_width ;
455457 // in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle
@@ -514,7 +516,7 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
514516 lcd_panel_io_i80_t * i80_device = __containerof (io , lcd_panel_io_i80_t , base );
515517 esp_lcd_i80_bus_t * bus = i80_device -> bus ;
516518 lcd_i80_trans_descriptor_t * trans_desc = NULL ;
517- assert (color_size <= ( bus -> num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE ) && "color bytes too long, enlarge max_transfer_bytes" );
519+ assert (color_size <= bus -> max_transfer_bytes && "color bytes too long, enlarge max_transfer_bytes" );
518520 uint32_t cache_line_size = 0 ;
519521 if (esp_ptr_external_ram (color )) {
520522 // check alignment
@@ -610,18 +612,18 @@ static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_l
610612 ESP_RETURN_ON_ERROR (gdma_config_transfer (bus -> dma_chan , & trans_cfg ), TAG , "config DMA transfer failed" );
611613 gdma_get_alignment_constraints (bus -> dma_chan , & bus -> int_mem_align , & bus -> ext_mem_align );
612614
613- size_t num_dma_nodes = bus_config -> max_transfer_bytes / LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1 ;
615+ size_t buffer_alignment = MAX (bus -> int_mem_align , bus -> ext_mem_align );
616+ size_t num_dma_nodes = esp_dma_calculate_node_count (bus -> max_transfer_bytes , buffer_alignment , LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE );
614617 // create DMA link list
615618 gdma_link_list_config_t dma_link_config = {
616- .buffer_alignment = MAX ( bus -> int_mem_align , bus -> ext_mem_align ) ,
619+ .buffer_alignment = buffer_alignment ,
617620 .item_alignment = LCD_GDMA_DESCRIPTOR_ALIGN ,
618621 .num_items = num_dma_nodes ,
619622 .flags = {
620623 .check_owner = true,
621624 },
622625 };
623626 ESP_RETURN_ON_ERROR (gdma_new_link_list (& dma_link_config , & bus -> dma_link ), TAG , "create DMA link list failed" );
624- bus -> num_dma_nodes = num_dma_nodes ;
625627
626628 return ESP_OK ;
627629}
0 commit comments