ESP32-S3 LCD and I2S FULL documentation

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Thu Feb 10, 2022 7:48 am

Baldhead wrote:
Mon Feb 07, 2022 11:53 pm
ESP_Sprite wrote:
Thu Jan 27, 2022 7:22 am
With that being said, the issue is that I can't really find much wrong with your code... I have a few things you could check, maybe:
- Do you have LCD_CAM_LCD_DUMMY and LCD_CAM_LCD_CMD_2_CYCLE_EN set to 0?
Yes. The default value.

- Not sure if that's 100% sure an issue if it isn't, but is data[] 4-byte aligned ?
I declared data[] statically.
How can i align this data[] ?

- Is there any way you can check your code with actual DMA, instead of pushing into the FIFO? As I said before, we think pushing into the FIFO should work, but it's relatively untested.
I will try as soon as possible.
But the digital team can't give some tips about pushing data into fifo ?
Maybe a hardware test inside espressif.

Fwiw, I have an answer from the digital team... not sure why it should work, but can you try setting LCD_CAM.lcd_misc.lcd_bk_en = 1 ? Alternatively, you could see what happens if you lower PCLK (by disabling lcd_clk_equ_sysclk, for instance)

Edit: The explanation is that when the pclk speed is the same as the module clock (when lcd_clk_equ_sysclk is 1, which happens by default) the DMA/fifo/LCD logic needs a clock cycle too long to fetch the first byte. It's a design flaw that is fixed in future chips.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Wed Feb 16, 2022 1:04 am

Fwiw, I have an answer from the digital team... not sure why it should work, but can you try setting LCD_CAM.lcd_misc.lcd_bk_en = 1 ? Alternatively, you could see what happens if you lower PCLK (by disabling lcd_clk_equ_sysclk, for instance)

Edit: The explanation is that when the pclk speed is the same as the module clock (when lcd_clk_equ_sysclk is 1, which happens by default) the DMA/fifo/LCD logic needs a clock cycle too long to fetch the first byte. It's a design flaw that is fixed in future chips.
Hi @ESP_Sprite,

In fifo mode, only changing "LCD_CAM.lcd_misc.lcd_bk_en = 1" worked.

I need to check if in dma mode it will work without changing clock configurations.
In dma mode i need to change "LCD_CAM.lcd_misc.lcd_bk_en = 1" too ???

************************************************************************
"It's a design flaw that is fixed in future chips"
which chips ?
In esp32-s3 chip yet or in new releases of other chips ???
************************************************************************

With respect to FIFO memory now:

I think fifo memory has a bug that should be fixed too.

Fifo memory should send every byte written and not every 8 bytes written.
Will this be fixed on the esp32-s3 chip?

Thank's.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Wed Feb 16, 2022 3:51 am

Baldhead wrote:
Wed Feb 16, 2022 1:04 am
In fifo mode, only changing "LCD_CAM.lcd_misc.lcd_bk_en = 1" worked.

I need to check if in dma mode it will work without changing clock configurations.
In dma mode i need to change "LCD_CAM.lcd_misc.lcd_bk_en = 1" too ???
From what I can tell, yes.

"It's a design flaw that is fixed in future chips"
which chips ?
In esp32-s3 chip yet or in new releases of other chips ???
Unreleased other chips that I can't talk about yet :P In theory, if the S3 has enough things we want to fix, we could also have a mask revision for that chip, but given the fact that it can be fixed with one bit in a register and fixing things in a mask revision is always risky, I'd assume this flaw will stay in the S3 for the foreseeable time.
With respect to FIFO memory now:

I think fifo memory has a bug that should be fixed too.

Fifo memory should send every byte written and not every 8 bytes written.
Will this be fixed on the esp32-s3 chip?

Thank's.
Can you do me a favour and summarize the exact issue there so I can send it to the digital team directly, and we don't have to go through a game of telephone where I try to summarize your findings in this thread for you? That'll probably help out a lot.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Wed Feb 16, 2022 11:58 pm

Can you do me a favour and summarize the exact issue there so I can send it to the digital team directly, and we don't have to go through a game of telephone where I try to summarize your findings in this thread for you? That'll probably help out a lot.
Hi @ESP_Sprite,

In this function below, data_len must be equal to 8 for the FIFO memory send the bytes to the lcd module(and i/o pin). This way is ok, command(0x02) appear at first clock pulse and data appear in clocks pulse 2,3,4,5,6. Notice that i am filling the fifo with dummy bytes until it completes 8 bytes. Example: send 5 bytes that will appear in the i/o output and 3 dummy bytes to fifo be able to send all bytes to the lcd module.

