Interfaces

After playing around with the image a little, it was time to connect the maaxboard to the outside world. The first things I wanted to try was to use the i2c interface, since that was my preferred bus to hook up my sensors. I2C is a bus which allows multiple devices to share the same bus, each with its own address. Looking around the hardware I found that its 4 i2c buses were spread out:

  • Bus 1 is on the camera connector
  • Bus 2 is on the GPIO pin header: SDA is pin 3, SCL is pin 5
  • Bus 3 is also on the GPIO header: SDA is pin 27, SCL is pin 28
  • Bus 4 is on the MIPI (screen) connector

These buses are visible to the system:

$ ls -lia /dev/i2c-*

3192 crw-rw---- 1 root i2c 89, 0 feb  7 16:50 /dev/i2c-0

2566 crw-rw---- 1 root i2c 89, 1 feb  7 16:50 /dev/i2c-1

2567 crw-rw---- 1 root i2c 89, 2 feb  7 16:50 /dev/i2c-2

2568 crw-rw---- 1 root i2c 89, 3 feb  7 16:50 /dev/i2c-3

So I hooked up a small breadboard with 2 i2c devices I had lying around:

  • MCP23017 port expander
  • BMP280 pressure and temperature sensor

ma

I use the 3.3V and GND connections from the GPIO header:

  • GPIO pin 1 (3.3V) to the positive bus on the breadboard
  • GPIO pin 6 (GND) to the negative bus on the breadboard
  • GPIO pin 3 (SDA from i2c-1 bus)
  • GPIO pin 5 (SCL from i2c-1 bus)

I used this tutorial to test the MCP23017: https://www.raspberrypi-spy.co.uk/2013/07/how-to-use-a-mcp23017-i2c-port-expander-with-the-raspberry-pi-part-1/

After connecting everything, the devices showed up on the i2c bus:

pi@maaxboard:~$ sudo i2cdetect -y 1

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00:          -- -- -- -- -- -- -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

70: -- -- -- -- -- -- 76 --

Address 20 (HEX) was the MCP23017, address 76 (HEX) was the BMP280.

By using the 'i2cset' command, I was able to trigger the connected leds to on and off (this is taken from the tutorial mentioned above):

To do a quick test we can use the command line to enable the LED on GPA0 :

First we configure Port A pins GPA0-6 as outputs and GPA7 as an input. (10000000 in binary and 0x80 in hex) :

sudo i2cset -y 1 0x20 0x00 0x80 

Then we set GPA0 to logic high which will enable the LED :

sudo i2cset -y 1 0x20 0x14 0x01 

To turn off the LED we use :

sudo i2cset -y 1 0x20 0x14 0x00

So the GPIO expander worked, how about the sensor? I found a small python script to read out the sensor:

# python test_bmp.py

Temperature in Celsius : 21.94 C

Temperature in Fahrenheit : 71.49 F

Pressure : 1017.50 hPa

So the sensor also worked.

I wanted more, for I knew there were kernel modules for the various sensors, so I would be able to read them continuously without using a python script. I had some experience in compiling linux kernel modules, but I was used to the basic way of building them: https://www.kernel.org/doc/Documentation/kbuild/modules.txt  which used the kernel source tree to build a module:

To build against the running kernel use:

 

$ make -C /lib/modules/`uname -r`/build M=$PWD

This gave an error, because, as I found out, the running kernel was 4.14.78, and the '/lib/modules' directory looked like this:

 

# ls -lia /lib/modules/4.14.78/

totaal 368

  853 drwxrwxr-x 3 user user  4096 apr 16 12:41 .

  852 drwxrwxr-x 5 user user  4096 apr 14 21:07 ..

  855 lrwxrwxrwx 1 user user    26 jan 14 03:48 build -> /home/embest/compile/linux

  867 drwxrwxr-x 9 user user  4096 jan 14 03:48 kernel

30600 -rw-r--r-- 1 root root 64579 apr 16 12:41 modules.alias

12216 -rw-r--r-- 1 root root 69092 apr 16 12:41 modules.alias.bin

  857 -rw-rw-r-- 1 user user 31857 jan 14 03:48 modules.builtin

30602 -rw-r--r-- 1 root root 34659 apr 16 12:41 modules.builtin.bin

30599 -rw-r--r-- 1 root root 22440 apr 16 12:41 modules.dep

12215 -rw-r--r-- 1 root root 36296 apr 16 12:41 modules.dep.bin

30603 -rw-r--r-- 1 root root    98 apr 16 12:41 modules.devname

  856 -rw-rw-r-- 1 user user 12832 jan 14 03:48 modules.order

30601 -rw-r--r-- 1 root root    85 apr 16 12:41 modules.softdep

