Yes, you have 3 SPI busses on the T4.1 which I show in my excel document: Screen shot
And again you access the pins like SPI.transfer will use your fist set of pins and likewise SPI1.transfer uses the other pins...
Now more to your questions.
If you do something like:
Code:
uint8_t ret = SPI.transfer(0);
And most of the other methods like this in the SPI library, they work by putting one thing on the queue and wait for the thing to transfer and the results come back, so it is only doing one thing at a time...
That is the nature of those APIs as they are setup to be synchronous, so their transfer is done before it returns.
However we did add a version of transfer to the SPI library to allow asyncronous transfers, that looks like:
Code:
bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
We have the event responder object that can be setup to query to see if done, or setup to have it call your function when done, which can be called immediately, or in yield or ...
So if you do something like:
Code:
SPI.transfer(buff1, buff2, size1, event1);
SPI1.transfer(buff3, buff4, size2, event2);
Then both transfers can be happening at the same time, as well as your own user code...
Or you can do it at the lower levels, which is what many of our display drivers do. Easiest thing to see how that is done is to look at one of our drivers like the st7735_t3 code.
Chip Select pins - Note they work differently on T3.x than T4.x.
Now if your code is doing some normal simple things like use the SPI library to do transfers, you typically can use any digital pin as the CS pin for a device.
If you have 3 devices, you simply need to make sure that the right one is asserted before you do the transfer.
However if you are using a driver that tries to speed things up by using the hardware CS pin(pins), than again a lot different on T3.x than T4.x.
Why?
T3.x the stuff is put in the FIFO queue by using the PUSHR register where the lower 16 bits is the data (maybe only 8) and the upper 16 bits encodes other data including which CTAR to use (which usually controls how many bits of data) as well as a mask of which of hardware CS pin/pins to assert/deassert as part of the transfer and if they should be continue to be asserted after the transfer. Note: in this we can have multiple CS pins asserted. Some of our drivers like ili9341_t3 use this to encode both CS and DC pin, which speeds things up. Why? because you can queue up multiple different configurations of data onto the FIFO without having to wait for previous one to complete and not having to wait for completion before changing the CS pin states speeds things up.
it is different on T4.x. Their output FIFO is handled by two different registers. You put stuff to output on the queue using TDR register, which allows you to transfer 1-32 bits of data per transfer. And there is another register TCR which allows you to change things like Word size and which CS pin to assert. And in this case only one CS pin can be asserted.
There is speed ups with some of these drivers if the DC pin is on the hardware CS pin, but most of them don't require you to use it, as for example T4 and T4.1 the main CS pins is pin 10 and most people have driver boards with pin 10 being the CS pin not DC... So was confusing to have to change those.
And on my chart shown you will see that T4.1 added some additional alternate CS pins. Some of which translate to the same logical signal (only one can be used on the system) and others setup as the CSx-1 or CSX-2... which are other unique CS pins for that SPI buss.
Note: one exception to all of this is if you are trying to do a slave device. In this case, which SPI library does not do, you need to use the hardware CS pin to be signaled by the Master SPI device of the transfers and I believe it must be CSx-0 (first defined CS ins...)
Hope that helps
Kurt