Page 9 of 14

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Thu Mar 24, 2022 9:02 am
by ESP_Sprite
No clue, sorry. Perhaps take a look at components/hal/esp32s3/include/hal/clk_gate_ll.h to see how that does it?

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 1:36 am
by Baldhead
dfsdfsdfgsdgsdgfsdfsdfsd

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 1:36 am
by Baldhead
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.

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 1:55 am
by Baldhead
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;
}

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 2:06 am
by ESP_Sprite
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).

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 2:08 am
by Baldhead
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

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 2:17 am
by ESP_Sprite
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.

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 3:54 am
by Baldhead
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

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 6:15 pm
by Baldhead
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.

Re: ESP32-S3 LCD and I2S FULL documentation

Posted: Fri Mar 25, 2022 11:00 pm
by Baldhead
@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 ???