I have a 2.8" capacitive TFT screen from and a PN532 RFID reader from Adafruit. The problem is, they both use SPI. When I use the RFID reader, the screen goes completely white and I have to restart the Pi to get the image back. I have to use the SPI interface on the reader so that I can use the Adafruit library to use it with Python. The screen going white isn't a problem as long as it's only when the RFID reader is in use. Is there anyway to "restart" the screen after using the RFID reader? Any help is appreciated.
A SPI bus consists of 3 wires + 1 chip select signal per individually addressable slave on the SPI bus. Some devices, for example NeoPixels, many DACs, every shift register, etc. allow for daisy chaining, where a chain of devices may share a common chip select line.
However in your case you most certainly want to address devices that don't support daisy chaining. So each device requires an individual chip select line.
Let's first recapitulate, how a SPI bus works.
SPI transfers typically look like this
/CS ‾‾‾\___________________ . . . ___________/‾‾‾
CLK _____/‾‾‾\___/‾‾‾\___/‾ . . . ‾‾\____________
MOSI =====X=======X=======X= . . . ===============
MISO =========X=======X===== . . . ==X============
i.e. first the chip select (/CS
) goes low, then the MOSI (master out → slave in) data lines are set to the next bit to be transferred and on the rising clock edge, and on the falling clock edge the slave reads that bit. Similarly on the falling clock edge the slave pulls the data line for the master to read on the rising endge.
However some devices require inverted clock polarity or expect different timings on MOSI/MISO. However the timings as outlined above are what works for most and which I've usually do when bitbanging.
The purpose of the /CS
line is to delimit a bus transaction. A falling /CS
begins a transaction, a rising one ends it. Which in essence means: If a device does not see a falling /CS
it will simply ignore everything that happens on the other lines.
So the first thing to wonder with a problem like your is: "Am I addressing my SPI slaves using different /CS
signals, and if so, is the timing correct?" The must have debugging tool for issues like that is an oscilloscope; preferrably one with 4 channels.
Your Raspberry-Pi has a couple of GPIO pins. Each of them technically can be used for a /CS
signal. However often SPI transfers are controlled by devices and/or drivers which want to use a very specific pin for /CS
. I'm not familiar with the Adafruit library, if it has such an expectancy. However if you can configure a "chip select" (CS), "slave select" (SS) or "chip enable" (CE) signal in the library, then this is where you specify, which GPIO you're using as /CS
for the device in question.
If you can't configure it like that, there's always the option to use a hardwired AND gate on the /CS
signal. The foolproof and robust solution is to use 74HCx series gate, however this comes with a lot of redundant wires. A slightly more elegant solution is to use a logic demultiplexer like a 74HC154 where you connect /CS
to the /EN
pins and using 4 GPIO lines can address to which of the 16 outputs the /CS
signal gets routed.
However there's also a dead-cheap variant called wired OR. Remeber that the usual convention for /CS
is to be pulled low. So what you can do is us a couple of resistors – and if you can't tristate your GPIO pins a few diodes – to force the /CS
signal up for the devices you don't want to address. See https://en.wikipedia.org/wiki/Wired_logic_connection for details on that.
So I've had a quick look at the library hosted here https://github.com/adafruit/Adafruit_Python_PN532 and right in the example there's this https://github.com/adafruit/Adafruit_Python_PN532/blob/feaf22f659731586adc9ded4af969bb256969ed3/examples/readmifare.py#L28
# Setup how the PN532 is connected to the Raspbery Pi/BeagleBone Black.
# It is recommended to use a software SPI connection with 4 digital GPIO pins.
# Configuration for a Raspberry Pi:
CS = 18
MOSI = 23
MISO = 24
SCLK = 25
So not only is this library in question using not tied to a dedicated SPI peripheral, you can actually freely configure which GPIO pins to use, to talk to the RFID reader.