Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebIOPi using piFace and raspios-bullseye does not start; spi init fails #4

Open
noanight opened this issue Apr 21, 2022 · 5 comments · May be fixed by #5
Open

WebIOPi using piFace and raspios-bullseye does not start; spi init fails #4

noanight opened this issue Apr 21, 2022 · 5 comments · May be fixed by #5

Comments

@noanight
Copy link

Setup

  • PiFace
  • RPI 1 B Your Pi is a Revision 2, so your ports are: [2, 3, 27]
  • raspios bullseye
uname -a
Linux piface 5.15.32+ #1538 Thu Mar 31 19:37:58 BST 2022 armv6l GNU/Linux

WebIOPi Config

[DEVICES]
pifaceModule = PiFaceDigital

Startup log

2022-04-20 16:51:18 - WebIOPi - INFO - Starting WebIOPi/0.7.1/Python3.9
2022-04-20 16:51:18 - WebIOPi - DEBUG - Mapping GPIO.digitalCount to REST GET /GPIO/count
2022-04-20 16:51:18 - WebIOPi - DEBUG - Mapping GPIO.digitalRead to REST GET /GPIO/%(channel)d/value
2022-04-20 16:51:18 - WebIOPi - DEBUG - Mapping GPIO.digitalWrite to REST POST /GPIO/%(channel)d/value/%(value)d
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.getFunctionString to REST GET /GPIO/%(channel)d/function
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.getPulse to REST GET /GPIO/%(channel)d/pulse
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.outputSequence to REST POST /GPIO/%(channel)d/sequence/%(args)s
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.portRead to REST GET /GPIO/*/integer
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.portWrite to REST POST /GPIO/*/integer/%(value)d
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.pulse to REST POST /GPIO/%(channel)d/pulse/
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.pulseAngle to REST POST /GPIO/%(channel)d/pulseAngle/%(value)f
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.pulseRatio to REST POST /GPIO/%(channel)d/pulseRatio/%(value)f
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.setFunctionString to REST POST /GPIO/%(channel)d/function/%(value)s
2022-04-20 16:51:19 - WebIOPi - DEBUG - Mapping GPIO.wildcard to REST GET /GPIO/*
2022-04-20 16:51:19 - WebIOPi - INFO - GPIO - Native mapped to REST API /GPIO
2022-04-20 16:51:19 - WebIOPi - INFO - Loading configuration from /etc/webiopi/config
2022-04-20 16:51:19 - WebIOPi - INFO - Loading SPI modules
2022-04-20 16:51:19 - WebIOPi - DEBUG - Loading module : spi-bcm2708
modprobe: FATAL: Module spi-bcm2708 not found in directory /lib/modules/5.15.32+
2022-04-20 16:51:19 - WebIOPi - DEBUG - Loading module : spidev
2022-04-20 16:51:19 - WebIOPi - ERROR - 
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/__main__.py", line 75, in <module>
    main(sys.argv)
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/__main__.py", line 69, in main
    server = Server(port=port, configfile=configfile, scriptfile=scriptfile)
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/server/__init__.py", line 66, in __init__
    manager.addDevice(name, driver, args)
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/manager.py", line 28, in addDevice
    dev = devClass()
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/shield/piface.py", line 22, in __init__
    mcp = MCP23S17(0, 0x20+board)
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/digital/mcp23XXX.py", line 148, in __init__
    MCP23SXX.__init__(self, chip, slave, 16, "MCP23S17")
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/digital/mcp23XXX.py", line 119, in __init__
    SPI.__init__(self, toint(chip), 0, 8, 10000000)
  File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/spi.py", line 98, in __init__
    assert(self.mode == mode)
AssertionError

Errors

modprobe: FATAL: Module spi-bcm2708 not found in directory /lib/modules/5.15.32+

from https://forums.raspberrypi.com/viewtopic.php?p=675658#p675658

The January 2015 Raspbian release, with Pi 2 support, switches to a new kernel (3.18), and includes a configuration change to enable Device Tree support by default. This has caused some previously working things to mysteriously stop working, but with a few configuration changes normal service should be resumed. We'll tell you how to do that in a moment, but first here's some background information. 

Conclusion: so no module load required

Workaround

sudo nano /usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/bus.py

replace spi-bcm2708 with spi-bcm2835

BUSLIST = {
"I2C": {"enabled": False, "gpio": {0:"SDA", 1:"SCL", 2:"SDA", 3:"SCL"}, "modules": ["i2c-bcm2708", "i2c-dev"]},
"SPI": {"enabled": False, "gpio": {7:"CE1", 8:"CE0", 9:"MISO", 10:"MOSI", 11:"SCLK"}, "modules": ["spi-bcm2835", "spidev"]>
"UART": {"enabled": False, "gpio": {14:"TX", 15:"RX"}},
"ONEWIRE": {"enabled": False, "gpio": {4:"DATA"}, "modules": ["w1-gpio"], "wait": 2}
}

SPI.init(self, toint(chip), 0, 8, 10000000) File "/usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/spi.py", line 98, in init assert(self.mode == mode)

Workaround

sudo nano /usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/spi.py
class SPI(Bus):
    def __init__(self, chip=0, mode=0, bits=8, speed=0):
        Bus.__init__(self, "SPI", "/dev/spidev0.%d" % chip)
        self.chip = chip

        val8 = array.array('B', [0])
        val8[0] = mode
        '''
        if fcntl.ioctl(self.fd, SPI_IOC_WR_MODE, val8):
            raise Exception("Cannot write SPI Mode")
        if fcntl.ioctl(self.fd, SPI_IOC_RD_MODE, val8):
            raise Exception("Cannot read SPI Mode")
        self.mode = struct.unpack('B', val8)[0]
        assert(self.mode == mode)
        '''
@MichaIng
Copy link
Contributor

Confirmed: raspberrypi/linux@bdfc988
This was removed with RPi Linux 4.3 already, spi-bcm2835 is available instead.

@MichaIng
Copy link
Contributor

The same is true for I2C: While the module is still available, it is deprecated in favour of i2c-bcm2835: https://forums.raspberrypi.com/viewtopic.php?t=133024

MichaIng added a commit to MichaIng/WebIOPi that referenced this issue Apr 21, 2022
spi-bcm2708 has been removed with RPi kernel v4.3: raspberrypi/linux@bdfc988
i2c-bcm2708 has been deprecated a long time ago: https://forums.raspberrypi.com/viewtopic.php?t=133024

The respective bcm2835 modules are available and compatible with all RPi models.

Solves: Freenove#4

Signed-off-by: MichaIng <[email protected]>
@MichaIng MichaIng linked a pull request Apr 21, 2022 that will close this issue
@MichaIng
Copy link
Contributor

PR up to fix this: #5

@noanight
Copy link
Author

I think the loadModule and unloadModule Functions, calling modprobe, should be removed, because it's outdated. The Kernel uses device tree.

@noanight
Copy link
Author

noanight commented Apr 22, 2022

About the failing assert...

SPI_CS_HIGH Flag is always set when reading the SPI mode...though the assertion fails.

According to raspberrypi/linux#3745

_CS_HIGH handling has changed between 4.19 and 5.4 - the SPI framework forces CS_HIGH then leaves it up to the GPIO layer to handle the ACTIVE_LOW semantics. I don't like the change because it is (ab)using user-facing flags - CS_HIGH no longer means what you think it means. The attitude upstream (and I may be missing some nuance here) seems to be that CS_HIGH is a bus property rather than a device property - if you have to wait until an application starts to reverse the polarity of one of the CS pins then the device has possibly already been responding to and interfering with devices on other CS lines from the same
controller.

In short - dropping the device.cshigh = False line not only makes it work but is the right thing to do. Under other circumstances this kernel change might have broken other aspects of the py-spidev library, but I think the fact that it reads the initial value of the mode from spidev means that everything is fine unless you try to clear cshigh._

raspberrypi/linux#4018
https://forums.raspberrypi.com/viewtopic.php?t=304156

Tried the C Version with the same result...SPI_CS_HIGH is set.

wget https://raw.githubusercontent.com/torvalds/linux/master/tools/spi/spidev_test.c
gcc -o spidev_test spidev_test.c
./spidev_test -D /dev/spidev0.0
sudo nano /usr/local/lib/python3.9/dist-packages/WebIOPi-0.7.1-py3.9-linux-armv6l.egg/webiopi/devices/spi.py

SPI_CS_HIGH     = 0x04
# SPI_LSB_FIRST   = 0x08
# SPI_3WIRE       = 0x10
# SPI_LOOP        = 0x20
# SPI_NO_CS       = 0x40
# SPI_READY       = 0x80
...
...
..

class SPI(Bus):
    def __init__(self, chip=0, mode=0, bits=8, speed=0):
        Bus.__init__(self, "SPI", "/dev/spidev0.%d" % chip)
        self.chip = chip

        val8 = array.array('B', [0])
        val8[0] = mode
        if fcntl.ioctl(self.fd, SPI_IOC_WR_MODE, val8):
            raise Exception("Cannot write SPI Mode")
        if fcntl.ioctl(self.fd, SPI_IOC_RD_MODE, val8):
            raise Exception("Cannot read SPI Mode")
        self.mode = struct.unpack('B', val8)[0]
        self.mode &= ~SPI_CS_HIGH
        assert(self.mode  == mode)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants