Did anyone find a solution for this. I am having the same problem. I am implementing an LCD driver
Below is a section of the code.
When I use the functions Lcd_Cmd or Lcd_Data, the SPI transaction is fast, but there is a 15mS delay before the function completes and returns. Any ideas on how to speed up the time between transactions?
Code: Select all
/******************************************************************************
* FUNCTION: Lcd_InitSpi
*
* DESCRIPTION: Initialize the SPI connection to the LCD
*
* PARAMETERS:
*
* RETURN: None
******************************************************************************/
void Lcd_InitSpi(void)
{
esp_err_t ret;
spi_bus_config_t buscfg =
{
.miso_io_num=PIN_NUM_MISO,
.mosi_io_num=PIN_NUM_MOSI,
.sclk_io_num=PIN_NUM_CLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
.max_transfer_sz=PARALLEL_LINES*320*2+8
};
spi_device_interface_config_t devcfg =
{
.clock_speed_hz=10*1000*1000, //Clock out at 10 MHz
.mode=0, //SPI mode 0
.spics_io_num=PIN_NUM_CS, //CS pin
.queue_size=7, //We want to be able to queue 7 transactions at a time
.pre_cb=Lcd_SpiPreTransferCallback, //Specify pre-transfer callback to handle D/C line
};
/* Initialize the SPI bus */
ret = spi_bus_initialize(LCD_HOST, &buscfg, DMA_CHAN);
ESP_ERROR_CHECK(ret);
/* Attach the LCD to the SPI bus */
ret = spi_bus_add_device(LCD_HOST, &devcfg, &Lcd_Spi);
ESP_ERROR_CHECK(ret);
}
/******************************************************************************
* FUNCTION: Lcd_InitDriver
*
* DESCRIPTION: Initialize the LCD Driver
*
* PARAMETERS:
*
* RETURN: None
******************************************************************************/
void Lcd_InitDriver(void)
{
int cmd = 0;
const lcd_init_cmd_t* lcd_init_cmds;
/* Set IM pins to SPI Interface */
gpio_set_direction(PIN_NUM_IM1, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_NUM_IM2, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_NUM_IM3, GPIO_MODE_OUTPUT);
gpio_set_level(PIN_NUM_IM1, 1);
gpio_set_level(PIN_NUM_IM2, 1);
gpio_set_level(PIN_NUM_IM3, 1);
/* Initialize non-SPI GPIOs */
gpio_set_direction(PIN_NUM_DC, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_NUM_BCKL, GPIO_MODE_OUTPUT);
/* Reset the display */
gpio_set_level(PIN_NUM_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(PIN_NUM_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS);
/* detect LCD type */
if ( Lcd_GetId() == 0 )
{
/* ID zero = ILI9341 graphics chip */
lcd_init_cmds = ili_init_cmds;
}
else
{
/* ID non-zero = ST7789V graphics chip */
lcd_init_cmds = st_init_cmds;
}
/* Send all initialization commands */
while (lcd_init_cmds[cmd].databytes != 0xff)
{
Lcd_Cmd(lcd_init_cmds[cmd].cmd);
Lcd_Data(lcd_init_cmds[cmd].data, lcd_init_cmds[cmd].databytes & 0x1F);
if (lcd_init_cmds[cmd].databytes & 0x80)
{
vTaskDelay(100 / portTICK_RATE_MS);
}
cmd++;
}
/* Enable backlight */
gpio_set_level(PIN_NUM_BCKL, 0);
}
/******************************************************************************
* FUNCTION: Lcd_Cmd
*
* DESCRIPTION: Send a command byte through the SPI to the LCD
*
* PARAMETERS: spi - Pointer to SPI instance
* cmd - CommandByte to be sent
*
* RETURN: None
******************************************************************************/
void Lcd_Cmd(const uint8_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); // Zero out the transaction
t.length = 8; // Command is 8 bits
t.tx_buffer = &cmd; // The data is the cmd itself
t.user = (void*)0; // D/C needs to be set to 0
ret = spi_device_polling_transmit(Lcd_Spi, &t); // Transmit!
assert(ret == ESP_OK); // Should have had no issues.
}
/******************************************************************************
* FUNCTION: Lcd_Data
*
* DESCRIPTION: Send data bytes to the LCD over the SPI interface
*
* PARAMETERS: spi - Pointer to SPI instance
* data - pointer to data buffer
* len - number of data bytes to send
*
* RETURN: None
******************************************************************************/
void Lcd_Data(const uint8_t *data, int len)
{
esp_err_t ret;
spi_transaction_t t;
if (len == 0)
{
return; // no need to send anything
}
memset(&t, 0, sizeof(t)); // Zero out the transaction
t.length = len*8; // Len is in bytes, transaction length is in bits.
t.tx_buffer = data; // Data
t.user = (void*)1; // D/C needs to be set to 1
ret = spi_device_polling_transmit(Lcd_Spi, &t); // Transmit!
assert(ret == ESP_OK); // Should have had no issues.
}