Difference between revisions of "Quartz64 Model A using a PCF8574"

From PINE64
Jump to navigation Jump to search
m (→‎Device Tree Changes: Use tabs in device tree code)
m (Replace an awkward "off of" with an "off")
Line 29: Line 29:
   
   


This lets the kernel know that there's a PCF8574 hanging off of the third I<sup>2</sup>C controller, and is listening on slave address <code>0x20</code> (decimal: 32). Be sure to use tabs of size 8 for the indentation, this is the style the kernel uses.
This lets the kernel know that there's a PCF8574 hanging off the third I<sup>2</sup>C controller, and is listening on slave address <code>0x20</code> (decimal: 32). Be sure to use tabs of size 8 for the indentation, this is the style the kernel uses.


Now run <code>make dtbs</code> to compile the device tree. This should give you a <tt>arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dt'''b'''</tt>, which you can then copy into your <tt>/boot/dtbs/</tt> as for example <tt>quartz-with-pcf8574.dtb</tt> or something like that. Then, in your <tt>extlinux.conf</tt>, either add a new boot label or modify your existing boot labels <code>FDT</code> line to point towards this dtb file, with the path being relative to <tt>/boot</tt> and not to <tt>/</tt>.
Now run <code>make dtbs</code> to compile the device tree. This should give you a <tt>arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dt'''b'''</tt>, which you can then copy into your <tt>/boot/dtbs/</tt> as for example <tt>quartz-with-pcf8574.dtb</tt> or something like that. Then, in your <tt>extlinux.conf</tt>, either add a new boot label or modify your existing boot labels <code>FDT</code> line to point towards this dtb file, with the path being relative to <tt>/boot</tt> and not to <tt>/</tt>.

Revision as of 15:56, 30 November 2021

In this article, we'll go over how to hook up a PCF8574 I2C I/O extender to a Quartz64 Model A single-board computer, including what device tree changes to make and how to control it.

Introduction To The PCF8574

The PCF8574 is a fairly ubiquitous GPIO extender that communicates through the I2C bus. You can find modules featuring it from many vendors on the usual marketplaces for cheap. It exposes 8 additional GPIO lines, and can be daisy chained to up to 4 devices, giving you an additional 64 GPIO outputs. Combining it with 4 PCF8574A modules will actually push this to a total of 128 GPIO outputs added to your board!

The PCF8574 has a mainline Linux driver, meaning that you do not need to use I2C directly to control it; it will just appear as another /dev/gpiochip<n> device. A lot of Raspberry Pi focused guides for this chip get this precise thing wrong actually, and have the user manually fiddle with the bus.

Device Tree Changes

To control the chip, you'll need to modify your board's device tree—a description of its hardware for devices that don't automatically enumerate—so that the kernel knows how to load the driver.

The easiest way to go about this is to get a copy of the Linux kernel source code from https://kernel.org that matches your kernel version (uname -a), as the device tree definitions live in the Linux kernel repository. Technically, device trees should be compatible across kernel versions, but I wouldn't gamble on it.

Once you have the kernel source, you can use your local configuration: run zcat /proc/config.gz > .config inside the top-level directory of the Linux kernel source tree to use your running kernel's configuration. Then run make xconfig (or one of the other non-graphical alternatives, like nconfig or menuconfig), save the configuration to set any new options to their default values, and then also ensure that CONFIG_GPIO_PCF857X (a.k.a. "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders") is either set to "M" or "Y".

In arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts, add the following section:

&i2c3 {
	status = "okay";
 
	pcf8574: pcf8574@20 {
		compatible = "nxp,pcf8574";
		gpio-controller;
		#gpio-cells = <2>;
		reg = <0x20>;
	};
};

This lets the kernel know that there's a PCF8574 hanging off the third I2C controller, and is listening on slave address 0x20 (decimal: 32). Be sure to use tabs of size 8 for the indentation, this is the style the kernel uses.

Now run make dtbs to compile the device tree. This should give you a arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dtb, which you can then copy into your /boot/dtbs/ as for example quartz-with-pcf8574.dtb or something like that. Then, in your extlinux.conf, either add a new boot label or modify your existing boot labels FDT line to point towards this dtb file, with the path being relative to /boot and not to /.

TODO: Expand this section with how to describe daisy chained modules in the device tree.

Hooking Up The Module

Hook up SDA to pin number 3 of your board, and SCL to pin number 5. Connect GND to ground, e.g. pin number 9, and VCC to 3.3V, for example pin number 1. If your module has an interrupt pin, you can leave it unconnected for now; producing interrupts when pin states change is an advanced topic we will expand on later.

TODO: Put photo of hooked up module here.

Using The GPIOs

Upon booting your board with your modified device tree blob, you should have an additional /dev/gpiochip<n> device, most likely /dev/gpiochip5. You can verify this by running libgpiod's gpioinfo utility, which should now show you an additional GPIO chip with only 8 lines.

To test whether this is working, you can connect an LED between a pin (in this example, 4) of your PCF8574, and ground. Then (assuming your chip number is 5) you can use sudo gpioset -B pull-down 5 4=0 to turn off the pin and set its bias mode to be pulled down, and use sudo gpioset 5 4=1 to turn it on and sudo gpioset 5 4=0 to turn it off. Connecting an LED with no resistor in-line should be fine because the pins deliver like 100mA current at most.

TODO: Expand this section with how to control the pins programmatically using libgpiod or whatever.