0

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 &amp; 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] &lt;&lt; 8) | (spibuf[2])) &gt;&gt; 4;

printf(&quot;%d\n&quot;, adcout);

}

And finally, the device tree overlay:

/dts-v1/;
/plugin/;

/ { compatible = "brcm,bcm2835";

fragment@0 {
    target = &lt;&amp;spi0_cs_pins&gt;;
    frag0: __overlay__ {
        brcm,pins = &lt;8 7 1 5 6&gt;;
    };
};

fragment@1 {
    target = &lt;&amp;spi0&gt;;
    frag1: __overlay__ {
        #address-cells = &lt;1&gt;;
        #size-cells = &lt;0&gt;;

        cs-gpios = &lt;&amp;gpio 8 1&gt;, &lt;&amp;gpio 7 1&gt;, &lt;&amp;gpio 1 1&gt;, &lt;&amp;gpio 5 1&gt;, &lt;&amp;gpio 6 1&gt;;
        status = &quot;okay&quot;;

        spidev0_2: spidev@2 {
            compatible = &quot;spidev&quot;;
            reg = &lt;2&gt;;
            #address-cells = &lt;1&gt;;
            #size-cells = &lt;0&gt;;
            spi-max-frequency = &lt;125000000&gt;;
        };

        spidev0_3: spidev@3 {
            compatible = &quot;spidev&quot;;
            reg = &lt;3&gt;;
            #address-cells = &lt;1&gt;;
            #size-cells = &lt;0&gt;;
            spi-max-frequency = &lt;125000000&gt;;
        };

        spidev0_4: spidev@4 {
            compatible = &quot;spidev&quot;;
            reg = &lt;4&gt;;
            #address-cells = &lt;1&gt;;
            #size-cells = &lt;0&gt;;
            spi-max-frequency = &lt;125000000&gt;;
        };
    };
};

};

I'm pretty new to GPIO, SPI and WiringPi, so I am assuming I may have a fundamental disconnect in my understanding.

nullPainter
  • 115
  • 4
  • It is unclear what you are asking, BUT WiringPi is deprecated, so is a poor choice for new code (although it still works, but PI4 support is incomplete).
  • – Milliways Sep 03 '21 at 11:18
  • 1
  • The gpio tool DOES NOT report ACTUAL pin configuration, but a fixed default pin function. See https://raspberrypi.stackexchange.com/a/123749/8697 for a tool which reports actual configured function.
  • – Milliways Sep 03 '21 at 11:21
  • 1
  • AFAIK the wiringpi code uses its own direct register access to provide SPI, it does not use device tree settings. Indeed the device tree setting DOES NOT use the SOC CS code, but its own kernel driver, which is invisible to any gpio function tools.
  • – Milliways Sep 03 '21 at 11:25