ESP32-S3 LCD and I2S FULL documentation

ESP_Sprite
Posts: 9766
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Thu Mar 24, 2022 9:02 am

No clue, sorry. Perhaps take a look at components/hal/esp32s3/include/hal/clk_gate_ll.h to see how that does it?

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 1:36 am

dfsdfsdfgsdgsdgfsdfsdfsd
Last edited by Baldhead on Fri Mar 25, 2022 2:05 am, edited 5 times in total.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 1:36 am

ESP_Sprite wrote:
Thu Mar 24, 2022 9:02 am
No clue, sorry. Perhaps take a look at components/hal/esp32s3/include/hal/clk_gate_ll.h to see how that does it?
I didn't find anything relevant in this file.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 1:55 am

Hi @ESP_Sprite,

I am testing LCD_CAM with dma with memory allocated in spiram, but the data in the final part of buffers are corrupted( the last ~16400 bytes of a total of 307200 bytes ).
I filled the buffers with 0xffff.
The dma is working but with the final part of buffers corrupted.
I already reduced the clock to 10 MHz and problem persists.

With static ram allocated dinamically the dma is working all ok until 80 MHz ( ie: the buffers are not corrupted ).

Some suggestion ????

Code: Select all

#define buffer_in_spi_ram 1

#if buffer_in_spi_ram
    #define pixels_size 153600  // 153600 pixels = 307200 bytes.
#else
    #define pixels_size 19200  // 19200 pixels = 38400 bytes.
#endif

#define hw_lcd_dma_command_buf_size 32  // 32 bytes.


DMA_ATTR dma_descriptor_t* dma_desc_buf_a = NULL;
DMA_ATTR dma_descriptor_t* dma_desc_buf_b = NULL;
DMA_ATTR dma_descriptor_t* dma_desc_buf_command = NULL;

DMA_ATTR uint16_t* p_buffer_a = NULL;
DMA_ATTR uint16_t* p_buffer_b = NULL;
DMA_ATTR uint8_t* p_buf_command = NULL;

static esp_err_t hw_lcd_dma_alloc_memory()
{
    dma_desc_buf_a = (dma_descriptor_t*) heap_caps_calloc( descriptor_size, sizeof(dma_descriptor_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL );
    dma_desc_buf_b = (dma_descriptor_t*) heap_caps_calloc( descriptor_size, sizeof(dma_descriptor_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL );
    dma_desc_buf_command = (dma_descriptor_t*) heap_caps_calloc( 1, sizeof(dma_descriptor_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL ); 

    p_buf_command = (uint8_t*) heap_caps_malloc( hw_lcd_dma_command_buf_size * sizeof(uint8_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL );

#if buffer_in_spi_ram    
    p_buffer_a = (uint16_t*) heap_caps_aligned_alloc( 1, pixels_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM );
    p_buffer_b = (uint16_t*) heap_caps_aligned_alloc( 1, pixels_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM );
#else
    p_buffer_a = (uint16_t*) heap_caps_malloc( pixels_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL );
    p_buffer_b = (uint16_t*) heap_caps_malloc( pixels_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL );
#endif

    if( dma_desc_buf_a == NULL || dma_desc_buf_b == NULL || dma_desc_buf_command == NULL || p_buffer_a == NULL || p_buffer_b == NULL || p_buf_command == NULL )
    {    
        if(dma_desc_buf_a == NULL)        ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("dma_desc_buf_a == NULL"));        
        if(dma_desc_buf_b == NULL)        ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("dma_desc_buf_b == NULL"));
        if(dma_desc_buf_command == NULL)  ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("dma_desc_buf_command == NULL"));       
        if(p_buffer_a == NULL)            ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("p_buffer_a == NULL")); 
        if(p_buffer_b == NULL)            ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("p_buffer_b == NULL"));
        if(p_buf_command == NULL)         ESP_LOGI(HW_LCD_DMA_TAG, LOG_USER("p_buf_command == NULL"));
       
        heap_caps_free(dma_desc_buf_a);
        heap_caps_free(dma_desc_buf_b);
        heap_caps_free(dma_desc_buf_command);
        heap_caps_free(p_buffer_a);
        heap_caps_free(p_buffer_b);         
        heap_caps_free(p_buf_command);
    
        dma_desc_buf_a = NULL;
        dma_desc_buf_b = NULL;
        dma_desc_buf_command = NULL;        
        p_buffer_a = NULL;
        p_buffer_b = NULL;
        p_buf_command = NULL;

        return ESP_ERR_NO_MEM;
    }

    return ESP_OK;
}

