02-14-2018 05:57 PM
I would like to use the SPI peripheral in the PS to communicate with an ADC that has an bidirectional SPI data pin (SDIO). The SPI pins are mapped to EMIO pins since the SPI device is hooked to PL pins.
So far I have instantiated an IOBUF with the following connections.
IOBUF sdio_buf ( .I (SPI_M0_io0_o), .IO (sdio), .O (SPI_M0_io1_i), .T (SPI_M0_io0_t) );
How do you write a driver to control the tristate signal such that the interface works with an SDIO pin instead of separate MOSI and MISO pins?
02-15-2018 12:08 AM
When the interface has a tri-state logic, and tri-state signal is coming from the controller, you need not do anything specific to that in the software/driver. The SPI controller will take care of asserting this signal when ever required.
There is a driver available already.
02-15-2018 12:37 AM
Your IOBUF instantiation is correct. But make sure of which tri-state you have to connect? and weather to connect directly or negation of it?
IOBUF sdio_buf ( .I (SPI_M0_io0_o), .IO (sdio), .O (SPI_M0_io1_i), .T (SPI_M0_io0_t) // .T (SPI_M0_io1_t) // .T (~SPI_M0_io0_t) // .T (~SPI_M0_io1_t) );
02-15-2018 12:46 AM
Issue I'm seeing is that the tristate signal is never going high. Is there something I have to tell to the driver to indicate that I want enable the tristate?
02-15-2018 01:06 AM
Its all up to the software application code. There are some examples in SDK installation area, if you wan tto have a look.
From software application, code has to initialize the controller and initiate transfers.
02-21-2018 03:26 PM
The issue is that Xilinx's XSpiPs driver code does not appear to have any concept of data direction.
When a SPI is enabled in the PS, the PS module has input, output, and tristate-enable ports for each of SCLK, M, S, and SS. Thus I assume that the hardware SPI engine is capable of supporting 3-wire SPI. But there is no data-direction argument to XSpiPs_Transfer() (or XSpiPs_PolledTransfer()). Nor is there any sort of data-direction control-bit in any of the structures defined in xspips.h. The code provided by Xilinx has no mechanism for controlling any of these tristate-enable signals (apart from XSPIPS_MASTER_OPTION, which sets whether the PS-SPI engine is a master or a slave).
To work around this, we've created a register bit in the PL, which software writes to control the tristate-enable of MOSI. For 3-wire read transactions, software uses XSPIPS_FORCE_SSELECT_OPTION and we modified XSpiPs_PolledTransfer() to do two transfers (a command/address write, followed by a data read) with assertion of the tristate-enable in between, with slave-select asserted through the entire transaction. This is obviously a bit "hacky" and would hope a more elegant way is possible.
02-21-2018 07:13 PM
02-22-2018 02:56 PM
Are you saying to use the QSPI Master to talk to the SPI slave?
Even if this was possible, I have 3 such slaves and there is only 1 QSPI slave select line. Also I need to route the SPI signals over EMIO which didn't seem possible when I tried setting it in the GUI.
02-25-2018 10:21 PM
When you configure the controller to be a master, MOSI will be an output, and MISO will be an input. And is same as SPI spec says.
Coming to the driver APIs, for example XSpiPs_PolledTransfer(), which has to be called from SPI master software, has no direction as you said. Because it performs both write and read transfer at a time, and that is the reason why you can provide read_buffer and write_buffer to the API. When this API gets executed SPI master sends the data in write_buffer and fills the read_buffer with data sent by SPI slave. The user has to make sure that, the TXFIFO of SPI slave is filled and is ready to sent the data before this API gets executed on SPI master.