If data_len < 8, fifo memory dont send data to lcd module. No data at output, only command(0x02) appear at first clock pulse.

If data_len > 8, i dont study the behavior.

Code: Select all

"hw_lcd_dma_tx_push_n_data( 0, data, 8 );"

inline void hw_lcd_dma_tx_push_n_data( uint32_t channel, uint8_t* data, uint32_t data_len )
{ 
    for( uint32_t i = 0 ; i < data_len ; i++ )
    {             
        // while( hw_lcd_dma_L1_fifo_full(channel) );
    
        GDMA.channel[channel].out.push.outfifo_wdata = data[i];  // This register stores the data that need to be pushed into DMA FIFO.
        GDMA.channel[channel].out.push.outfifo_push = 1;         // Set this bit to push data into DMA FIFO.           
    }
}

Code to test inside espressif:
Try changing the last parameter in this function: "hw_lcd_dma_tx_push_n_data( 0, data, 8 );"

Code: Select all

void app_main(void)
{  
    esp_err_t r = hw_lcd_init();
    printf("r = %s\n\n", esp_err_to_name(r));

    uint8_t data[32];

    data[0] = 0x01;
    data[1] = 0x02;
    data[2] = 0x04;
    data[3] = 0x08;
    data[4] = 0xA5;   
    data[5] = 0x00;  
    data[6] = 0x00;  
    data[7] = 0x00;  


    while(1)
    {        
        hw_lcd_write_n_data( 0x02, data, 5 ); 
        vTaskDelay( pdMS_TO_TICKS(1000) );   
    }
}


inline void hw_lcd_write_n_data( uint32_t command, uint8_t* data, uint32_t data_len )      
{   
    LCD_CAM.lcd_user.lcd_always_out_en = 0;  // 0 = fifo mode. 1 = dma mode 
    
    hw_lcd_afifo_reset();
    hw_lcd_dma_tx_fifo_reset( 0 );
    
    LCD_CAM.lcd_user.lcd_dout_cyclelen = data_len - 1;  // 0 = 1 single byte. LCD_CAM.lcd_user.lcd_always_out_en = 0;
        
    LCD_CAM.lcd_user.lcd_cmd = 1;   // R/W; bitpos: [26]; default: 0. 1: Be able to send command in LCD sequence when LCD starts. 0: Disable.  
    LCD_CAM.lcd_user.lcd_dout = 1;  // R/W; bitpos: [24]; default: 0. 1: Be able to send data out in LCD sequence when LCD starts. 0: Disable.
    
    LCD_CAM.lcd_cmd_val.lcd_cmd_value = command;  // R/W; bitpos: [31:0]; default: 0. The LCD write command value. 
    
    hw_lcd_dma_tx_push_n_data( 0, data, 8 );  // hw_lcd_dma_tx_push_n_data( 0, data, data_len );
    
    LCD_CAM.lcd_user.lcd_update = 1;  // R/W; bitpos: [20]; default: 0. 1: Update LCD registers, will be cleared by hardware. 0 : Not care. Update parameters before start transaction.
    LCD_CAM.lcd_user.lcd_start = 1;   // R/W; bitpos: [27]; default: 0. LCD start sending data enable signal, valid in high level.
}


inline void hw_lcd_dma_tx_push_n_data( uint32_t channel, uint8_t* data, uint32_t data_len )
{ 
    for( uint32_t i = 0 ; i < data_len ; i++ )
    {             
        // while( hw_lcd_dma_L1_fifo_full(channel) );
    
        GDMA.channel[channel].out.push.outfifo_wdata = data[i];  // This register stores the data that need to be pushed into DMA FIFO.
        GDMA.channel[channel].out.push.outfifo_push = 1;         // Set this bit to push data into DMA FIFO.           
    }
}


static inline void hw_lcd_afifo_reset()
{
    LCD_CAM.lcd_misc.lcd_afifo_reset = 1;
    LCD_CAM.lcd_misc.lcd_afifo_reset = 0;
}


inline void hw_lcd_dma_tx_fifo_reset( uint32_t channel )
{
    GDMA.channel[channel].out.conf0.out_rst = 1;  // This bit is used to reset DMA channel 0 Tx FSM and Tx FIFO pointer.
    GDMA.channel[channel].out.conf0.out_rst = 0;
}

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Thu Feb 17, 2022 12:17 am

@ESP_Sprite,

I need another instruction to send fifo data to lcd module besides that ?
"GDMA.channel[channel].out.push.outfifo_push = 1;"

// Set this bit to push data into DMA FIFO.
This bit only push data to dma fifo.
It doesn't mean that the dma fifo will dump to the lcd module in this exact moment ???
Need set some another register bit to dma fifo dump to the lcd module in this exact moment ???

Code: Select all

inline void hw_lcd_dma_tx_push_n_data( uint32_t channel, uint8_t* data, uint32_t data_len )
{ 
    for( uint32_t i = 0 ; i < data_len ; i++ )
    {             
        // while( hw_lcd_dma_L1_fifo_full(channel) );
    
        GDMA.channel[channel].out.push.outfifo_wdata = data[i];  // This register stores the data that need to be pushed into DMA FIFO.
        GDMA.channel[channel].out.push.outfifo_push = 1;         // Set this bit to push data into DMA FIFO.           
           
        Will i need to set some bit here to send the fifo data to the lcd module every time i write a new data/byte ?
    }
}
Last edited by Baldhead on Fri Mar 04, 2022 10:23 pm, edited 1 time 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 04, 2022 12:45 am

@ESP_Sprite,

Do you have some position about the last question ?

Or do you have some date to the digital team test and respond me ?

Thank's.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Mon Mar 07, 2022 3:09 am

Sorry, the digital team hasn't answered me yet. I'll ask them again. Again, note that we're not sure if we support the FIFO push feature officially, as it was intended as a debug feature... so it could very well be that no answer is the equivalent of 'we don't know, we did not test this, please use DMA for everything'.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Mon Mar 07, 2022 3:38 am

Got an answer:
It is relative to how the FIFO works in GDMA. There are 3-level FIFOs, namely, L1FIFO, L2FIFO, L3FIFO. Actually, L2FIFO is a larger SRAM.
In order to make the bandwith of SRAM is the same as L1FIFO/L3FIFO. For Tx Channel, the data is transfered from L1FIFO to L2FIFO when the following two conditions are met:
1, there are 8 or more data in L1FIFO;
2, data number in L1FIFO is less than 8, but there is data with eof in L1FIFO.
Note that the FIFO data register is 9-bit, with bit 8 the EOF bit, so I think you should be able to set the 9th bit of the last byte you push and you'd not have to send any dummy bits.

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby Baldhead » Wed Mar 09, 2022 12:44 am

ESP_Sprite wrote:
Mon Dec 27, 2021 2:35 am
Btw:
Why "GDMA.channel[channel].out.push.outfifo_wdata" is 9 bit wide ?
Got a response from the digital team: The 9th bit is the EOF bit. Setting this generates a DMA EOF interrupt when the byte is processed.
"Note that the FIFO data register is 9-bit, with bit 8 the EOF bit, so I think you should be able to set the 9th bit of the last byte you push and you'd not have to send any dummy bits."

Worked, but the interrupt is not being trigged.

Some suggestion ???

I enabled all possible GDMA interrupt and nothing happen.

Code: Select all

esp_intr_alloc( ETS_DMA_OUT_CH0_INTR_SOURCE, 0, hw_lcd_dma_isr_dma_0, NULL, NULL ); 

static IRAM_ATTR void hw_lcd_dma_isr_dma_0(void *args)
{    
    gpio_set_level( (gpio_num_t)my_led_io_13, 1 ); 
            
    uint32_t int_st = GDMA.channel[0].out.int_st.val;
    ESP_EARLY_LOGI(HW_LCD_DMA_TAG, "int_st = %u\n\n", int_st);

    GDMA.channel[0].out.int_clr.val = GDMA.channel[0].out.int_st.val;     
}


    GDMA.channel[0].out.int_ena.out_done = 1;  

    GDMA.channel[0].out.int_ena.out_dscr_err = 1; 

    GDMA.channel[0].out.int_ena.out_eof = 1; 

    GDMA.channel[0].out.int_ena.out_total_eof = 1;

    GDMA.channel[0].out.int_ena.outfifo_ovf_l1 = 1;  

    GDMA.channel[0].out.int_ena.outfifo_ovf_l3 = 1; 

    GDMA.channel[0].out.int_ena.outfifo_udf_l1 = 1; 

    GDMA.channel[0].out.int_ena.outfifo_udf_l3 = 1; 

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

Re: ESP32-S3 LCD and I2S FULL documentation

Postby ESP_Sprite » Wed Mar 09, 2022 3:18 am

I imagine the interrupt that would be triggered if you were to actually use DMA would be the EOF/done interrupt... but I can also imagine it's the actual DMA that triggers that and not the fifo, because if you poke the FIFO directly, you know you wrote an EOF in it, you don't need an interrupt to tell you that.

Who is online

Users browsing this forum: No registered users and 19 guests