ESP_Sprite
Posts: 9766
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Fri Mar 25, 2022 2:06 am

Are you sure you are staying within the limits of the psram throughput? If GDMA can't fetch data fast enough it leads to corruption. Also keep in mind that worst case scenario, the gdma can only use half of the bandwidth of the psram peripheral (as it's round-robin shared with the CPUs).

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 2:08 am

ESP_Sprite wrote:
Fri Mar 25, 2022 2:06 am
Are you sure you are staying within the limits of the psram throughput? If GDMA can't fetch data fast enough it leads to corruption. Also keep in mind that worst case scenario, the gdma can only use half of the bandwidth of the psram peripheral (as it's round-robin shared with the CPUs).
i printed the dma descriptors and they are correct

ESP_Sprite
Posts: 9766
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Fri Mar 25, 2022 2:17 am

Yes, I'm sure they are, but that's not what I'm referring to. You should look at A. the bandwidth of your PSRAM (which is the frequency it runs at, divided by 2 if the PSRAM does not run in octal mode), and B. the maximum bandwidth of your LCD (the pixel clock times the amount of bytes you send out per pixel). If A/2 < B, then your issue is a bandwidth one.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 3:54 am

ESP_Sprite wrote: Yes, I'm sure they are, but that's not what I'm referring to. You should look at A. the bandwidth of your PSRAM (which is the frequency it runs at, divided by 2 if the PSRAM does not run in octal mode), and B. the maximum bandwidth of your LCD (the pixel clock times the amount of bytes you send out per pixel). If A/2 < B, then your issue is a bandwidth one.
Psram is octal(inside chip esp32-s3) and are configureted to 80 MHz.

For now i am only doing the driver(generic one), so i am worried about making it work.

The problem is: what is causing buffer corruption when gdma use psram buffers ?

The data inside buffer may be correct really, i am check it tomorrow. the problem could be in some configuration maybe. Strange that it works with static memory.

The amount of bytes sent seems correct( i measured de transmission time), only the last ~5% at the end of the transmission is corrupted

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 6:15 pm

ESP_Sprite wrote:
Fri Mar 25, 2022 2:17 am
Yes, I'm sure they are, but that's not what I'm referring to. You should look at A. the bandwidth of your PSRAM (which is the frequency it runs at, divided by 2 if the PSRAM does not run in octal mode), and B. the maximum bandwidth of your LCD (the pixel clock times the amount of bytes you send out per pixel). If A/2 < B, then your issue is a bandwidth one.
I am using i8080 interface, ie, the lcd have a controller with frame memory inside the glass( ex: ili9341 low pixel count,i am using another controller ).

The LCD_CAM support RGB format( as far as i know, there is no frame memory in this type of controller, they are called dumb display, so, the LCD_CAM need to refresh ALL pixels in lcd glass at 60 Hz all the time ), so, how do LCD_CAM get bandwidth for that ?
If you use the SRAM, the graphical driver will need to transfer all this information from flash memory to SRAM to render the image in chunks, because the sram memory is small.

For this reason, maybe, it would be interesting to try to use psram.

Is there an example that uses psram for this ?

Also if PSRAM bandwidth is a problem for GDMA(EDMA), gdma should just stall and wait for the information become available and not keep working and corrupt the information.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Fri Mar 25, 2022 11:00 pm

@ESP_Sprite,

LCD_CAM with GDMA(EDMA) with PSRAM:

I tested LCD_CAM with 78125 Hz LCD_PCLK and the problem persists, the last ~5% of data bytes are corrupted.
I tested it with other frequencies too and the same problem.

I also scanned the entire buffers after each new dma transmission and found no corrupted positions, ie all 153600 positions of the two buffers continued with the value 0xffff, so i can say that the problem is not in the memory allocation, neither something was corrupting the buffer data.
The problem must be in something in the integration between LCD_CAM and GDMA(EDMA) when using a PSRAM memory.

Any suggestion ???

Who is online

Users browsing this forum: No registered users and 14 guests