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;
}