IKS01A2 MEMS expansion board

Revision as of 07:14, 15 May 2019 by Registered User (→‎Accelerometer)

Template:ArticleMainWriter Template:ReviewersList


1. Article purpose[edit source]

The purpose of this article is to explain how to integrate the IKS01A expansion board with STM32MP157C-DK2. IKS01A expansion is a motion MEMS and environmental sensor expansion board.
This article will explain step by step how to support IKS01A expansion board on Linux part of software and describe how to use several motion MEMS like HTS221 and LSM6DX.

2. Pre-requisite[edit source]

2.1. Hardware[edit source]

  • STM32MP157C-DK2
STM32MP157C-DK2 recto

For more information about hardware and how to start it: link

  • IKS01A2 expansion board
IKS01A2
IKS01A2

2.2. Software[edit source]

For the software, please follow all step described on [start for STM32MP157C-DK2]

3. Software customization for supporting IKS01A expansion board[edit source]

For using IKS01A expansion board you need to configure the kernel with some device tree add-ons and kernel configuration.

3.1. Kernel configuration[edit source]

By default the motions MEMS driver present on IKS01A expansion board are supported: hts221, pressure(lp22hb) and lsm6dsl

To verify if the kernel have this driver, at runtime on board , the configuration of kernel available:

$BOARD> cat /proc/config.gz | gunzip | grep HTS221
CONFIG_HTS221=y
CONFIG_HTS221_I2C=y
CONFIG_HTS221_SPI=y
$BOARD> cat /proc/config.gz | gunzip | grep ST_PRESS
CONFIG_IIO_ST_PRESS=m
CONFIG_IIO_ST_PRESS_I2C=m
CONFIG_IIO_ST_PRESS_SPI=m
$BOARD> cat /proc/config.gz | gunzip |  grep ST_LSM6DS
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_IIO_ST_LSM6DSX_I2C=m
CONFIG_IIO_ST_LSM6DSX_SPI=m

3.2. Kernel device tree[edit source]

The IKS01A expansion board are use via the IC2 bus and on STM32MP157C-DK2 this I2C bus associated are I2C5.
On device tree of STM32MP157C-DK2, the I2C5 must be activated and contains the entry for each hardware to support. Content to add in stm32mp157c-dk2.dts:

 &i2c5 {
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&i2c5_pins_a>;
	pinctrl-1 = <&i2c5_pins_sleep_a>;
	i2c-scl-rising-time-ns = <124>;
	i2c-scl-falling-time-ns = <3>;
	/delete-property/dmas;
	/delete-property/dma-names;

	status = "okay";

	hts221@5f {
		compatible = "st,hts221";
		reg = <0x5f>;
	};
	lsm6dsl@6b {
		compatible = "st,lsm6dsl";
		reg = <0x6b>;
	};
 };
Info white.png Information
Do regenerate a device tree, please follow the indication of [Modify, rebuild and reload the Linux® kernel]

3.3. Activate new configuration on board[edit source]

  • Pre-requisite: you need to have re-generated your device tree and your kernel.
  • Please put the two file on file system of board, on bootfs partition (/boot directory)
$BOARD>  ls -1 /boot/stm32*dk2*                                                                                                     
/boot/stm32mp157c-dk2-a7-examples.dtb
/boot/stm32mp157c-dk2-iks01a2.dtb
/boot/stm32mp157c-dk2-m4-examples.dtb
/boot/stm32mp157c-dk2.dtb
  • add an entry on extlinux.conf file, here on /boot/mmc0_stm32mp157c-dk2_extlinux/extlinux.conf or if there is no mmc0-<something> available on /boot/extlinux/extlinux.conf
 
 # Generic Distro Configuration file generated by OpenEmbedded
 menu title Select the boot mode
 MENU BACKGROUND ../splash.bmp
 TIMEOUT 20
 DEFAULT stm32mp157c-dk2-iks01a2
 LABEL stm32mp157c-dk2-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-a7-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-a7-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-m4-examples-sdcard
         KERNEL /uImage
         FDT /stm32mp157c-dk2-m4-examples.dtb
         APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
 LABEL stm32mp157c-dk2-iks01a2
        KERNEL /uImage
        FDT /stm32mp157c-dk2-iks01a2.dtb
        APPEND root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
Warning white.png Warning
don't forget to synchronize the filesystem before to reboot the board
$BOARD> sync
  • Reboot the board

3.4. Verify new configuration on board[edit source]

  • Verify if i2c5 are enable:
$BOARD> cat /proc/device-tree/soc/i2c\@40015000/status 
okay
  • Verify if motions MEMS driver are declared on device tree node:
$BOARD> ls -l /proc/device-tree/soc/i2c\@40015000/
total 0
-r--r--r-- 1 root root  4 Dec 19 11:01 #address-cells
-r--r--r-- 1 root root  4 Dec 19 11:01 #size-cells
-r--r--r-- 1 root root  8 Dec 19 11:01 clocks
-r--r--r-- 1 root root 15 Dec 19 11:01 compatible
-r--r--r-- 1 root root  6 Dec 19 11:01 dma-names
-r--r--r-- 1 root root 32 Dec 19 11:01 dmas
drwxr-xr-x 2 root root  0 Dec 19 10:54 hts221@5f
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-falling-time-ns
-r--r--r-- 1 root root  4 Dec 19 11:01 i2c-scl-rising-time-ns
-r--r--r-- 1 root root 19 Dec 19 11:01 interrupt-names
-r--r--r-- 1 root root 44 Dec 19 11:01 interrupts-extended
drwxr-xr-x 2 root root  0 Dec 19 10:54 lsm6dsl@6b
-r--r--r-- 1 root root  4 Dec 19 11:01 name
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-0
-r--r--r-- 1 root root  4 Dec 19 11:01 pinctrl-1
-r--r--r-- 1 root root 14 Dec 19 11:01 pinctrl-names
-r--r--r-- 1 root root  4 Dec 19 11:01 power-domains
-r--r--r-- 1 root root  8 Dec 19 11:01 reg
-r--r--r-- 1 root root  8 Dec 19 11:01 resets
-r--r--r-- 1 root root 12 Dec 19 11:01 st,syscfg-fmp
-r--r--r-- 1 root root  5 Dec 19 11:01 status
  • Verify if the driver are probed correctly and see the hardware:
