As of the recently Kernel 5.4.51 it's no longer possible to add_event_detect
on an SPI Chip-Select pin while the SPI interface is enabled.
Yes in retrospect using a channel "reserved" by the SPI device in this way was probably never a wise thing to do. But what's done is done.
To replicate use the following code snippet on a 5.4.51 Pi vs the previous kernel:
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(8, GPIO.IN) def test(pin): pass GPIO.add_event_detect(8, edge=GPIO.RISING, callback=test)
It attempts to set up edge detection on SPI's default CE0 pin.
Run this without SPI enabled and it will work fine.
Run it with SPI enabled, and it will fail with "RuntimeError: Failed to add edge detection".
This has changed from previous behaviour and is no doubt the fault of changes as of the 5.x Linux kernel (the new mutually exclusive gpiochip instead of sysfs) and is, furthermore, no doubt fully intended behaviour depite the fact it breaks some potential back-compatibility cases (I've encountered this on a new ready to ship product and am dispairing with the world right now).
I am raising it here in case there is some workaround that can be added to RPi.GPIO itself (I fear not) and to make this issue (and the below solution) known to other users who might have also been drawn into the trap of thinking they could own the SPI chip-select pins.
The fix is simple, though a minor hassle for end-users. You must re-allocate the offending chip select channel to a different pin. There's a dtoverlay for this:
dtoverlay=spi0-cs,cs0_pin=14
This example (add it to /boot/config.txt
) allocates CS0 to BCM14 (UART transmit) so that the above code will work in both cases.
This dtoverlay also supports- you guessed it- an cs1_pin
argument that can be used to re-allocate the other channel.
Hi Phil,
I'd just like to say a massive thank you for your detailed explanation, and solution!
I've just come across this myself (CE1, 7 for me) and had a look here to see if anyone else had come across it.
Hardware is made so it's not easy to change.
Added the overlay (for CE1) and all is well again (for my application - not the world..)