.. _SD.Kernel.Bm1088ImuIioDriver: .. include:: /content/swdocs.rsts .. spelling:: IMU IIO ADC BMI gyroscope accelerometer AON GPIO gpio CONFIG BMI088 SYSFS TEGRA HTS GTE NVS BMI08X accel addr reg irq gpio accel irq DT INT BM1088 IMU IIO Driver !!!!!!!!!!!!!!!!!!!!! The Linux industrial IO (IIO) is framework that is used to implement sensor drivers such as analog-to digital-converters (ADC), temperature, light, and inertial measurement unit (IMU). The `BMI088 is Bosch IMU ; status = "okay"; reg = <0x69>; accel_irq_gpio = <&tegra_aon_gpio TEGRA_AON_GPIO(BB, 0) GPIO_ACTIVE_HIGH>; gyro_irq_gpio = <&tegra_aon_gpio TEGRA_AON_GPIO(BB, 1) GPIO_ACTIVE_HIGH>; accel_matrix = [01 00 00 00 01 00 00 00 01]; gyro_matrix = [01 00 00 00 01 00 00 00 01]; accel_reg_0x53 = <0x0A>; gyro_reg_0x16 = <0x01>; gyro_reg_0x18 = <0x01>; }; Accelerometer IIO Attributes @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The accelerometer IIO device files that are listed in the following table are available in ``/sys/bus/iio/devices/iio:deviceX/``, where the ``X`` value is enumerated during IIO registration. .. note:: The following table assumes that user is in the ``/sys/bus/iio/devices/iio:deviceX/`` directory. .. list-table:: :widths: auto :header-rows: 1 * - IIO SYSFS Interface - Default Value - Possible Values - Usage * - **Buffer Management** - - - * - buffer/enable - 0 - 0, 1 - Writing 1 enables buffer and data acquisition, at least one axis needs to be enabled before enabling the buffer. * - buffer/length - 64 - N/A - Internally kernel uses ``kmalloc`` to allocate the required length. - The maximum value depends on the state of system memory that is available to kernel at the point of the request. * - buffer/watermark - 1 - 1, buffer length - The application using poll and friends will wait till this number of samples are collected. * - **Debug** - - - * - dev_err - Here are the values: - I2C Bus Errors:0 - GTE Timestamp Errors:0 - Sample dropped:0 - N/A - Read-only, displays the current errors. - It records the i2c bus and hardware timestamp errors. - Hardware timestamp errors are recorded when the driver fails to retrieve hardware timestamp for the given datasets. The hardware timestamp, also known as GTE, has been dividied in the following way: - GTE Timestamp Errors: is a real timestamp failure, which means that the driver could not retrieve the hardware timestamp. - Sample dropped: The samples were dropped. This can happen when the data rate is higher than what i2c bus can handle. * - dev_state - N/A - N/A - Read-only and displays device state, for example, suspend/shutdown. * - dump_regs - N/A - N/A - Read-only and dumps all the current register values. * - **Common Attributes** - - - * - in_accel_sampling_frequency - 12.5 - 12.5, 25, 50, 100, 200, 400, 800, 1600 - This is output data rate (ODR) in Hz. - The user can write any values from the list. - The I2C bus clock speed dictates what the user can program. * - in_accel_sampling_frequency_available - 12.5, 25, 50, 100, 200, 400, 800, 1600 - N/A - Read-only and displays the available ODR. * - in_accel_scale - 0.000897 - 0.000897, 0.00179, 0.003591, and 0.007182 - This interface represents the resolution and its value will be used to calculate actual value from the raw data. - Stop the user space application **before** you change the scale value. * - in_accel_scale_available - 0.000897, 0.00179, 0.003591, 0.007182 - N/A - Read-only and displays the available scales. * - in_accel_x_raw - N/A - N/A - Fetches the raw X-axis value. To read, the respective scan element and device buffer must be enabled. * - in_accel_y_raw - N/A - N/A - Fetches the raw Y-axis value. To read, the respective scan element and device buffer must be enabled. * - in_accel_z_raw - N/A - N/A - Fetches the raw Z-axis value. To read, the respective scan element and device buffer must be enabled. * - mount_matrix - 1,0,0,0,1,0,0,0,1 - N/A - Read-only, displays current mount matrix, which is by default, its identity matrix. - Refer to `https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/iio/mount-matrix.txt `_ for more information. * - name - "accelerometer" - N/A - Read-only value. * - part - "bmi08x accelerometer" - N/A - Read-only value displays the Bosch IMU model. * - trigger/current_trigger - accelerometer-devX - N/A - The trigger comes from the device, and no other value is acceptable. - Here, the value for X is the same as the enumerated IIO device. * - **Channel Attributes** - - - * - scan_elements/in_accel_x_en - 0 - 0,1 - Writing 1 enables X axis/channel, this needs to be set before you enable the buffer. * - scan_elements/in_accel_x_en - 0 - 0,1 - Writing 1 enables Y axis/channel, this needs to be set before you enable the buffer. * - scan_elements/in_accel_z_en - 0 - 0,1 - Writing 1 enables Z axis/channel, this needs to be set before you enable the buffer. * - scan_elements/in_timestamp_en - 0 - 0,1 - Writing 1 enables timestamp channel, this needs to be set before you enable the buffer. * - scan_elements/in_accel_x_index - 0 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_accel_y_index - 1 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_accel_z_index - 2 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_timestamp_index - 3 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_accel_x_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the X-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_accel_y_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the Y-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_accel_z_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the Z-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_timestamp_type - "le:s64/64>>0" - N/A - Read-only and displays details about how the timestamp data is represented in the buffer. This value means data is a little endian-signed 64 bits and does not require a shift operation. Gyroscope IIO @@@@@@@@@@@@@ .. list-table:: :widths: auto :header-rows: 1 * - IIO SYSFS Interface - Default Value - Possible Values - Usage * - **Buffer Management** - - - * - buffer/enable - 0 - 0, 1 - Writing 1 enables buffer and data acquisition. * - buffer/length - 600 - N/A - Internally kernel uses ``kmalloc`` to allocate the required length. - The maximum value depends on the state of system memory that is available to kernel at the point of the request. * - buffer/watermark - 1 - 1, buffer length - The application that uses ``poll`` and ``friends`` will wait until this number of samples are collected. * - **Debug** - - - * - dev_err - Here are the values: - I2C Bus Errors:0 - GTE Timestamp Errors:0 - Sample dropped:0 - N/A - Read-only, displays the current errors. - It records the i2c bus and hardware timestamp errors. - Hardware timestamp errors are recorded when the driver fails to retrieve hardware timestamp for the given datasets. The hardware timestamp, also known as GTE, has been dividied in the following way: - GTE Timestamp Errors: is a real timestamp failure, which means that the driver could not retrieve the hardware timestamp. - Sample dropped: The samples were dropped. This can happen when the data rate is higher than what i2c bus can handle. * - dev_state - N/A - N/A - Read-only and displays device state, for example, suspend/shutdown. * - dump_regs - N/A - N/A - Read-only and dumps all the current register values. * - **Common Attributes** - - - * - in_accel_sampling_frequency - 100 - 100, 200, 400, 1000, 2000 - This is output data rate (ODR) in Hz. - The user can write any values from the list. - The I2C bus clock speed dictates what the user can program. * - in_accel_sampling_frequency_available - 100, 200, 400, 1000, 2000 - N/A - Read-only and displays the available ODR. * - in_accel_scale - 0.001065 - 0.001065, 0.000532, 0.000266, 0.000133, 0.000066 - This interface represents the resolution and its value will be used to calculate actual value from the raw data. - Stop the user space application **before** you change the scale value. * - in_accel_scale_available - 0.001065, 0.000532, 0.000266, 0.000133, 0.000066 - N/A - Read-only and displays the available scales. * - in_accel_x_raw - N/A - N/A - Fetches the raw X-axis value. To read, the respective scan element and device buffer must be enabled. * - in_accel_y_raw - N/A - N/A - Fetches the raw Y-axis value. To read, the respective scan element and device buffer must be enabled. * - in_accel_z_raw - N/A - N/A - Fetches the raw Z-axis value. To read, the respective scan element and device buffer must be enabled. * - mount_matrix - 1,0,0,0,1,0,0,0,1 - N/A - Read-only, displays current mount matrix, which is by default, its identity matrix. - Refer to `https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/iio/mount-matrix.txt `_ for more information. * - name - "gyroscope" - N/A - Read-only value. * - part - "bmi08x gyroscope" - N/A - Read-only value displays the Bosch IMU model. * - trigger/current_trigger - gyroscope-devX - N/A - The trigger comes from the device, and no other value is acceptable. - Here, the value for X is the same as the enumerated IIO device. * - **Channel Attributes** - - - * - scan_elements/in_anglvel_x_en - 0 - 0,1 - Writing 1 enables the X axis/channel, and this needs to be set before you enable the buffer. * - scan_elements/in_anglvel_y_en - 0 - 0,1 - Writing 1 enables the Y axis/channel, and this needs to be set before you enable the buffer. * - scan_elements/in_anglvel_z_en - 0 - 0,1 - Writing 1 enables the Z axis/channel, and this needs to be set before you enable the buffer. * - scan_elements/in_timestamp_en - 0 - 0,1 - Writing 1 enables the timestamp channel, and this needs to be set before you enable the buffer. * - scan_elements/in_anglvel_x_index - 0 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_anglvel_y_index - 1 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_anglvel_z_index - 2 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_timestamp_index - 3 - N/A - Read-only and provides the channel index to the dataset. The data set is 6 + 8 bytes, where there are two bytes for each axis, and eight bytes for the timestamp. * - scan_elements/in_anglvel_x_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the X-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_anglvel_y_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the Y-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_anglvel_z_type - "le:s16/16>>0" - N/A - Read-only and displays details about how the Z-axis data is represented in the buffer. This value means that the data is a little endian-signed 16 bits and does not require a shift operation. * - scan_elements/in_timestamp_type - "le:s64/64>>0" - N/A - Read-only and displays details about how the timestamp data is represented in the buffer. This value means data is a little endian-signed 64 bits and does not require a shift operation. Testing the BM1088 Driver @@@@@@@@@@@@@@@@@@@@@@@@@ There is a sample IIO utility available in ``/tools/iio/``, where ``kernel source`` is the kernel source repository. The ``iio_generic_buffer.c`` sample application is used to demonstrate the driver. During the execution, the application enables the scan elements and buffer for the specified device as described in *Hardware Timesptamping Engine (GTE)*. After the process is complete, the application automatically disables the scan elements and buffer. Hardware Timesptamping Engine (GTE) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The IIO framework uses s64, which are signed 64bits to represent the timestamp information that is reflected the ``app iio_generic_buffer`` userspace in this section. However the GTE uses u64, which are unsigned 64bits. Run the following command to to update the ``iio_generic_buffer.c`` file to use signed bits as below before proceeding to the next section. .. code-block:: none diff --git a/iio_generic_buffer.c b/iio_generic_buffer.c index f90ea14..1cbde1e 100644 --- a/iio_generic_buffer.c +++ b/iio_generic_buffer.c @@ -158,7 +158,7 @@ void print8byte(uint64_t input, struct iio_channel_info *info) printf("%05f ", ((float)val + info->offset) * info->scale); } else { - printf("%05f ", ((float)input + info->offset) * info->scale); + printf("%" PRIu64 " ", input); } } Compile and Execute @@@@@@@@@@@@@@@@@@@ .. note:: For the kernel version 5.10.x and later, if the timestamp channel is specified, the IIO framework enables it by default, and the above command will result in in the following error: .. code-block:: none root@jetson:~# ./iio_generic_buffer -a -c 10 --device-name accelerometer -g -l 64 iio device number being used is 0 trigger-less mode selected Auto-channels selected but some channels are already activated in sysfs Proceeding without activating any channels Failed to enable buffer: Invalid argument To get around that, make sure to disable timestamp channel before executing iio_generic_buffer by issuing "echo 0 > /sys/bus/iio//scan_elements/in_timestamp_en" in the jetson device as a root. Accelerometer Sample Output @@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. code-block:: none root@tegra-ubuntu:~# ./iio_generic_buffer -a -c 10 --device-name accelerometer -g iio device number being used is 2 trigger-less mode selected scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_y_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_x_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_timestamp_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_z_en , enabled:0 No channels are enabled, enabling all channels Enabling: in_accel_y_en Enabling: in_accel_x_en Enabling: in_timestamp_en Enabling: in_accel_z_en scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_y_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_x_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_timestamp_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device2/scan_elements/in_accel_z_en , enabled:1 buffer directory: /sys/bus/iio/devices/iio:device2/buffer X Axis Y Axis Z Axis Timestamp [This row is not present in the output] -9.484633 -0.103250 1.109713 4515182411776 -9.560051 -0.098761 1.115998 4515261579264 -9.547482 -0.096965 1.116896 4515340746752 -9.543890 -0.092476 1.117793 4515419914240 -9.547482 -0.096067 1.112406 4515499606016 -9.542993 -0.096965 1.112406 4515578773504 -9.550175 -0.107739 1.112406 4515657940992 -9.548379 -0.105046 1.115100 4515737108480 -9.540298 -0.101454 1.109713 4515816275968 -9.545686 -0.095170 1.116896 4515895443456 Disabling: in_accel_y_en Disabling: in_accel_x_en Disabling: in_timestamp_en Disabling: in_accel_z_en Gyroscope Sample Output @@@@@@@@@@@@@@@@@@@@@@@ .. code-block:: none root@tegra-ubuntu:~# ./iio_generic_buffer -a -c 10 --device-name gyroscope -g iio device number being used is 3 trigger-less mode selected scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_z_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_timestamp_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_y_en , enabled:0 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_x_en , enabled:0 No channels are enabled, enabling all channels Enabling: in_anglvel_z_en Enabling: in_timestamp_en Enabling: in_anglvel_y_en Enabling: in_anglvel_x_en scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_z_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_timestamp_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_y_en , enabled:1 scan element filename:/sys/bus/iio/devices/iio:device3/scan_elements/in_anglvel_x_en , enabled:1 buffer directory: /sys/bus/iio/devices/iio:device3/buffer X Axis Y Axis Z Axis Timestamp [This row is not present in the output] 0.000000 0.000000 -0.001064 4629188837376 0.000000 0.000000 -0.002128 4629198798848 0.001064 0.000000 -0.002128 4629208760320 0.002128 0.000000 -0.002128 4629218721792 0.002128 0.000000 -0.001064 4629228683264 0.002128 0.000000 -0.001064 4629238644736 0.002128 0.000000 -0.001064 4629248606208 0.001064 0.000000 -0.001064 4629258567680 0.001064 0.000000 -0.001064 4629268529152 0.002128 -0.001064 -0.001064 4629278490624 Disabling: in_anglvel_z_en Disabling: in_timestamp_en Disabling: in_anglvel_y_en Disabling: in_anglvel_x_en