Bosch SMI230 IIO driver

1. Overview

The driver is intended to work on Bosch SMI230 Inertial Sensor for Non-Safety Automotive Applications. The SMI230 is a combined triaxial accelerometer (ACC) and triaxial gyroscope (GYR) for non-safety related applications, e.g. for in-dash navigation in the passenger compartment. Within one package, the SMI230 offers the detection of acceleration and angular rate for the x-, y-, and z-axis. The digital standard serial peripheral interface (SPI) of the SMI230 allows for bi-directional data transmission. To increase flexibility, both gyroscope and accelerometer can be operated individually, but can also be tied together for data synchronization purposes.

2. Hardware Setup

Important

This Hardware Setup serves as a quick startup kit, to help the user to run and understand the driver. It is for demonstration purposes, not supposed to be used in a production environment.

2.1 Hardware Components:

  1. Linux Host Board

  2. SMI230 sensor + Shuttleboard + Motherboard (acquirable from Bosch)

  3. connection cable (female to female)

  4. a mini SD card

2.2 Cable Connection

 .................................                      .................................
.?^^^^^^^^^^~~~~~~~~^^^^^^^^^^^^^~?       VDD          !!^^^^^^^^^~~~~~~~~~~~~~~^^^^^^^^7~
:?          Host Board            Y~~~~~~~~~~~~~~~~~~~~J~ 2    SMI230 Mother Board      !!
:?                               .J       GND          ?^                               !~
:?                               .Y~~~~~~~~~~~~~~~~~~~~J^ 3                             !~
:?                               .J                    7^                               !~
:?                               .J       MOSI         7^                               !~
:?                               .Y~~~~~~~~~~~~~~~~~~~~J~ 5                             !~
:?                               .J       MISO         ?^                               !~
:?                               .Y~~~~~~~~~~~~~~~~~~~~J~ 4                             !~
:?                               .Y       SCLK         J~                               !~
:?                               .J~~~~~~~~~~~~~~~~~~~~?~ 6                             !~
:?                               .Y      SPI CE0       J~                               !~
:?                               .Y~~~~~~~~~~~~~~~~~~~~J~ 8                             !~
:?                               .J      SPI CE1       7^                               !~INT1
:?                               .J~~~~~~~~~~~~~~~~~~~~7^ 14                         21 !~~~~~~~
:?                               .J                    7^                               !~     |
:?                               .J                    7^                               !~INT3 |
:?                               .J      INT2          7^                            22 !~~~~~~~
:?                               .Y~~~~~~~~~~~~~~~~~~~~J^ 20                            !~
:?                               .J      INT4          ?^                               !~
:?                                Y~~~~~~~~~~~~~~~~~~~~J^ 19                            !~
:J...............................:J                    7~...............................7~
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                    :^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.

2.3 First Startup

  1. Write Linux Image (32 bit) to SD Card

  2. Insert SD Card Host Board and power on

  3. Enable SSH on Host Board

  4. Switch the Bus selection to SPI on mother board. The green LED shall be on

3. Software Setup

3.1 Required Software

  1. Linux kernel

  2. SMI230 IIO Linux driver https://github.com/boschmemssolutions/SMI230-Linux-Driver-IIO

  3. Linux environment (native or as VM)

Note

We do not recommend to build the driver with Linux kernel directly on host board. This takes too long. Build it on PC is much faster. Since the toolchain is Linux based, a Linux environment is required. We use Ubuntu 20.04.1 LTS

  • Install Toolchain and dependences

sudo apt install crossbuild-essential-armhf
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
  • Clone Linux kernel

We use kernel v6.6.

  • Clone SMI230 IIO Linux driver

git clone --depth=1  https://github.com/boschmemssolutions/SMI230-Linux-Driver-IIO.git

3.2 Build SMI230 IIO Linux driver

Integrate Linux driver into Linux kernel

  • Copy source code into Linux kernel

cp -r SMI230-Linux-Driver-IIO/drivers/iio/imu/smi230 linux/drivers/iio/imu
  • Add entry in imu Kconfig

Open linux/drivers/iio/imu/Kconfig and add the SMI230 entry at bottom

