Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOCUMENATION] [QUESTION] Purpose of uDMA QSPI Full-Duplex Command #325

Open
cookpate opened this issue Oct 10, 2023 · 4 comments
Open

[DOCUMENATION] [QUESTION] Purpose of uDMA QSPI Full-Duplex Command #325

cookpate opened this issue Oct 10, 2023 · 4 comments
Assignees
Labels
question Further information is requested

Comments

@cookpate
Copy link

In the QSPI documentation, this notice is at the bottom of the implementation section:

The major limitation is the lack of support for the full duplex transfers.

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?

+------+----------------------+-------+----------------------------------------------------+
| 0xC | SPI_CMD_FULL_DUPL | | Activate full duplex mode |
+------+----------------------+-------+----------------------------------------------------+
| | DATA_SIZE | 15:0 | N-1, where N is the number of bits to send |
+------+----------------------+-------+----------------------------------------------------+
| | | | (max 64K) |
+------+----------------------+-------+----------------------------------------------------+
| | LSB | 26:26 | 0x0: Data is LSB first |
+------+----------------------+-------+----------------------------------------------------+
| | | | 0x1: Data is MSB first |
+------+----------------------+-------+----------------------------------------------------+

@MikeOpenHWGroup MikeOpenHWGroup added the question Further information is requested label Oct 10, 2023
@MikeOpenHWGroup
Copy link
Member

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?

@rawalexe
Copy link

rawalexe commented Oct 19, 2023

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.

@MikeOpenHWGroup
Copy link
Member

Hi @rawalexe, thanks for your interest in the CORE-V-MCU. You are asking a good question, but (there is always a "but"):

  1. I am not the right person to ask about this. I am a SystemVerilog jockey and definitely not the right person to answer your question.
  2. Your question is related to, but not the same as, the original questions posted in this Issue. Please create another issue for your question, and I'll help you find the right person to answer it.

@rawalexe
Copy link

Hello @MikeOpenHWGroup ,
Thank you and I have now created a new issue here: #326

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants