I am trying to get more than two chip selects available on the Pi. I have the devices present, but am struggling to read a MCP3008 when the CS is plugged into the additional GPIO pins. My end goal is to connect two MCP3008 and two MCP23S17 port expanders.
I have used the device tree overlay from here, copied below, to create an additional three chip select pins. This overlay results in chip select pins on GPIO 8, 7, 1, 5, and 6.
In /dev
, I now have the following, as expected:
/dev/spidev0.0
/dev/spidev0.1
/dev/spidev0.2
/dev/spidev0.3
/dev/spidev0.4
Using the following sample code, very lightly modified from here - just to add the channel as a const and pass it into both wiringPiSPISetup()
and wiringPiSPIDataRW()
- I can read from standard GPIO 8 and 7, but not the other three. For those, I am just getting 0
returned from my MCP3008 input.
I have tried writing a 0
to physical pin 28, which I understand to be GPIO 1, but still no joy.
For reference, here's the result of gpio readall
:
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | OUT | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | OUT | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | OUT | 1 | 7 || 8 | 1 | IN | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | IN | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | OUT | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | OUT | 0 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | OUT | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | IN | 0 | 35 || 36 | 0 | IN | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | IN | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | IN | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
and the c I'm using to test:
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
void mcp3008_read(uint8_t);
// channels 0 and 1 work, 2 - 4 don't
const int channel = 0;
int main(void)
{
wiringPiSetupGpio();
wiringPiSPISetup(channel, 410001000);
delay(50);
for (;;){
mcp3008_read(0);
delay(50);
}
return 0;
}
// read a channel
void mcp3008_read(uint8_t adcnum)
{
unsigned int commandout = 0;
unsigned int adcout = 0;
commandout = adcnum & 0x3; // only 0-7
commandout |= 0x18; // start bit + single-ended bit
uint8_t spibuf[3];
spibuf[0] = commandout;
spibuf[1] = 0;
spibuf[2] = 0;
wiringPiSPIDataRW(channel, spibuf, 3);
adcout = ((spibuf[1] << 8) | (spibuf[2])) >> 4;
printf("%d\n", adcout);
}
And finally, the device tree overlay:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0_cs_pins>;
frag0: __overlay__ {
brcm,pins = <8 7 1 5 6>;
};
};
fragment@1 {
target = <&spi0>;
frag1: __overlay__ {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 1>, <&gpio 7 1>, <&gpio 1 1>, <&gpio 5 1>, <&gpio 6 1>;
status = "okay";
spidev0_2: spidev@2 {
compatible = "spidev";
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
spidev0_3: spidev@3 {
compatible = "spidev";
reg = <3>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
spidev0_4: spidev@4 {
compatible = "spidev";
reg = <4>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <125000000>;
};
};
};
};
I'm pretty new to GPIO, SPI and WiringPi, so I am assuming I may have a fundamental disconnect in my understanding.