source "drivers/iio/imu/inv_icm42600/Kconfig"
source "drivers/iio/imu/inv_mpu6050/Kconfig"
source "drivers/iio/imu/smi230/Kconfig"
source "drivers/iio/imu/st_lsm6dsx/Kconfig"
source "drivers/iio/imu/st_lsm9ds0/Kconfig"
  • Add entry in imu Makefile

Open linux/drivers/iio/imu/Makefile and add the SMI230 entry at bottom

obj-y += smi230/
obj-y += st_lsm6dsx/
obj-y += st_lsm9ds0/
  • Extend devicetree

extend the device tree with the sensor entries. This part is very HW specific. Please consult your HW vendor, how to do it properly for your HW.

I2C example

fragment@0 {
        target = <&i2c_arm>;
        __dormant__ {
                #address-cells = <1>;
                #size-cells = <0>;
                status = "okay";

                smi230acc: smi230acc@18 {
                        compatible = "bosch,smi230acc";
                        reg = <0x18>;
                        interrupt-parent = <&gpio>;
                        interrupts = <26 1>; /*IRQ_TYPE_EDGE_RISING*/
                        interrupt-names = "ACC_INT";
                        status = "okay";
                };
        };
};

fragment@1 {
        target = <&i2c_arm>;
        __dormant__ {
                #address-cells = <1>;
                #size-cells = <0>;
                status = "okay";

                smi230gyro: smi230gyro@68 {
                        compatible = "bosch,smi230gyro";
                        reg = <0x68>;
                        interrupt-parent = <&gpio>;
                        interrupts = <20 1>; /*IRQ_TYPE_EDGE_RISING*/
                        interrupt-names = "GYRO_INT";
                        status = "okay";
                };
        };
};

SPI example

    fragment@2 {
    target = <&spi0>;
    __dormant__ {
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";

        smi230acc@0 {
            compatible = "bosch,smi230acc";
            spi-max-frequency = <10000000>;
            reg = <0>;
            interrupt-parent = <&gpio>;
            interrupts = <26 1>; /*IRQ_TYPE_EDGE_RISING*/
            interrupt-names = "ACC_INT";
        };
    };
};

fragment@3 {
    target = <&spi0>;
    __dormant__ {
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";

        smi230gyro@1 {
            compatible = "bosch,smi230gyro";
            spi-max-frequency = <10000000>;
            reg = <1>;
            interrupt-parent = <&gpio>;
            interrupts = <20 1>; /*IRQ_TYPE_EDGE_RISING*/
            interrupt-names = "GYRO_INT";
        };
    };
};

Build SMI230 Linux driver with the kernel

  • Config SMI230 Linux driver

cd linux
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

Activate the option as following

Hint

To activate an option, press “y” on the option. A * appears, which means this option is activated as part of the kernel. Alternatively we can press “m” on the option. A “M” appears, which means this option is activated as kernel module (not as part of the kernel). Therefore we need to manually install the kernel module by ourself.

Device Drivers -->
      <*>Industrial I/O support  --->
              -*-     Industrial I/O buffering based on kfifo

              -*-     Industrial I/O triggered buffer support

              Inertial measurement units  --->
                      <*> Bosch Sensor SMI230 Inertial Measurement Unit
                      Select communication interface (Enable I2C connection)  --->
                      Select interrupt operation mode (Enable fifo-wm interrupt)  --->
                      Select ACC interrupt ouput pin (use int2 as interrupt ouput)  --->
                      Select GYRO interrupt ouput pin (use int4 as source)  --->
                      Interrupt Features (deactivate interrupt features)  --->
  • Build SMI230 Linux driver

make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs

Note

Build process takes quite long on the first time. To reduce the build time, we use the option “-j4”. This is the option to enable the build process to be executed parallelly in 4 threads. To improve the parallel execution, just give a big number e.g. “-j6”. How many parallel thread to use is dependent on your processor core number.

  • Install the kernel with SMI230 Linux driver in SD card

insert the SD card (created in 2.3). A “bootfs” partition and a “rootfs” partition will be mounted. Find out the mount point. In Ubuntu the mount point looks like that

/media/username/bootfs

/media/username/rootfs

write the kernel with SMI230 Linux driver in SD card

