How to use the SPI (master) correctly | Cypress Semiconductor
How to use the SPI (master) correctly
(By the way, please don’t say to look at the examples – I have they I cannot see how they cover my situations as described below.)
I am trying to communicate with an MAX3421E (USB Host controller chip) using an SPI (master) component. The bit rate is 3MHz with 8-bit values. At this stage, I'm writing this as a polled interface - at some time in the future (as the project grows) I'll probably need to move to an interrupt driven approach.
There are two situations that I need to handle:
1) I need to read/write individual registers which means that I need to write a command byte and then either a value or dummy for the register value to be written or read.
2) I need to read/write a FIFO with up to 64 values (plus a leading command byte)
In the first case, I receive a 'status' value back as I send the command and, when reading a register, I will receive the register value with the 2nd byte.
In the second case I need to send the command (I can ignore the status value in this situation) and then send or receive up to 64 values from/to memory. When writing my values to the slave, I don’t need anything back so I’m OK with overflowing the FIFO. However I do call “xxx_ClearRxBuffer” afterwards to make sure it is clear before anything else uses the SPI component.
For both cases, I'm using the "xxx_PutArray" function to write the values to the SPI component and the only functions that seem to apply to read the values are "xxx_GetRxBufferSize" and "xxx_ReadRxData".
From what I understand, I need to ensure that there are always values to send to ensure that the \SS\ line stays low for the entire transaction (however many values long)
I have tried using the SPI component both with and without the software buffer and I'm getting different issues with both approaches.
Without the software buffer (using the 4 value FIFO for both Tx and Rx), I can send the 2 values for case #1 and I can receive the status and 2nd value OK. However, for case #2, I *think* it is OK for writing multiple values to the chip's FIFO but I have no idea how to read back the values.
So Question #1: What is the correct way to read back the received values when there are more than will fit into the FIFO.
My trials show that I seem to be able to use this configuration to send my 65 values and the slave gets these OK. However I will certainly overflow the 4-value FIFO. In the situation where I’m trying to read the values back from the I will need to somehow get the values form the FIFO *while* the other values are being sent.
Therefore Question #2: how can I ensure that the \SS\ line is kept low while sending multiple values to the slave AND reading back the received values?
To try to get around the above limitation, I tried using a 65 value software buffer for both Tx and Rx. In case #1 (i.e. 2 values exchanged) I seem to need to look at both the “xxx_GetRxBufferSize” function value (which always seems to be 0) and the “xxx_ReadRxStatus” (and the xxx_STS_RX_FIFO_NOT_EMPTY bit) but that tells me a value is available – but fails to say there is a 2nd value received. It is as though the software buffer is not used for receiving as both values fit into the FIFO but I only seem to be able to read the first!
So, Question #3: how should you read fewer values (i.e. that will fit into the FIFO and not need the software buffer) when the software buffer is enabled?
Which also leads to Question #4: Is the only option to not use the \SS\ output of the device and manually handle this output pin in my code? Alternatively are there APIs that let me manipulate the \SS\ manually?