Open cookpate opened 1 year ago
Hi @cookpate. I spoke with Mike Aronson of RumbleDev and he's never heard of full-duplex QSPI. Single-bit SPI can be full duplex, with one input and one output line, transferring one bit each direction per clock. QSPI uses those 2 lines, and 2 others, in a half-duplex manner to transfer 4 bits per clock.
You are right that the RTL supports control for full-duplex in the command-buffer, see line 188 in udma_spim_ctrl.sv, but my read of the RTL is that configuring the module for quad mode automatically disables full-duplex (see udma_spim_ctrl.sv and udma_spim_txrx.sv). So it seems that the Mike Aronson is correct and full-duplex mode is not supported for QuadSPI, but is supported for SPI-mode operation (if s/w emables it).
Clearly the documentation is either confusing or just plain wrong. I would suggest changing the line:
The major limitation is the lack of support for the full duplex transfers.
to
Full duplex transfers are only supported in single-bit SPI mode. QSPI transfers are half-duplex.
Can you confirm that single-bit SPI works in full-duplex?
Hello @MikeOpenHWGroup, I am trying to turn on the full duplex mode using the udma driver, Can you please share the sequence in which the registers expect to enable the full duplex mode, I have currently setup my code to work as below for an attempt to full duplex read ,
#define WORD_PER_TRANSFER 4 // 1, 2 or 4 is only supported
#define WORD_SIZE 8
.
.
*pcmd++ = kSPIm_Cfg | clk_divisor;
*pcmd++ = ( uint32_t ) kSPIm_SOT | chipSelect; // cs 0
*pcmd++ = kSPIm_TxData | ( ( WORD_PER_TRANSFER << 20 ) |
( ( WORD_SIZE - 1 ) << 16 ) |
( xBytes - 1 ) ); // user size to transfer
*pcmd++ = kSPIm_RxData | ( ( WORD_PER_TRANSFER << 20 ) |
( ( WORD_SIZE - 1 ) << 16 ) |
( xBytes - 1 ) ); // user size recieved
*pcmd++ = ( uint32_t ) kSPIm_FDX | ( xBytes - 1 );
*pcmd++ = ( uint32_t ) kSPIm_EOT | 1; // generate event
iot_spi_handler->udma->tx_saddr = ( uintptr_t ) pdataWrite;
iot_spi_handler->udma->tx_size = xBytes - 1;
iot_spi_handler->udma->tx_cfg_b.datasize = 2;
iot_spi_handler->udma->tx_cfg_b.en = 1;
iot_spi_handler->udma->rx_saddr = ( uintptr_t ) pdataRead;
iot_spi_handler->udma->rx_size = xBytes;
iot_spi_handler->udma->rx_cfg_b.en = 1;
iot_spi_handler->udma->cmd_saddr = ( uintptr_t ) auccmd_tx_write;
iot_spi_handler->udma->cmd_size = ( uint32_t ) ( pcmd -
auccmd_tx_write ) *
sizeof( *pcmd );
iot_spi_handler->udma->cmd_cfg_b.en = 1; // initiate the transfer
.
.
I took a reference from the working half duplex example and try to extend it for full duplex example, However, the drive does not work as expected of a full duplex driver.
Hi @rawalexe, thanks for your interest in the CORE-V-MCU. You are asking a good question, but (there is always a "but"):
Hello @MikeOpenHWGroup , Thank you and I have now created a new issue here: https://github.com/openhwgroup/core-v-mcu/issues/326
In the QSPI documentation, this notice is at the bottom of the implementation section:
https://github.com/openhwgroup/core-v-mcu/blob/12bc79e8b2fd4975db1d998a00a936b5ff5bd3d9/docs/doc-src/ip-blocks/udma_qspim.rst?plain=1#L40
Does this apply to both single-bit SPI and QSPI? If so, why is there a command in the control buffer section to enable full-duplex? Does this expect that a configured buffer can be used for both TX and RX? How is this specified?
https://github.com/openhwgroup/core-v-mcu/blob/12bc79e8b2fd4975db1d998a00a936b5ff5bd3d9/docs/doc-src/ip-blocks/udma_qspim.rst?plain=1#L276-L286