This video provides an overview of the project, demonstrating 5 SPI devices being driven from a Raspberry Pi simultaneously, using a 74HC139 2-4 line decoder. A 128x64 OLED SPI display is driven, plus two 8 line A-D converters and two 16 bit GPIO extenders.
Control up to 8 SPI devices with a 2-4 line decoder like 74HC139, 16 devices with two 3-8 line decoders like 74HC138, 32 devices with two 4-16 line decoders like 74HC154. Or combination of one or two decoder chips.
A video demonstrating example Python source code to interface with the RPiSPi driver.
Demonstrating driving the SSD1306 128x64 OLED SPI display.
Also MCP3008 SPI 8 channel A-D converter.
And the MCP23S17 SPI 16 bit GPIO extender.
Finally RAW generic driving for any other SPI devices.
A demonstration video of an actual application for the RPiSPi Driver. Showing an Asteroids game playing on a 128x64 OLED SPI display, and a MCP23S17 SPI GPIO extender as button inputs for controls.
If interested, you can find the same source code converted into other languages and for other platforms here: Coding a Technology
VIDEO 2016-12-21 V1.03 Update now allowing up to two demultiplexers to be connected. Allowing up to 32 SPI devices to be controlled by the driver.
The video demonstrates two 2-4 line demultiplexers being used to drive five OLED displays and a 16 bit GPIO port extender. The driver has a buffer for each OLED display used, so it can drive up to 32 of these SSD1306 128x64 OLED displays.
Added additional Python source code examples, and updated existing examples.
With the 74HCxxx series of devices, the HC means high speed CMOS, these devices can run directly from the Raspberry Pi 3V3 supply and require no additional external components. When selecting a decoder chip this is important. Also that the outputs are normally high and active low, as this is typically how SPI device, chip select pins are active.
On the decoder IC, set all of the active low chip enable pins to the Raspberry Pi SPI GPIO pin 8 (CE0). When using two decoders, the second decoder will go to the Raspberry Pi SPI GPIO pin 7 (CE1). Any active high chip enable pin will need to be tied to 3V3, refer to the data-sheet for the device.
Depending on the device 2-4, 3-8 or 4-16 line decoder, two, three, or four Raspberry Pi GPIO pins will be required as the inputs to the decoder IC.
Not all of the outputs of the decoder IC need to be used. Anything from one to all of them can be connected to SPI devices. So if 4-16 line decoders cost the same as 3-8 line, why not use a 4-16 line decoder and allow for more devices to be connected at will in future.
Once the SPI devices have a CS signal, they just require the three other SPI lines from the Raspberry Pi to be connected to them. MOSI, to allow data to go from the Raspberry Pi to the SPI device. MISO to allow data to go from the SPI device to the Raspberry Pi, place a 1K resistance in this line, as when the Raspberry Pi boots, this line could actually be an output. And SCKL to allow the SPI communication to be synchronized.
In rare situations an SPI device, such as the OLED 128x64 SSD1306, will require a data select line DS, in order to distinguish between commands and data. In these circumstances an additional Raspberry Pi GPIO pin can be used to connect to the DS pin of the SPI device.
Some SPI devices require a reset signal on power up to allow the device to initialize internally, such as the OLED 128x64 SSD1306 or MCP23S17 GPIO Extender. This can be achieved with a 1uF capacitor and 10K resistor. Connecting the capacitor to 0V and one side of the resistor. Then connecting the other side of the resistor to 3V3. The point between the capacitor and resistor can be used as a reset signal. On power on the capacitor will charge, during this period the reset pin will be held low, then when the capacitor has charged, the resistor will pull the reset pin high.
Install the device driver with the following commands in a command terminal. If your specific kernel version is not available, download the closest to it as it should work fine:
su - root
su - root
KERNEL_VER=`uname -r | sed "s/[+-].*$//g"`
tar -xf RPiSPiDev_23_4.4.30.tar.gz
# Add a @reboot line to the crontab of root user
DownloadV1.00 2016-11-11 - Initial version.
V1.01 2016-11-15 - Font sizes for width and height 1-8.
Additional Python example code.
Additional devices supported.
Supported devices in /proc/RPiSPi
V1.02 2016-11-22 - Fix MCP3008 support.
V1.03 2016-12-20 - Support for two decoder chips.
Select the download for the specific device it is
to run on, the Kernel build should not be important:
Raspberry Pi 2 & 3 - Kernel Build 4.4.30Raspberry Pi Original & Zero - Kernel Build 4.4.30Tested
Raspberry Pi (Original)
Raspberry Pi 2
Raspberry Pi 3
Raspberry Pi Zero
The following commands can be used in a command terminal to check how well the device driver is running:
This command lists the device drivers currently installed and running on the system. The driver should show up something like the following if it is running:
RPiSPi 91481 0
Display information about the device driver.
Display the system log entries. If the driver has issues running messages will show up in this log amongst the messages from other parts of the system. The driver also logs informational messages here.
The following message indicates that a later version of the driver should be used, the driver can be used with versions of the kernel it was not built against, but sometimes changes in the kernel can require drivers to be rebuilt against them, in order for the driver to continue working: RPiSPi: disagrees about version of symbol module_layout
Manually stop the device driver.
Manually start the device driver.
The configuration of the device driver is stored in the file: /etc/RPiSPi/RPiSPi.ini
The Raspberry Pi SPI clock speed can be set. The higher the value, the lower the SPI bus clock speed. Some devices can use higher speeds then others. If a device is having an issue, it may be worth trying a higher value for the clock speed. Remember to restart the driver if this value is changed, in order for the new value to take effect.
The following lines in the configuration file, map Raspberry Pi GPIO pins to the data select and chip select features of the device driver. Using a value of -1 signifies no GPIO pin is assigned. The chip select values have to be used in the order CS1, CS2, CS3 and CS4:
Devices are defined on lines such as the following, where the first number is the chip select assignment in binary form. The first digit of the chip select is the Raspberry Pi SPI CS0 or CS1, 0 for CS0 and 1 for CS1. The second number is the device address in binary form. And the device name is on the right of the assignment. Current supported device names are: MCP3008, MCP23S17, SSD1306 and SPI_RAW:
Running the following command in a command terminal will reconfigure the driver to the configuration contained in the file Device.cfg, while the driver is still running: cat Device.cfg > /dev/RPiSPi
Each line in the file contains three comma separated values. The first is the chip select for the device, in binary representation. The second is the address of the device on the chip select line, in binary representation, for most devices this will most likely be 000. Devices such as MCP23S17 have address lines. The last value is the device name, current supported device names are: MCP3008, MCP23S17, SSD1306 and SPI_RAW:
Running the following command in a command terminal will show the current configuration of the driver: cat /dev/RPiSPi
Running the following command in a command terminal will show the current state of the driver: cat /proc/RPiSPi
In the following examples, the examples have been written for the default example configuration of the driver. Replace the device names in the code to the equivalent names on your system before running each example. For instance the device name /dev/RPiSPi_00010_000_2_0_SSD1306_INIT would be different on your system unless your system is configured the same as the default configuration.
Download examples in a command terminal:
Example written in Python demonstrating writing graphics functions on an SSD1306 128x64 OLED display: sudo ./RPiSPi_SSD1306.py
Example written in Python demonstrating displaying the current date and time and IP address on an SSD1306 128x64 OLED display: sudo ./RPiSPi_SSD1306_DateTime.py
Example written in Python demonstrating displaying the current date and time as an analog clock on an SSD1306 128x64 OLED display: sudo ./RPiSPi_SSD1306_AnalogClock.py
Example written in Python demonstrating displaying scrolling messages on an SSD1306 128x64 OLED display: sudo ./RPiSPi_SSD1306_ScrollMessage.py
Example written in Python demonstrating displaying two image files alternating on an SSD1306 128x64 OLED display: sudo ./RPiSPi_SSD1306_Image.py
Example written in Python demonstrating reading each of the two A-D ports on a MCP3002 device: sudo ./RPiSPi_MCP3002.py
Example written in Python demonstrating reading each of the four A-D ports on a MCP3004 device: sudo ./RPiSPi_MCP3004.py
Example written in Python demonstrating reading each of the eight A-D ports on a MCP3008 device: sudo ./RPiSPi_MCP3008.py
Example written in Python demonstrating reading and writing to each of the eight bit GPIO ports on a MCP23S17 device: sudo ./RPiSPi_MCP23S17.py
Example written in Python demonstrating reading each of the eight A-D ports on a MCP3008 device, using the generic SPI interface which can be used to read and write to most SPI devices: sudo ./RPiSPi_RAW.py
An example actual application using the SPI interface to read the ports on a MCP23S17 and write to an SSD1306 128x64 OLED display. Providing a playable game using the driver: sudo ./Asteroids/AsteroidsPi.py