Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Hi all,
I try to use VSPI in QSPI mode to increase communication speed.
ESP32 can write out register address, but when it reads back register data, IO2 bit is always read as 0 although it is 1 in a probed waveform.
Here is my code to configure VSPI in QSPI mode:
spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num = GPIO_NUM_19,
.mosi_io_num = GPIO_NUM_23,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_22,
.quadhd_io_num = GPIO_NUM_21,
.max_transfer_sz= 16*320*2+8
};
spi_device_interface_config_t devcfg={
.clock_speed_hz = 1*1000*1000,
.mode = 0,
.spics_io_num = -1,
.queue_size = 7, //We want to be able to queue 7 transactions at a time
.flags= SPI_DEVICE_HALFDUPLEX,
};
//Initialize the SPI bus
ret = spi_bus_initialize(VSPI_SPI_HOST, &buscfg, 0);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add QSPI device");
return false;
}
ret=spi_bus_add_device(VSPI_SPI_HOST, &devcfg, &SPIM);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add QSPI device");
return false;
}
//Configure CS pin
gpio_config_t io_conf = {
.intr_type = GPIO_PIN_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1LL << GPIO_NUM_5,
};
ret = gpio_config(&io_conf);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add CS pin");
return FALSE;
}
gpio_set_level(GPIO_NUM_5, 1);
//Test to read data of a register
gpio_set_level(GPIO_NUM_5, 0); //active CS
//send register addr
spi_transaction_t trans;
memset(&trans, 0, sizeof(trans));
trans.tx_buffer = reg_addr; //point to user buffer for Tx data
trans.rxlength = 0;
trans.length = 3*8; //3bytes of reg addr
trans.flags = 0;
trans.rx_buffer = NULL;
trans.flags |= SPI_TRANS_MODE_QIO;
spi_device_transmit(SPIM, &trans);
//read back reg data
memset(&trans, 0, sizeof(trans));
trans.tx_buffer = NULL;
trans.length = 0;
trans.flags = 0;
trans.rx_buffer = ®_data;
trans.rxlength = 4 * 8; //readback 4 bytes
trans.flags |= SPI_TRANS_MODE_QIO;
spi_device_transmit(SPIM, &trans);
The register addr is 0x3020C0 and the expected register data is 0xFFEE. However, ESP32 reads back as 0xBBAA ( all IO2 bits are read as 0). If IO2 bits are read as 1 then, it will return 0xFFEE which is expected.
I capture the waveform to check, IO2 bits are correctly output by slave device, but ESP32 always read as 0s.
I attach the waveform here. Note that in reading reg data phase, it reads 4 bytes but uses last 2 bytes (that requirement comes from the slave device.
Here is the print log from ESP32 showing that it reads back reg data as 0xBBAA
I (2183) GPU: Send 30,20,c0[3020c0]
I (2183) GPU: Rd16=aa,0,aa,bb
E (2183) FT8XX: Failed to check REG_PLAYBACK_FREQ[bbaa]
Should I miss anything? Is there any bugs in SPI driver in QSPI mode?
Please help.
Thanks,
Huy
I try to use VSPI in QSPI mode to increase communication speed.
ESP32 can write out register address, but when it reads back register data, IO2 bit is always read as 0 although it is 1 in a probed waveform.
Here is my code to configure VSPI in QSPI mode:
spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num = GPIO_NUM_19,
.mosi_io_num = GPIO_NUM_23,
.sclk_io_num = GPIO_NUM_18,
.quadwp_io_num = GPIO_NUM_22,
.quadhd_io_num = GPIO_NUM_21,
.max_transfer_sz= 16*320*2+8
};
spi_device_interface_config_t devcfg={
.clock_speed_hz = 1*1000*1000,
.mode = 0,
.spics_io_num = -1,
.queue_size = 7, //We want to be able to queue 7 transactions at a time
.flags= SPI_DEVICE_HALFDUPLEX,
};
//Initialize the SPI bus
ret = spi_bus_initialize(VSPI_SPI_HOST, &buscfg, 0);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add QSPI device");
return false;
}
ret=spi_bus_add_device(VSPI_SPI_HOST, &devcfg, &SPIM);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add QSPI device");
return false;
}
//Configure CS pin
gpio_config_t io_conf = {
.intr_type = GPIO_PIN_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1LL << GPIO_NUM_5,
};
ret = gpio_config(&io_conf);
if(ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to add CS pin");
return FALSE;
}
gpio_set_level(GPIO_NUM_5, 1);
//Test to read data of a register
gpio_set_level(GPIO_NUM_5, 0); //active CS
//send register addr
spi_transaction_t trans;
memset(&trans, 0, sizeof(trans));
trans.tx_buffer = reg_addr; //point to user buffer for Tx data
trans.rxlength = 0;
trans.length = 3*8; //3bytes of reg addr
trans.flags = 0;
trans.rx_buffer = NULL;
trans.flags |= SPI_TRANS_MODE_QIO;
spi_device_transmit(SPIM, &trans);
//read back reg data
memset(&trans, 0, sizeof(trans));
trans.tx_buffer = NULL;
trans.length = 0;
trans.flags = 0;
trans.rx_buffer = ®_data;
trans.rxlength = 4 * 8; //readback 4 bytes
trans.flags |= SPI_TRANS_MODE_QIO;
spi_device_transmit(SPIM, &trans);
The register addr is 0x3020C0 and the expected register data is 0xFFEE. However, ESP32 reads back as 0xBBAA ( all IO2 bits are read as 0). If IO2 bits are read as 1 then, it will return 0xFFEE which is expected.
I capture the waveform to check, IO2 bits are correctly output by slave device, but ESP32 always read as 0s.
I attach the waveform here. Note that in reading reg data phase, it reads 4 bytes but uses last 2 bytes (that requirement comes from the slave device.
Here is the print log from ESP32 showing that it reads back reg data as 0xBBAA
I (2183) GPU: Send 30,20,c0[3020c0]
I (2183) GPU: Rd16=aa,0,aa,bb
E (2183) FT8XX: Failed to check REG_PLAYBACK_FREQ[bbaa]
Should I miss anything? Is there any bugs in SPI driver in QSPI mode?
Please help.
Thanks,
Huy
- Attachments
-
- QSPI_waveform.png (38.49 KiB) Viewed 10548 times
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Aren't you missing flags in transaction struct?
SPI_USE_TXDATA, SPI_USE_RXDATA
Also your receive code is wrong rx_data contains already allocated bytes from interrupt.
Try this
SPI_USE_TXDATA, SPI_USE_RXDATA
Also your receive code is wrong rx_data contains already allocated bytes from interrupt.
Try this
//send register addr
spi_transaction_t trans;
memset(&trans, 0, sizeof(trans));
trans.tx_buffer = reg_addr; //point to user buffer for Tx data
trans.rxlength = 3*8;
trans.length = 3*8; //3bytes of reg addr
trans.rx_buffer = NULL;
trans.flags |= SPI_TRANS_MODE_QIO | SPI_USE_TXDATA;
spi_device_transmit(SPIM, &trans);
//read back reg data
memset(&trans, 0, sizeof(trans));
trans.length = 4*8;
trans.rxlength = 4 * 8; //readback 4 bytes
trans.flags |= SPI_TRANS_MODE_QIO | SPI_USE_RXDATA;
spi_device_transmit(SPIM, &trans);
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Hi,
I do not use SPI_USE_TXDATA, SPI_USE_RXDATA flags because I want to define a generic SPI Tx/Rx functions that can transfer arbitrary buffers from other modules. Besides, I check the SPI driver code and see that these flags is just to define whether SPI driver should use data from its internal 4-bytes buffer or from external larger buffer. So it may not relate to the issue here.
Should I miss anything?
Thanks,
Huy
I do not use SPI_USE_TXDATA, SPI_USE_RXDATA flags because I want to define a generic SPI Tx/Rx functions that can transfer arbitrary buffers from other modules. Besides, I check the SPI driver code and see that these flags is just to define whether SPI driver should use data from its internal 4-bytes buffer or from external larger buffer. So it may not relate to the issue here.
Should I miss anything?
Thanks,
Huy
Last edited by huykhacnguyen on Mon May 21, 2018 9:00 am, edited 3 times in total.
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
That may not true. As I check, the SPI driver will record my Rx buffer so that it can write received data into in interrupt.Also your receive code is wrong rx_data contains already allocated bytes from interrupt.
Anyway, I will give a try to double check my understanding.
Thanks
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Anyways - that's what I observed - there is already a memory data to be read in form of uint8_t rx_data[4]
I am not sure if it is DMA related
I am not sure if it is DMA related
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Yes, you can read every 4bytes for each transaction if you specify the flag SPI_USE_RXDATA, if you want to read more data in one transaction, SPI_USE_RXDATA should not be used and you can input an user-defined RX buffer to store received data. That is what I read from the code.Anyways - that's what I observed - there is already a memory data to be read in form of uint8_t rx_data[4]
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Then your settings are missing something. Probably larger buffers must be allocated certain way with certain malloc
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Yes, I think something missing, but dont know what is it
Need help from community to solve this, not only for me, but also for others if they want to use QSPI mode because I see ESP32 does not have example code for SPI in QSPI mode.
Need help from community to solve this, not only for me, but also for others if they want to use QSPI mode because I see ESP32 does not have example code for SPI in QSPI mode.
-
- Posts: 11
- Joined: Mon May 07, 2018 2:38 pm
Re: Why IO2 of VSPI in QSPI mode is always read as 0 in Receiving phase?
Just found this ticket, maybe my issue is related to a bug in SPI driver
https://github.com/espressif/esp-idf/issues/1736
https://github.com/espressif/esp-idf/issues/1736
Who is online
Users browsing this forum: No registered users and 61 guests