Enabling and using the i2c interface, via custom device tree overlay file, to communicate with a bmp280 temperature and pressure sensor
The i2c support can be enabled and used according to two basic strategies. First, is enable of the i2c interface alone, and then use various scripting and/or programming languages to communicate with the sensors on the using the i2c bus and protocol. Second, when available, use the native operating system sensors support, i.e. a kernel level driver, to communicate with the sensors again via the via the i2c bus and protocol. Reference for the i2c protocol https://en.wikipedia.org/wiki/I²C
The types of devices which leverage the i2c interface and communication protocol include, sensors, display screens, touch panels, etc., is extensive. Specific to this example, will be establishing support for the popular bmp280 temperature and pressure combined sensor. Reference https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp280/. This example is also specific to rockchip based SBCs, and will be specific to the boot loader configuration for Arch Linux distributions, as illustrated using the BredOS and the IndieDroid Nova SBC.
There are various libraries that provide direct support for the bmp280 sensor. For example, Adafruit, provides python compatible bmp280 sensor support, refer to https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries and https://learn.adafruit.com/adafruit-bmp280-barometric-pressure-plus-temperature-sensor-breakout/circuitpython-test. For full native kernel support, the device tree method can be used to tell the kernel that there is a device and to let it take over control of it. The following example will illustrate the full native kernel driver support method for accessing the bmp280 sensor via the i2c bus and protocol.
To leverage the kernel device tree for this, typically the following steps are necessary when new functionality is established:
BredOS already has the applicable device tree file to enable the correct i2c bus, i.e. bus 8, to use the i2c GPIO pins. However, to communicate with the bmp280 sensor a device tree file specific to support the bmp280 sensor must be used.
Install i2c-tools package, The i2c-tools package provides CLI commands to list the sensors found on the i2c bus.
pacman -Sy i2c-tools
ls -l /dev/i2c*
Note that the i2c-8 bus is not present by default. Specific to the IndieDroid the i2c bus 8 (m2), which is not enabled by default, but available on GPIO board pins 3 and 5, respectively i2c SDA (i.e. data pin), and i2c SCL (i.e. clock pin).
Regardless of using full native kernel support, or only enablement of the applicable i2c bus, the use of a device tree source file to validate the i2c bus function is required. This ensures that the i2c interface on the correct bus is functional, and the sensor is found at the expected i2c address.
BMP280 VCC pin to 3.3v power pin on Nova SBC
BMP280 GND to any available ground, such as pin 9, on Nova SBC
BMP280 SDA pin to i2c SDA (data) pin 3 on Nova SBC
BMP280 SCL pin to i2c SCL (clock) pin 5 on Nova SBC
Find the device tree source file to enable i2c bus 8.. Specific to the InideDroid Nova i2c support on the GPIO header via board pins 3 and 5, i.e. i2c SDA (data pin) and i2c SCL (clock pin), and are qualified as the 'm2' variant. Thus the boot configuration must be amended to load compiled rk3588-i2c8-m2 device tree file.
Open a terminal session via Secure Shell (SSH) or within the desktop (GUI) and elevate to root level access...
su
Confirm that the GPIO i2c 8 (m2) device tree object files are present on the boot partition...
find /boot | grep i2c8
Output will look something like this
/boot/dtbs/rockchip/overlay/rk3588-i2c8-m2.dtbo
/boot/dtbs/rockchip/overlay/rk3588-i2c8-m4.dtbo
Edit the extlinux.conf
file to load the device tree object file, ensure the 'fdtoverlays' configuration setting is set to /dtbs/rockchip/overlay/rk3588-i2c8-m2.dtbo
...
cat /boot/extlinux/extlinux.conf
label BredOS ARM
kernel /vmlinuz-linux-rockchip-rkr3
initrd /initramfs-linux-rockchip-rkr3.img
fdt /dtbs/rockchip/rk3588s-9tripod-linux.dtb
fdtoverlays /dtbs/rockchip/overlay/rk3588-i2c8-m2.dtbo
append root=UUID=4475cf68-ec3f-4665-be9c-a761f4dba528 console=ttyFIQ0,1500000n8 console=tty1 console=both loglevel=3 rw panic=10 rootwait rw init=/sbin/init rootflags=subvol=@ rootfstype=btrfs
Reboot the IndieDroid Nova...
reboot
ls -l /dev/i2c* | grep i2c-8
crw-rw---- 1 root i2c 89, 8 Sep 22 09:44 /dev/i2c-8
Should the above device directory not exist, then the compiled device tree file did not load as expected. Validate that the extlinux.conf
file was changed as required to enable the i2c 8 bus, using the m2
variant of the file. For example...
fdtoverlays /dtbs/rockchip/overlay/rk3588-i2c8-m2.dtbo
i2cdetect -y 8
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
The bmp280 sensor should appear on the i2c bus 8 at address 0x76, as noted by the '76' reference above in the 70 row and 6 column. Should this not be the case, then the device tree file loaded as expected, thus the sensor is not visible on i2c bus 8. If planning to only enable the applicable i2c bus, i.e. 8, no more additional steps are required, other than installing the application level libraries and development of sensor query applicable code. If use of full native kernel support for the sensor is desired, complete the following steps below.
Create a device tree file, which enables the i2c bus 8, and the native kernel bmp280 support...
cd /root
nano rk3588-bmp280.dts
/dts-v1/;
/plugin/;
/ {
metadata {
title = "Enable BMP280 on I2C8-M2";
compatible = "rockchip,rk3588";
category = "misc";
exclusive = "GPIO1_D6", "GPIO1_D7";
description = "Enable BMP280 on I2C8-M2. Pin 3 and 5";
};
};
&i2c8 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c8m2_xfer>;
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
bmp280: bmp280@76 {
compatible = "bosch,bmp280";
reg = <0x76>;
status = "okay";
};
};
Compile device tree file...
dtc -I dts -O dtb rk3588-bmp280.dts -o rk3588-bmp280.dtbo
Move device tree compiled file to the device tree overlay directory...
mv rk3588-bmp280.dtbo /boot/dtbs/rockchip/overlay/
Add the following line to the /boot/extlinux/extlinux.conf configuration file...
cp /boot/extlinux/extlinux.conf /boot/extlinux/extlinux.conf.original
nano /boot/extlinux/extlinux.conf
fdtoverlays /dtbs/rockchip/overlay/rk3588-bmp280.dtbo
For example...
cat /boot/extlinux/extlinux.conf
label BredOS ARM
kernel /vmlinuz-linux-rockchip-rkr3
initrd /initramfs-linux-rockchip-rkr3.img
fdt /dtbs/rockchip/rk3588s-9tripod-linux.dtb
fdtoverlays /dtbs/rockchip/overlay/rk3588-bmp280.dtbo
append root=UUID=4475cf68-ec3f-4665-be9c-a761f4dba528 console=ttyFIQ0,1500000n8 console=tty1 console=both loglevel=3 rw panic=10 rootwait rw init=/sbin/init rootflags=subvol=@ rootfstype=btrfs
/dtbs/rockchip/overlay/
is a relative path, where the full path of the device tree compiled file is/boot/dtbs/rockchip/overlay/
reboot
lsmod | grep bmp280
bmp280_spi 16384 0
bmp280_i2c 16384 0
bmp280 28672 2 bmp280_i2c,bmp280_spi
Note the that both the i2c and spi support shows available, this is because the bmp280 sensor supports both SPI and i2c interfaces. However, for this example, only the i2c support is applicable.
i2cdetect -y 8
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- UU --
Note that the value at address 0x76 on the i2c 8 bus, has changed from '76' to 'UU', this is expected and desired, in that it shows that the native kernel bmp280 support has taken ownership of the sensor.
dmesg | grep bmp280
[ 11.513718] bmp280 8-0076: Looking up vddd-supply from device tree
[ 11.513728] bmp280 8-0076: Looking up vddd-supply property in node /i2c@feca0000/bmp280@76 failed
[ 11.513757] bmp280 8-0076: supply vddd not found, using dummy regulator
[ 11.513830] bmp280 8-0076: Looking up vdda-supply from device tree
[ 11.513836] bmp280 8-0076: Looking up vdda-supply property in node /i2c@feca0000/bmp280@76 failed
[ 11.513847] bmp280 8-0076: supply vdda not found, using dummy regulator
[ 11.694189] SPI driver bmp280 has no spi_device_id for bosch,bmp085
Query Temperature And Pressure Values From The bmp280 Sensor...
cat /sys/devices/platform/feca0000.i2c/i2c-8/8-0076/iio:device1/in_temp_input
Output: 30630
Temperature 30.630 Celsius
cat /sys/devices/platform/feca0000.i2c/i2c-8/8-0076/iio:device1/in_pressure_input
Output: 100.292183593
Pressure returned is in kPa units.
For other operating systems, the location of the device tree compiled file will vary, the method to load the compiled file will vary. But the over all process is similar, in that a device tree file will have to be compiled and put in the appropriate boot visible directory.