export KERNEL=kernel7
export SD_BOOT_PATH=/media/username/bootfs
export SD_ROOTFS_PATH=/media/username/rootfs
sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=$SD_ROOTFS_PATH modules_install
sudo cp $SD_BOOT_PATH/$KERNEL.img $SD_BOOT_PATH/$KERNEL-backup.img
sudo cp arch/arm/bootfs/zImage $SD_BOOT_PATH/$KERNEL.img
sudo cp arch/arm/bootfs/dts/*.dtb $SD_BOOT_PATH
sudo cp arch/arm/bootfs/dts/overlays/*.dtb* $SD_BOOT_PATH/overlays/
sudo cp arch/arm/bootfs/dts/overlays/README $SD_BOOT_PATH/overlays/
  • adapt the boot configuraion

open the “config.txt” in “boot” partition, and add the following entries

SPI

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=spi=on
dtoverlay=smi230-spi,smi230acc
dtoverlay=smi230-spi,smi230gyro

I2C

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on,i2c_arm_baudrate=400000
dtoverlay=smi230-i2c,smi230acc
dtoverlay=smi230-i2c,smi230gyro

Take the SD card out and put it back in board.

4. Work with SMI230 Linux driver

  • Check driver initialization

Power on the board. We firstly check if the driver was initialized properly

dmesg | grep smi230
[   52.312908] smi230: loading out-of-tree module taints kernel.
[   53.632399] smi230acc_i2c 1-0018: Write config file OK
[   53.746229] Acc and Gyro I2C driver registered successfully

If the driver was installed properly, 2 folders will be created. A number of devicefiles are created in the folders. which we can use to read/write data from/to the sensor

/sys/bus/iio/devices/iio:device0

/sys/bus/iio/devices/iio:device1

Note

Folder name is assigned automatically by the system, therefore does not reflect the sensor type. There is a “name” file in the devicefolder, which we can read to find out the sensor type

cd /sys/bus/iio/devices/iio:device0
sudo su
cat name
smi230acc
  • Work with driver using command line

Note

To change sensor settings we need root access. It is not sufficient just using “sudo …” For the following examples we use accelerometer. Gyroscope is quite similar.

Check sensor type

cd /sys/bus/iio/devices/iio:device0
sudo su
cat name
smi230acc

check power mode and activate if it is suspended.

cat /sys/bus/iio/devices/iio:device0/pwr
suspend
echo normal > /sys/bus/iio/devices/iio:device0/pwr
cat /sys/bus/iio/devices/iio:device0/pwr
normal

Read data from sensor.

cat /sys/bus/iio/devices/iio:device0/in_accel_z_raw
7980

cat /sys/bus/iio/devices/iio:device0/range
4g

cat /sys/bus/iio/devices/iio:device0/odr
100Hz

Change sensor setting

echo 200Hz > /sys/bus/iio/devices/iio:device0/odr
cat /sys/bus/iio/devices/iio:device0/odr
100Hz

echo 8g > /sys/bus/iio/devices/iio:device0/range
cat /sys/bus/iio/devices/iio:device0/range
8g
  • Using driver in C code

SMI 230 Driver provides 2 interfaces for the user space program,

  1. Sensor data interface: IIO Buffer. SMI230 driver writes sensor data into the IIO buffer from kernel space. Program from user space reads the data from the IIO buffer

  2. Sensor Event interface: IIO Event. SMI230 driver sends IIO Event to user space to inform the program in user space that some sensor event happened. (e.g. sensor value over threshold)

ACC Example to read sensor data:

Source code: be able to find inside the linux source tree tools/iio/iio_generic_buffer.c

Build the example

cd tools
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- iio

Upload iio_generic_buffer in board and execute it

Note

For the following exsample we use accelerometer. Gyroscope is quite similar. Run iio_generic_buffer as root. Use device number of SMI230ACC -N 1.

root@raspberrypi:/home/she2rt# ./iio_generic_buffer -n smi230acc -c -1 -a
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_temp_object_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_accel_z_en
/sys/bus/iio/devices/iio:device0 smi230acc-trigger
87.000000 5.000000 8033.000000 26500.000000 1734559005920419779
87.000000 3.000000 8026.000000 26500.000000 1734559005930259755
86.000000 13.000000 8020.000000 26500.000000 1734559005940125825
89.000000 -4.000000 8027.000000 26500.000000 1734559005950007363
91.000000 -19.000000 8032.000000 26500.000000 1734559005959873902
98.000000 -5.000000 8019.000000 26500.000000 1734559005969743305
101.000000 0.000000 8030.000000 26500.000000 1734559005979612760
100.000000 -15.000000 8029.000000 26500.000000 1734559005989482215
112.000000 -18.000000 8020.000000 26500.000000 1734559005999359795
108.000000 -8.000000 8033.000000 26500.000000 1734559006009226023
105.000000 16.000000 8016.000000 26500.000000 1734559006019096317
91.000000 6.000000 8020.000000 26500.000000 1734559006029000986
76.000000 -10.000000 8038.000000 26500.000000 1734559006038880030
82.000000 -13.000000 8025.000000 26500.000000 1734559006048745064
80.000000 7.000000 8017.000000 26500.000000 1734559006058626088
[accX accY accZ temperature time_ns]

Hint

Check the device number of smi230acc by reading “name” from devicefolder

cd /sys/bus/iio/devices/iio:device0
sudo su
cat name
smi230acc

5. SMI230 Firmware Features

The firmware features uses IIO event to signal the user space application that some sensor event happened (e.g. sampling value over threshold). To read the event from user space, the Linux kernel provides a C program uder tools/iio. And we need to firstly complie it and upload to working board.

cd tools
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- iio
scp tools/iio/iio_event_monitor to your board

5.1 Anymotion

Any-motion detection uses the absolute difference (=slope) between the current input and an acceleration reference sample to detect the motion status of the device. This feature can be used for wake-up. An interrupt is generated when the absolute difference exceeds a configurable, preset threshold for a preset duration. For more details see SMI230 TCD

Note

Currently the event type defined by the Linux IIO is not able to cover our firmware features. Therefore we have to map our feature event to the existed IIO event type. We map anymotion event to IIO event type “roc” and direction “rising”

anymotion configuration is able to be found under

/sys/bus/iio/devices/iio:deviceX/events
├── in_accel_x_roc_rising_en                          // enable/disable any motion x-axis
├── in_accel_y_roc_rising_en                          // enable/disable any motion y-axis
├── in_accel_z_roc_rising_en                          // enable/disable any motion z-axis
├── roc_rising_period                                 // configure any motion duration
└── roc_rising_value                                  // configure any motion threshold

enable any motion x-axis with default duration and threshold

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/in_accel_x_roc_rising_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1

Move sensor in x-axis. We will see the anymotion events as following

Event: time: 1667837753823018925, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising
Event: time: 1667837753842726224, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising
Event: time: 1667837753862437586, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising
Event: time: 1667837753882149312, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising
Event: time: 1667837753901861871, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising
Event: time: 1667837753921574535, type: accel(x|y|z), channel: 0, evtype: roc, direction: rising

5.2 Nomotion

No-motion detection uses the absolute slope between two consecutive acceleration signal samples to detect the static state of the device. In no-motion mode, an interrupt is generated if the slope of all enabled axes remains smaller than a preset threshold for a preset duration. For more details see SMI230 TCD

Note

Currently the event type defined by the Linux IIO is not able to cover our firmware features. Therefore we have to map our feature event to the existed IIO event type. We map nomotion event to IIO event type “roc” and direction “falling”

nomotion configuration is able to be found under

/sys/bus/iio/devices/iio:deviceX/events
├── in_accel_x_roc_falling_en                          // enable/disable no motion x-axis
├── in_accel_y_roc_falling_en                          // enable/disable no motion y-axis
├── in_accel_z_roc_falling_en                          // enable/disable no motion z-axis
├── roc_falling_period                                 // configure no motion duration
└── roc_falling_value                                  // configure no motion threshold

enable no motion x-axis with default duration and threshold

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/in_accel_x_roc_falling_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1
Event: time: 1667845513396539597, type: accel(x&y&z), channel: 0, evtype: roc, direction: falling
Event: time: 1667845513416250976, type: accel(x&y&z), channel: 0, evtype: roc, direction: falling
Event: time: 1667845513435964698, type: accel(x&y&z), channel: 0, evtype: roc, direction: falling
Event: time: 1667845513455680347, type: accel(x&y&z), channel: 0, evtype: roc, direction: falling

Since the sensor is static, nomation events come immediately after command execution.

5.3 High-G

The high-g interrupt is based on the comparison of acceleration data against a high-g threshold for the detection of wake-up, shock, or other high-acceleration events. The interrupt is triggered if the absolute value of acceleration data of at least one enabled axis exceeds the programmed threshold for a preset duration. For more details see SMI230 TCD

Note

Currently the event type defined by the Linux IIO is not able to cover our firmware features. Therefore we have to map our feature event to the existed IIO event type. We map high-g event to IIO event type “thresh_adaptive” , map positive acceleration to direction “rising”, and map negative acceleration to direction “falling”

high-g configuration is able to be found under

/sys/bus/iio/devices/iio:deviceX/events
├── in_accel_x_thresh_adaptive_rising_en           // enable/disable high-g x-axis
├── in_accel_y_thresh_adaptive_rising_en           // enable/disable high-g y-axis
├── in_accel_z_thresh_adaptive_rising_en           // enable/disable high-g z-axis
├── thresh_adaptive_rising_hysteresis              // configure high-g hysteresis
├── thresh_adaptive_rising_period                  // configure high-g duration
└── thresh_adaptive_rising_value                   // configure high-g threshold

Note

Please do not get confused by the configuration name. Even the name contains “rising”, it’s not only for positive acceleration. It’s valid for both positive and negative acceleration.

enable high-g x-axis with default hysteresis, duration and threshold

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/in_accel_x_thresh_adaptive_rising_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1

Strongly move sensor in x-axis for several seconds. We will see the high-g events as following (in case of positive acceleration)

Event: time: 1667846375561835822, type: accel(x), channel: 0, evtype: thresh_adaptive, direction: rising
Event: time: 1667846375566740084, type: accel(x), channel: 0, evtype: thresh_adaptive, direction: rising
Event: time: 1667846375571704764, type: accel(x), channel: 0, evtype: thresh_adaptive, direction: rising
Event: time: 1667846375576619964, type: accel(x), channel: 0, evtype: thresh_adaptive, direction: rising
Event: time: 1667846375581546414, type: accel(x), channel: 0, evtype: thresh_adaptive, direction: rising

5.3 Low-G

The low-g interrupt is based on the comparison of acceleration data against a low-g threshold, which is most useful for free-fall detection. An interrupt is generated when the magnitude of the acceleration values goes below the set low-g threshold for a preset duration. For more details see SMI230 TCD

Note

Currently the event type defined by the Linux IIO is not able to cover our firmware features. Therefore we have to map our feature event to the existed IIO event type. We map low-g event to IIO event type “thresh” and direction “falling”

low-g configuration is able to be found under

/sys/bus/iio/devices/iio:deviceX/events
├── thresh_falling_en                                      // enable/disable low-g
├── thresh_falling_hysteresis                              // configure low-g hysteresis
├── thresh_falling_period                                  // configure low-g duration
└── thresh_falling_value                                   // configure low-g threshold

enable low-g with default hysteresis, duration and threshold

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/thresh_falling_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1

Let the sensor have a samll free-fall. We will see the low-g events as following

Event: time: 1667847250777175066, type: accel(x^2+y^2+z^2), channel: 0, evtype: thresh, direction: falling
Event: time: 1667847250796883737, type: accel(x^2+y^2+z^2), channel: 0, evtype: thresh, direction: falling
Event: time: 1667847250816595169, type: accel(x^2+y^2+z^2), channel: 0, evtype: thresh, direction: falling

5.4 Orientation

The orientation detection feature gives information on an orientation change of the SMI230 with respect to the gravitational field vector g. There are the orientations face up / face down, and orthogonal to that portrait upright, landscape left, portrait upside down and landscape right. For more details see SMI230 TCD

Note

Currently the event type defined by the Linux IIO is not able to cover our firmware features. Therefore we have to map our feature event to the existed IIO event type. We map face up/down event to IIO event type “change” and portrait/landscape event to IIO event type “mag”

orientation configuration is able to be found under

/sys/bus/iio/devices/iio:deviceX/events
├── change_rising_en                                     // enable/disable orientation face up/down feature
├── mag_en                                               // enable/disable orientation portrait/landscape
├── mag_hysteresis                                       // configure orientation hysteresis
├── mag_period                                           // configure orientation mode
├── mag_timeout                                          // configure orientation blocking
└── mag_value                                            // configure orientation theta

enable portrait/landscape only

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/mag_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1

turn the sensor up/down/right/left, we will see the following events

Event: time: 1667910697041617202, type: accel, channel: 0, evtype: mag, direction: rising
Event: time: 1667910699447225295, type: accel, channel: 0, evtype: mag, direction: falling
Event: time: 1667910720486024876, type: accel, channel: 0, evtype: mag
Event: time: 1667910725573235402, type: accel, channel: 0, evtype: mag, direction: either

Orientation Mapping

Portrait Upright -> evtype: mag, direction: rising
Portrait Upside Down -> evtype: mag, direction: falling
Landscape Right -> evtype: mag (Note: there is no direction)
Landscape Left -> evtype: mag, direction: either

enable face up/down additionally

sudo su
echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
echo 1 > /sys/bus/iio/devices/iio\:device1/events/mag_en
echo 1 > /sys/bus/iio/devices/iio\:device1/events/change_rising_en
./iio_event_monitor SMI230ACC
Found IIO device with name SMI230ACC with device number 1

turn the sensor up/left, down/left, down/right, ip/right, we will see the following events. Now,for each orientation change we will get 2 events

Event: time: 1667911964122230457, type: accel, channel: 0, evtype: change, direction: rising
Event: time: 1667911964122230457, type: accel, channel: 0, evtype: mag, direction: either
Event: time: 1667911964497059999, type: accel, channel: 0, evtype: change, direction: falling
Event: time: 1667911964497059999, type: accel, channel: 0, evtype: mag, direction: either
Event: time: 1667911973059147751, type: accel, channel: 0, evtype: change, direction: falling
Event: time: 1667911973059147751, type: accel, channel: 0, evtype: mag
Event: time: 1667911974716313160, type: accel, channel: 0, evtype: change, direction: rising
Event: time: 1667911974716313160, type: accel, channel: 0, evtype: mag

Orientation Mapping

Face Up -> evtype: change, direction: rising
Face Down -> evtype: evtype: change, direction: falling

5.4 Data Synchronization

To achieve data synchronization on SMI230, the new data interrupt signal from the gyroscope of the SMI230 needs to be connected to one of the interrupt pins of the SMI230 accelerometer (which can be configured as input pins). The internal signal processing unit of the accelerometer uses the data ready signal from the gyroscope to synchronize and interpolate the data of the accelerometer, considering the group delay of the sensors. The accelerometer part can then notify the host of available data. With this technique, it is possible to achieve synchronized data and provide accelerometer data at an ODR up to 2 kHz. The data synchronization feature supports 100 Hz, 200 Hz, 400 Hz, 1 kHz and 2 kHz data rates. For more details see SMI230 TCD

Note

SMI230 Linux driver only support the application schematic defined in TCD. The SMI230 interrupt pins INT1 (ACC) and INT3 (GYR) have to be connected externally on the PCB. The GYR new data interrupt needs to be mapped to INT3, while INT1 needs to be configured as an input pin. For a data ready host notification, the interrupt pin INT2 (ACC) shall be used.

  • Re-config ther kernel to activate data synchronization

Hint

To activate an option, press “y” on the option. A * appears, which means this option is activated as part of the kernel. Alternatively we can press “m” on the option. A “M” appears, which means this option is activated as kernel module (not as part of the kernel). Therefore we need to manually install the kernel module by ourself.

Device Drivers -->
      <*>Industrial I/O support  --->
              -*-     Industrial I/O buffering based on kfifo

              -*-     Industrial I/O triggered buffer support

              Accelerometers  --->
                      <*> Bosch Sensor SMI230 Accelerometer
                           Select operating mode (New data mode)  --->
                              ( ) New data mode
                              ( ) FIFO mode
                              (X) Data Sync mode

              Digital gyroscope sensors  --->
                      <*> BOSCH SMI230 Gyro Sensor
                           Select working mode (New data)  --->
                              ( ) New data
                              ( ) FIFO
                              (X) Data sync
  • Build SMI230 Linux driver

make -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
  • Install the kernel with SMI230 Linux driver in SD card

insert the SD card (created in 2.3). A “boot” partition and a “rootfs” partition will be mounted. Find out the mount point. In Ubuntu the mount point looks like that

/media/username/boot

/media/username/rootfs

write the kernel with SMI230 Linux driver in SD card

export KERNEL=kernel7
export SD_BOOT_PATH=/media/username/boot
export SD_ROOTFS_PATH=/media/username/rootfs
sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=$SD_ROOTFS_PATH modules_install
sudo cp $SD_BOOT_PATH/$KERNEL.img $SD_BOOT_PATH/$KERNEL-backup.img
sudo cp arch/arm/boot/zImage $SD_BOOT_PATH/$KERNEL.img
sudo cp arch/arm/boot/dts/*.dtb $SD_BOOT_PATH
sudo cp arch/arm/boot/dts/overlays/*.dtb* $SD_BOOT_PATH/overlays/
sudo cp arch/arm/boot/dts/overlays/README $SD_BOOT_PATH/overlays/

Take the SD card out and put it back in board. Power on

data sync configuration is able to be found under acc folder

/sys/bus/iio/devices/iio:deviceX
├── sampling_frequency                                     // data sync output data rate
└── sampling_frequency_available                           // vaild data sync output data rate

Hint

Check the device number of SMI230ACC by reading “name” from devicefolder

cd /sys/bus/iio/devices/iio:device1
sudo su
cat name
SMI230ACC

Enable acc and set output data rate to 100 Hz

sudo su
root@host:/home/pi# echo normal > /sys/bus/iio/devices/iio\:device1/power_mode
root@host:/home/pi# echo 100 > /sys/bus/iio/devices/iio\:device1/sampling_frequency

Read data from buffer

root@host:/home/pi# ./iio_generic_buffer -N 1 -c -1 -a
iio device number being used is 1
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_anglvel_z_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_anglvel_y_en
Enabling: in_accel_z_en
Enabling: in_anglvel_x_en
/sys/bus/iio/devices/iio:device1 SMI230ACC-trigger
-6.000000 -20.000000 8197.000000 -2.000000 3.000000 -2.000000 1669286887634661928
6.000000 -13.000000 8210.000000 -1.000000 2.000000 -2.000000 1669286887644684248
7.000000 -8.000000 8214.000000 -4.000000 3.000000 -1.000000 1669286887654704745
6.000000 -7.000000 8212.000000 0.000000 1.000000 -2.000000 1669286887664725555
5.000000 -20.000000 8203.000000 -3.000000 2.000000 0.000000 1669286887674767145
-7.000000 -39.000000 8213.000000 -2.000000 4.000000 -2.000000 1669286887684766393
-1.000000 -28.000000 8204.000000 -1.000000 1.000000 -1.000000 1669286887694787306
-10.000000 -10.000000 8211.000000 -1.000000 2.000000 -2.000000 1669286887704806866
-8.000000 1.000000 8195.000000 -1.000000 2.000000 -1.000000 1669286887714828249
-28.000000 -16.000000 8199.000000 -1.000000 1.000000 -1.000000 1669286887724851610
-18.000000 -24.000000 8207.000000 -2.000000 1.000000 -2.000000 1669286887734863149
4.000000 -22.000000 8218.000000 -2.000000 2.000000 -1.000000 1669286887744886042
3.000000 -20.000000 8210.000000 0.000000 4.000000 -2.000000 1669286887754906904
13.000000 -19.000000 8209.000000 -3.000000 3.000000 -2.000000 1669286887764926203
14.000000 -17.000000 8206.000000 -3.000000 2.000000 -3.000000 1669286887774948940
6.000000 -6.000000 8213.000000 -2.000000 2.000000 -1.000000 1669286887784969697
[accX_sync accY_sync accZ_sync gyroX, gyroY, gyroZ,time_ns]