Hi, it’s me again.
In a previous post about “SPI demo not working” valter.tx helped me splendid to get the SPI working. After this I wrote some code to interface with an SPI IO expander (MCP23S08). However during this code writing I came across some odd quirks or even maybe bugs because I didn’t read anything about this behavioral, let me explain.
When initializing the SPI with the following command:
Imx6Spi_SetConfigInt(SPI, L"BitsPerWord", 32, StoreVolatile);
When this setting is used the output of the MOSI is as expected:
Bytes to send: 0x01 0x02 0x03 0x04
Bytes read on an oscilloscope: 0x01 0x02 0x03 0x04
*Downside of this is that you will need to send bytes in multiple of 4, otherwise you run the risk of overwriting another register if the device allows sequential write/read.
However initialising the SPI with the following command:
Imx6Spi_SetConfigInt(SPI, L"BitsPerWord", 8, StoreVolatile);
When this setting is used the output of the MOSI is NOT as expected:
Bytes to send: 0x01 0x02 0x03 0x04
Bytes read on an oscilloscope: 0x04 0x03 0x02 0x01
As you can see the bytes are swapped. It isn’t a real problem but you have to find it first.
*The advantage of this that you can send bytes that are not multiple of 4. But there is a catch I discovered.
The catch is, that you still have to send out bytes that are multiple of 4. Because when I tried to send 3 bytes, they were send in a complete different (maybe even random) order. If I remember it correctly:
Bytes to send: 0x01 0x02 0x03 (0x04 ← added to stuff it to a full DWORD but will not be send).
Bytes read on an oscilloscope: 0x03 0x02 0x04 0x01
I tried and measure it multiple times, but the same results where visible. If you keep in mind those quirks I got my IO expander to work.
In addition I also measured the execution time of mine SPI routing (writing to six IO expanders as fast as possible). The routine is sending to 6 IO expanders 4 bytes to update the output and than invert the value and send again, this was done in a loop.
To my surprise there was also a big time different between using 32 and 8 “BitsPerWord”.
For one step in the loop with 32 “BitsPerWord” the execution time is ~0.28 ms.
For one step in the loop with 8"BitsPerWord" the execution time is ~31.6 ms.
This lead me to wonder how fast, or in my case, how slow is the SPI. Going with ~0,28 ms, for 6 SPI write cycles with each 4 bytes, this will results in ~46,6 us for one SPI write with 4 bytes.
When calculating how long SPI will need to send this, it’s ~3,2 us. So there is an overhead of ~43,4 us.
I know there is some overhead involved to process the code and send it by SPI, but in my opinion the overhead takes rather long.
Am I correct to assume this is the min overhead time or is there a way to get it going much faster or would Linux a better option for this?
I know it’s a long post, but I appreciate the help and want to explain it fully to my extend. Therefore you can find the code I used for this here: https://share.toradex.com/wt2hfsi47row4cn
Also I added to measured time in the code as comments.
Kind regards,
Remco