SPI chip select

Status
Not open for further replies.

metalgimp

Active member
Can anyone explain why on the ili9341 the LCD must use one of the SPI CS lines but the touch digitizer does not? That indicates to me that I should be able to use any data line for the LCD as well.
 
Depends. If you use the Adafruit_ili9341 library you can probably use any IO pin.

Short answer because it allows you to speed things up.

Longer answer:

However if you want speed and therefore use the ili9341_t3 library or the like, you must use two hardware SPI pins. Why?

This library does not use the SPI library to do the actual transfers, but instead talks directly to the hardware. So if you look at one of the hardware manuals such as for the Teensy 3.2 at the SPI chapter (45).

And you look at the PUSHR register, that pushes data onto the FIFO queue, you will see this 32 bit register contains up to 16 bits of data to transfer. But in addition to this there is the PCS field, which is 6 bits, which says which of these CS signals you wish to assert as part of this transfer, plus the CONT bit which says if these signals should stay asserted after the transfer is complete.

The ili9341_t3 library makes use of using 2 of these Signals, one for DC and one for CS. My version of the ili9341_t3n can also work with just one of these if used for DC and one of my Pull Requests would allow this as well in the _t3 library.

How does this help? It helps allow you to keep the SPI pins fully working with minimal gaps in output.

Simple example suppose you call draw pixel, lets says 0, 0 to white (0xffff). This generates SPI data stream something like:
<CASET> 0 0 0 0 <PASET> 0 0 0 0 <RAMW> 0xff 0xff

In the above assume CS is asserted through the command and the <> are command bytes and must have DC asserted here but not for data bytes/words

With normal SPI, we would do this by doing:
Assert CS (digitalWrite)
Assert DC
Transfer byte: CASET
Wait for transfer to complete
Deassert DC
transfer 0 0 0 0(note we could do this as 4 bytes or as two words)
Wait for these to complete
Assert DC
...

So around each output of command we have to wait until the last bit of a command is output, then we change the state of the DC line. This leaves gaps in the output on the SPI pins.

With using PUSHR we can simple do this by
PUSHR <CASET> <ASSERT DC CS> <CONT bit>
PUSHR 16 bit 0 <ASSERT CS> <CONT>
PUSHR 16 bit 0 <ASSERT CS>
PUSHR <PASET> <ASSERT DC CS> <CONT>
...
PUSHR 16 bit 0xffff <ASSERT CS> (Not CONT)

And the SPI subsystem will take care of changing the DC SIGNAL just around the commands bytes, without gaps, except for the defined gap that you can set.... There are other things I did not mention here like checking to make sure you have room in queue.... And how POPR works, to retrieve your data...

As for the Touch code, it uses the basic SPI library, which relies on using digitalWrite to set the CS pin.

Kurt
 
Excellent.

It sounds like your library should be more efficient. Perhaps I should consider yours instead. AND it might be a good idea to use CS for touch as well.

Thank you.
 
Excellent.

It sounds like your library should be more efficient. Perhaps I should consider yours instead. AND it might be a good idea to use CS for touch as well.

Thank you.

There are only 5 special CS pins for the SPI port on the Teensy 3.2 (technically there are 9, but for four pairs of pins, you can only use 1 of the pair as a CS/DC pin). See the following for more details:

The pins (for 3.2) are:
  • 2 or 10
  • 6 or 9
  • 15/A1
  • 20/A6 or 23/A9
  • 21/A7 or 22/A8

Unlike a display where you are pumping out lots and lots of data, I suspect touch input does not need to be done super-fast, and a normal CS pin would be adequate.
 
Status
Not open for further replies.
Back
Top