$BOARD> grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
/sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
/sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
/sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
/sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl

4. Read Motion MEMS on Linux via Bash script[edit source]

4.1. List of sensors entry[edit source]

IKS01A2 expansion board provide several MEMS like hts221, lsm6dsl, lp22hb. The list of hardware (mems) detected by linux via IIO framework can be listed by verifying the entry on sysfs.

$BOARD>  grep OF_NAME /sys/bus/iio/devices/iio\:device*/uevent
/sys/bus/iio/devices/iio:device0/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device1/uevent:OF_NAME=adc
/sys/bus/iio/devices/iio:device2/uevent:OF_NAME=hts221
/sys/bus/iio/devices/iio:device3/uevent:OF_NAME=temp
/sys/bus/iio/devices/iio:device4/uevent:OF_NAME=lsm6dsl
/sys/bus/iio/devices/iio:device5/uevent:OF_NAME=lsm6dsl

This list of entries permit to know on which entry are associated a MEMS driver. In the rest of the article, we will keep this list as reference list of entries.

4.2. HTS221: Temperature/Humidity[edit source]

HTS221 is a capacitive digital sensor for relative humidity and temperature.

In this example hts221 entry are /sys/bus/iio/devices/iio:device2/.

4.2.1. Temperature[edit source]

  • Read entry associated to temperature for HTS221 driver
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_temp_raw
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_temp_offset
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_temp_scale
  • Calculate real temperature:
Temperature = ( Raw value + Offset value) * Scale value)
  • Calculate temperature by shell script

Content of hts221_read_temperature.sh:

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_temp_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_temp_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_temp_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Temperature $temperature"
printf "Temperature %.02f\n" $temperature
  • Test on board
$BOARD> ./hts221_read_temperature.sh
Value read: raw         563.000000
Value read: offset      1036.674817
Value read: scale       0.019172
Temperature 30.668765624
Temperature 30.67

4.2.2. Humidity[edit source]

  • Read entry associated to humidity for HTS221 driver
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset
$BOARD> cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale
  • Calculate real humidity
Humidity = ( Raw value + Offset value) * Scale value)
  • Calculate humidity by shell script

Content of hts221_read_humidity.sh:

#!/bin/sh
raw=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_raw`
offset=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_offset`
scale=`cat /sys/bus/iio/devices/iio\:device2/in_humidityrelative_scale`
printf "Value read: raw         %0f\n" $raw
printf "Value read: offset      %0f\n" $offset
printf "Value read: scale       %0f\n" $scale

humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`

echo "Humidity $humidity"
printf "Humidity %.02f\n" $humidity
  • Test on board
$BOARD> ./hts221_read_humidity.sh
Value read: raw         2669.000000
Value read: offset      -10661.500000
Value read: scale       -0.003000
Humidity 23.977500000
Humidity 23.98

4.3. LSM6DSL: Accelerometer/Gyroscope[edit source]

HTS221 is an inertial measurement unit (IMU), for smart phones and battery operated IoT, Gaming, Wearable and Consumer Electronics. Ultra-low power and high accuracy.

In this example lsm6dsl entry are /sys/bus/iio/devices/iio:device4/ and /sys/bus/iio/devices/iio:device4/.
Device4 entry are dedicated Accelerometer and device5 for gyroscope.

4.3.1. Accelerometer[edit source]

  • Read entry associated to Accelerometer for LSM6DSL driver
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw
$BOARD> cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale
  • Calculate accelerometer value:
X = Raw value * scale value * (256.0 / 9.81)
Y = Raw value * scale value * (256.0 / 9.81)
Z = Raw value * scale value * (256.0 / 9.81)
  • Calculate accel value by shell script

Content of lsm6dsl_accel_read.sh:

#!/bin/sh
xraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_raw`
xscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_x_scale`

yraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_raw`
yscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_y_scale`

zraw=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_raw`
zscale=`cat /sys/bus/iio/devices/iio\:device4/in_accel_z_scale`

printf "Value read: X (raw/scale)  %d / %.06f \n" $xraw $xscale
printf "Value read: Y (raw/scale)  %d / %.06f \n" $yraw $yscale
printf "Value read: Z (raw/scale)  %d / %.06f \n" $zraw $zscale

factor=`echo "scale=2;256.0 / 9.81" | bc`
xval=`echo "scale=2;$xraw*$xscale*$factor" | bc`
yval=`echo "scale=2;$yraw*$yscale*$factor" | bc`
zval=`echo "scale=2;$zraw*$zscale*$factor" | bc`

printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
  • Test on board
$BOARD> ./lsm6dsl_accel_read.sh
Value read: X (raw/scale)  104 / 0.000598 
Value read: Y (raw/scale)  -16378 / 0.000598 
Value read: Z (raw/scale)  -1117 / 0.000598 
Accelerometer value: [ 1.62, -255.53, -17.43 ]