You are in luck. The current RPi SPI driver, spi-bcm2835, support GPIO chip-selects. This means that any free GPIO line can be used as another chip select. In fact, as a result of some driver performance optimisations causing the hardware ("native") chip-selects to glitch, the driver will automatically convert native CS's to GPIO CS's.
The use of GPIO CS's (apart from the automatic native->GPIO coercion performed by the spi-bcm2835 driver) is controlled by the cs-gpio Device Tree property; the basic concepts and Device-tree usage are described
here. The GPIO syntax is very briefly touched on
here, but what you need to know is that after the reference to the GPIO controller ("&gpio") comes the pin number followed by a boolean indicating if the sense of the GPIO is normal (0) or inverted (1), e.g. "<&gpio 27 1>".
To request two extra CS-GPIOs, you would add this property to the node with the "spi0" label:
Code: Select all
cs-gpios = <0>, <0>, <&gpio 20 1>, <&gpio 21 1>;
The first two <0>s request that native CS's 0 and 1 are used (even though the driver will convert them to GPIO CS's), and that GPIO's 20 and 21 are used as active-low chip selects 2 and 3.
It is probably also wise (perhaps even necessary) to reserve the extra GPIO pins to ensure that no other drivers can claim them, and to mark them as outputs. You can do this by adding this to the node labelled "gpio":
Code: Select all
spi0_cs_pins: spio_cs_pins {
brcm,pins = <20 21>;
brcm,function = <1>; /* out */
};
and changing the spi0 node to say:
Code: Select all
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
You can do all of this with a Device Tree overlay that looks like this:
Code: Select all
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
[email protected] {
target = <&spi0>;
frag0: __overlay__ {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
status = "okay";
cs-gpios = <0>, <0>, <&gpio 20 1>, <&gpio 21 1>;
[email protected]{
compatible = "spidev";
reg = <2>; /* CE2 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <500000>;
};
[email protected]{
compatible = "spidev";
reg = <3>; /* CE3 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <500000>;
};
};
};
[email protected] {
target = <&gpio>;
__overlay__ {
spi0_cs_pins: spi0_cs_pins {
brcm,pins = <20 21>;
brcm,function = <1>; /* out */
};
};
};
__overrides__ {
cs2_pin = <&frag0>,"cs-gpios:12", <&spi0_cs_pins>,"brcm,pins:0";
cs3_pin = <&frag0>,"cs-gpios:24", <&spi0_cs_pins>,"brcm,pins:4";
};
};
The "__overrides__" block defines two Device Tree parameters, allowing you to change the pins that are used. Save the above as spi-gpio-cs-overlay.dts, and compile it into an overlay using:
Code: Select all
sudo apt-get install device-tree-compiler
# dtc [email protected] -I dts -O dtb -o spi-gpio-cs-overlay.dtb spi-gpio-cs-overlay.dts # Old version for 4.1 and earlier
# sudo cp spi-gpio-cs-overlay.dtb /boot/overlays
dtc [email protected] -I dts -O dtb -o spi-gpio-cs.dtbo spi-gpio-cs-overlay.dts # New version for 4.4 and later
sudo cp spi-gpio-cs.dtbo /boot/overlays
then use it by adding this to your config.txt:
Code: Select all
dtoverlay=spi-gpio-cs,cs2_pin=5,cs3_pin=6
An explanation of Device Tree and how to use it on Raspberry Pi's is
here.