12217 -rw-r--r-- 1 root root 30424 apr 16 12:41 modules.symbols

  862 -rw-r--r-- 1 root root 37398 apr 16 12:41 modules.symbols.bin

  854 lrwxrwxrwx 1 user user    26 jan 14 03:48 source -> /home/embest/compile/linux

The build directory was linked to a nonexistent home directory, probably used in building this image. I tried several things, like downloading a new kernel source, but I got stuck. After a long night of fruitless tries, I woke up the next morning retracing my steps, and found this entry on the element 14 blog: https://www.element14.com/community/message/287797/l/re-maaxboard-debian-image-tips-add-ins-and-fixes#287797, which pointed to a download of the kernel sources for this debian build. I followed the steps, and with the addition of a few extra commands:

# make modules

# make modules_prepare

I was able to compile the kernel modules for the bmp280 and bmp280-i2c drivers.

After loading them into the kernel with the command:

# modprobe bmp280-i2c

The driver was loaded:

# lsmod

Module                  Size  Used by

bmp280_i2c             16384  0

bmp280                 20480  1 bmp280_i2c

brcmfmac              249856  0

brcmutil               16384  1 brcmfmac

crc32_ce               16384  0

crct10dif_ce           16384  0

imx_sdma               36864  0

ip_tables              24576  0

x_tables               40960  1 ip_tables

(note that the bmp280 is also loaded, as required by the bmp280-i2c driver).

Now if we look at the contents of the i2c bus:

# ls -lia /sys/bus/i2c/devices/i2c-1/

totaal 0

7717 drwxr-xr-x 5 root root    0 apr 17 00:04 .

3142 drwxr-xr-x 4 root root    0 apr 17 00:04 ..

21038 drwxr-xr-x 4 root root    0 apr 17 00:04 1-0076

7722 --w------- 1 root root 4096 apr 17 00:04 delete_device

7732 lrwxrwxrwx 1 root root    0 apr 17 00:04 device -> ../../30a30000.i2c

17191 drwxr-xr-x 3 root root    0 apr 17 00:04 i2c-dev

7720 -r--r--r-- 1 root root 4096 apr 17 00:04 name

7721 --w------- 1 root root 4096 apr 16 23:47 new_device

7719 lrwxrwxrwx 1 root root    0 apr 17 00:04 of_node -> ../../../../firmware/devicetree/base/i2c@30a30000

7725 drwxr-xr-x 2 root root    0 apr 17 00:04 power

7724 lrwxrwxrwx 1 root root    0 apr 17 00:04 subsystem -> ../../../../bus/i2c

7718 -rw-r--r-- 1 root root 4096 apr 17 00:04 uevent

We can add the bmp280 device on the address we found on the i2cdetect scan (76):

# echo "bmp280 0x76" > /sys/bus/i2c/devices/i2c-1/new_device

And then we have a new device for the BMP280 sensor (it is loaded as iio/pressure):

# ls -lia /sys/bus/iio/devices/iio\:device0/

totaal 0

21054 drwxr-xr-x 3 root root    0 apr 17 00:08 .

21038 drwxr-xr-x 4 root root    0 apr 17 00:04 ..

21071 -r--r--r-- 1 root root 4096 apr 17 00:08 dev

21061 -rw-r--r-- 1 root root 4096 apr 16 23:47 in_pressure_input

21060 -rw-r--r-- 1 root root 4096 apr 17 00:08 in_pressure_oversampling_ratio

21057 -r--r--r-- 1 root root 4096 apr 17 00:08 in_pressure_oversampling_ratio_available

21059 -rw-r--r-- 1 root root 4096 apr 16 23:47 in_temp_input

21058 -rw-r--r-- 1 root root 4096 apr 17 00:08 in_temp_oversampling_ratio

21056 -r--r--r-- 1 root root 4096 apr 17 00:08 in_temp_oversampling_ratio_available

21062 -r--r--r-- 1 root root 4096 apr 17 00:08 name

21065 drwxr-xr-x 2 root root    0 apr 17 00:08 power

21064 lrwxrwxrwx 1 root root    0 apr 17 00:08 subsystem -> ../../../../../../bus/iio

21055 -rw-r--r-- 1 root root 4096 apr 16 23:47 uevent

And then we can read out the pressure and the temperature by just reading out the 'files':

# cat /sys/bus/iio/devices/iio\:device0/name

bmp280

# cat /sys/bus/iio/devices/iio\:device0/in_pressure_input

101.761613281

# cat /sys/bus/iio/devices/iio\:device0/in_temp_input

21950

Conclusion

With some struggles, I was able to get the i2c bus working. I have the luxury of 2 buses on the GPIO pins, so this gives ample opprtunity to interface with lots of devices, like PWM boards, sensors, GPIO expanders, etc. So far, the maaxboard has exceeded my expectations on this. My only problem so far is the simple fact that the debian image for the maaxboard is not quite ready for general use, it is still a work in progress.