- Configuring LinuxCNC
- HAL
- Patching the MCP23017 kernel driver device tree to work with hal_gpio (RPi)
Patching the MCP23017 kernel driver device tree to work with hal_gpio (RPi)
28 Dec 2023 13:33 - 28 Dec 2023 21:18 #289244
by jst
tldr: The following procedure should work for any SPI/I2C/... GPIO Expander with an existend linux kernel/gpiod driver that uses a Device Tree configuration.
I'm currently retrofitting a small CNC mill with LinuxCNC on the Raspberry Pi 4.
To get more GPIOs I wanted to use the MCP23017 I2C Port Expander (www.microchip.com/en-us/product/mcp23017).
For testing I use this board: www.adafruit.com/product/4132
I don't expect the GPIOs to be realtime, but I want to use them in a HAL file.
While resaerching I found this thread (but there is no real solution, only some hints): forum.linuxcnc.org/24-hal-components/464...dapt-the-extended-io
I also took a closer look at the hal_gpio driver.
As documented the hal_gpio driver relies on the gpiod package and the names given by gpioinfo. I was lucky because there is a linux kernel driver for the MCP23017:
github.com/torvalds/linux/blob/master/Do...pinctrl-mcp23s08.txt
github.com/torvalds/linux/blob/master/dr...nctrl-mcp23s08_i2c.c
So I added the Device Tree (/boot/broadcom/overlays/mcp23017.dtbo) that was already provided in the firmware folder on the RPi to the config.txt as an overlay and did a reboot.
- add follwing at the end of the file: - also enable I2C if not alredy enabled:
After running gpioinfo the GPIO extender with the pins was shown, but they didn't have a name ('unnamed').
After some resaech and comparison to the Raspberry Pi GPIO device tree I figured out how to set the GPIO names in the device tree:
- Decompile the .dtbo in the .dts format with dtc: - Edit the .dts file: - change the I2C address if necessary (the adafruit board has the address 0x20): - add the GPIO names in the mcp@20 section (ypu can choose your own names): - Compile the file back and save it to the firmware folder (keep a backup of the original .dtbo file) - reboot
After applying the patched Device Tree I got names in the gpioionfo output:
Then it is possible to use the GPIOs with the hal_gpio driver:
I'm currently retrofitting a small CNC mill with LinuxCNC on the Raspberry Pi 4.
To get more GPIOs I wanted to use the MCP23017 I2C Port Expander (www.microchip.com/en-us/product/mcp23017).
For testing I use this board: www.adafruit.com/product/4132
I don't expect the GPIOs to be realtime, but I want to use them in a HAL file.
While resaerching I found this thread (but there is no real solution, only some hints): forum.linuxcnc.org/24-hal-components/464...dapt-the-extended-io
I also took a closer look at the hal_gpio driver.
As documented the hal_gpio driver relies on the gpiod package and the names given by gpioinfo. I was lucky because there is a linux kernel driver for the MCP23017:
github.com/torvalds/linux/blob/master/Do...pinctrl-mcp23s08.txt
github.com/torvalds/linux/blob/master/dr...nctrl-mcp23s08_i2c.c
So I added the Device Tree (/boot/broadcom/overlays/mcp23017.dtbo) that was already provided in the firmware folder on the RPi to the config.txt as an overlay and did a reboot.
cnc@raspberrypi:~$ sudo nano /boot/broadcom/config.txt
dtoverlay=mcp23017
dtparam=i2c_arm=on
After running gpioinfo the GPIO extender with the pins was shown, but they didn't have a name ('unnamed').
cnc@raspberrypi:~$ gpioinfo
gpiochip0 - 58 lines:
line 0: "ID_SDA" unused input active-high
...
line 57: "RGMII_TXD3" unused input active-high
gpiochip1 - 8 lines:
line 0: "BT_ON" unused output active-high
...
line 7: "SD_OC_N" unused input active-high
gpiochip2 - 16 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused input active-high
line 6: unnamed unused input active-high
line 7: unnamed unused input active-high
line 8: unnamed unused input active-high
line 9: unnamed unused input active-high
line 10: unnamed unused input active-high
line 11: unnamed unused input active-high
line 12: unnamed unused input active-high
line 13: unnamed unused input active-high
line 14: unnamed unused input active-high
line 15: unnamed unused input active-high
After some resaech and comparison to the Raspberry Pi GPIO device tree I figured out how to set the GPIO names in the device tree:
- Decompile the .dtbo in the .dts format with dtc:
cnc@raspberrypi:~$ dtc /boot/broadcom/overlays/mcp23017.dtbo -o mcp23017.dts
cnc@raspberrypi:~$ nano mcp23017.dts
mcp23017_pins@20
mcp@20
reg = <0x20>;
gpio-line-names = "MCP20_A0","MCP20_A1","MCP20_A2","MCP20_A3","MCP20_A4","MCP20_A5","MCP20_A6","MCP20_A7","MCP20_B0","MCP20_B1","MCP20_B2","MCP20_B3","MCP20_B4","MCP20_B5","MCP20_B6","MCP20_B7";
cnc@raspberrypi:~$ dtc mcp23017.dts -o mcp23017.dtbo -O dtb
cnc@raspberrypi:~$ sudo mv /boot/broadcom/overlays/mcp23017.dtbo /boot/broadcom/overlays/mcp23017.dtbo.old
cnc@raspberrypi:~$ sudo mv mcp23017.dtbo /boot/broadcom/overlays/mcp23017.dtbo
After applying the patched Device Tree I got names in the gpioionfo output:
cnc@raspberrypi:~$ gpioinfo
gpiochip0 - 58 lines:
line 0: "ID_SDA" unused input active-high
...
line 57: "RGMII_TXD3" unused input active-high
gpiochip1 - 8 lines:
line 0: "BT_ON" unused output active-high
...
line 7: "SD_OC_N" unused input active-high
gpiochip2 - 16 lines:
line 0: "MCP20_A0" unused input active-high
line 1: "MCP20_A1" unused input active-high
line 2: "MCP20_A2" unused input active-high
line 3: "MCP20_A3" unused input active-high
line 4: "MCP20_A4" unused input active-high
line 5: "MCP20_A5" unused input active-high
line 6: "MCP20_A6" unused input active-high
line 7: "MCP20_A7" unused input active-high
line 8: "MCP20_B0" unused input active-high
line 9: "MCP20_B1" unused input active-high
line 10: "MCP20_B2" unused input active-high
line 11: "MCP20_B3" unused input active-high
line 12: "MCP20_B4" unused input active-high
line 13: "MCP20_B5" unused input active-high
line 14: "MCP20_B6" unused input active-high
line 15: "MCP20_B7" unused input active-high
Then it is possible to use the GPIOs with the hal_gpio driver:
cnc@raspberrypi:~$ halrun
halcmd: loadrt hal_gpio inputs=MCP20_A0,MCP20_A1 outputs=MCP20_B0,MCP20_B1
halcmd: show pin
Component Pins:
Owner Type Dir Value Name
4 bit OUT FALSE hal_gpio.MCP20_A0-in
4 bit OUT FALSE hal_gpio.MCP20_A0-in-not
4 bit OUT FALSE hal_gpio.MCP20_A1-in
4 bit OUT FALSE hal_gpio.MCP20_A1-in-not
4 bit IN FALSE hal_gpio.MCP20_B0-out
4 bit IN FALSE hal_gpio.MCP20_B1-out
4 s32 OUT 0 hal_gpio.read.time
4 s32 OUT 0 hal_gpio.write.time
Last edit: 28 Dec 2023 21:18 by jst. Reason: Fixed the code tags again
The following user(s) said Thank You: cornholio
Please Log in or Create an account to join the conversation.
28 Dec 2023 19:54 #289278
by cornholio
Replied by cornholio on topic Patching the MCP23017 kernel driver device tree to work with hal_gpio (RPi)
Great work
Please Log in or Create an account to join the conversation.
- Configuring LinuxCNC
- HAL
- Patching the MCP23017 kernel driver device tree to work with hal_gpio (RPi)
Time to create page: 0.099 seconds