SPI Master is not working properly | Cypress Semiconductor
SPI Master is not working properly
The SPI Master control component does not work properly.
If I have an SPI Master component in my design, properly connected to some I/O Pins and try to send an Array of data to it, even if the size of the array easily fits into the defined buffer, then the SPI Component drops the SS line between each byte being output.
I believe that this is a bug in the implementation of the component.
The SS line should not be dropped bewteen bytes, as this signals the end of the transmission to the slave.
It makes it impossible to do sequential writes or reads to slave devices.
There are two possible work arounds that I can see:
1. Manually control the SS I/O Pin, but this is always going to be sub-optimal and some slave devices may not like the timing.
2. Manually disable / re-enable the TXInterrupt - but I do not think this will work, if using a buffer bigger than 4 bytes, then the SPIM_WriteTxData() method forcibly re-enables the interrupt anyway. And SPIM_PutArray() calls SPIM_WriteTxData().
So the SPI Master control does not work as intended unless you manually control the SS line. To do that you'd need to add an OR gate and an extra Output Pin (without hardware connection) or Control register to your design.
Having looked at the generated source I believe I can see what is happening...
When you use SPIM_PutArray() to write a numebr of bytes over SPI, it calls SPIM_WriteTxData() which in turn enables the TX Interrupt. The TX Interrupt fires and transfers the byte out the SPI Master. It then looks to see if there is any more data in the buffer - if not, then it releases the SS line. This happens while SPIM_PutArray() is still trying to write data into the buffer, but happens so quickly that it outruns the PutArray loop and the SS line gets released while data is still being added to the output buffer.
The fix would be to not call SPIM_TxWriteData until the buffer had been filled. If the array is to big to fit into the buffer, then as much as possible should be copied in, then an OVERFLOW error bit should be set and an error result returned (or, like POSIX writes) the actual number of bytes added to the buffer should be returned. Only when SPIM_PutArray() is done adding to the buffer should the TX Interrupt be enabled.