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:
Linux Host Board
SMI230 sensor + Shuttleboard + Motherboard (acquirable from Bosch)
connection cable (female to female)
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
Write Linux Image (32 bit) to SD Card
Insert SD Card Host Board and power on
Enable SSH on Host Board
Switch the Bus selection to SPI on mother board. The green LED shall be on
3. Software Setup
3.1 Required Software
Linux kernel
SMI230 IIO Linux driver https://github.com/boschmemssolutions/SMI230-Linux-Driver-IIO
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,
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
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
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
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]