Skip to content

Commit 8271117

Browse files
committed
drivers/sensors: Add QST QMI8658 6-axis IMU sensor support
Add complete driver support for the QST QMI8658 6-axis IMU sensor featuring 3-axis accelerometer and 3-axis gyroscope with I2C interface and uORB integration. Key features implemented: * Full I2C communication with configurable frequency (default 400kHz) * Multiple accelerometer ranges (±2g, ±4g, ±8g, ±16g) and ODR settings * Multiple gyroscope ranges (±16 to ±1024 dps) with high ODR support * Low-pass filter configuration for both sensors * Temperature sensing with 16-bit resolution * Self-test capability for both accelerometer and gyroscope * Calibration-on-demand support with offset registers * FIFO buffer management (framework ready) * Interrupt-driven and polling mode support * Complete uORB integration with sensor_accel and sensor_gyro topics Driver components added: * Core driver implementation (qmi8658_uorb.c) with register operations * Header file with register definitions and scale factors (qmi8658.h) * Kconfig options for driver configuration and polling mode * Build system integration (CMakeLists.txt, Make.defs) * Comprehensive documentation with API reference and usage examples The driver follows NuttX sensor framework conventions and provides robust error handling, mutex protection, and comprehensive debugging support through CONFIG_DEBUG_SENSORS. Signed-off-by: Huang Qi <[email protected]>
1 parent d3021ff commit 8271117

File tree

8 files changed

+2159
-0
lines changed

8 files changed

+2159
-0
lines changed

Documentation/components/drivers/special/sensors.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ general interface.
3030
sensors/mcp9600.rst
3131
sensors/mpl115a.rst
3232
sensors/nau7802.rst
33+
sensors/qmi8658.rst
3334
sensors/sht4x.rst
3435
sensors/lsm6dso32.rst
3536
sensors/lis2mdl.rst
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
=======
2+
QMI8658
3+
=======
4+
5+
The QMI8658 is a high-performance 6-axis IMU sensor by QST featuring a 3-axis
6+
accelerometer and 3-axis gyroscope. It supports both I2C and SPI interfaces,
7+
although this driver currently supports I2C communication only.
8+
9+
This driver uses the :doc:`uorb
10+
</components/drivers/special/sensors/sensors_uorb>` interface. It supports the
11+
self-test capability for both the accelerometer and gyroscope.
12+
13+
The driver supports comprehensive features including multiple full-scale ranges,
14+
configurable ODR settings, low-pass filters, FIFO buffer management, temperature
15+
sensing, and device calibration.
16+
17+
.. note::
18+
The QMI8658 is a feature-rich sensor with advanced capabilities like
19+
tap detection, motion detection, and various low-power modes. This driver
20+
implements the core functionality for accelerometer and gyroscope data
21+
acquisition with room for future feature extensions.
22+
23+
Application Programming Interface
24+
=================================
25+
26+
.. code-block:: c
27+
28+
#include <nuttx/sensors/qmi8658.h>
29+
30+
The QMI8658 driver provides one registration function:
31+
32+
- **uORB Interface**: ``qmi8658_uorb_register()``
33+
34+
Registration
35+
------------
36+
37+
The uORB interface registers the driver and creates separate uORB topics for
38+
accelerometer and gyroscope data under ``/dev/uorb/``: ``sensor_accel<n>`` and
39+
``sensor_gyro<n>``, where ``n`` is the device number.
40+
41+
.. code-block:: c
42+
43+
/* Example uORB registration */
44+
45+
ret = qmi8658_uorb_register(0, i2c_bus, QMI8658_I2C_ADDR_DEFAULT);
46+
if (ret < 0)
47+
{
48+
syslog(LOG_ERR, "Couldn't register QMI8658 uORB: %d\n", ret);
49+
return ret;
50+
}
51+
52+
The uORB interface registers the driver and creates separate uORB topics for
53+
accelerometer and gyroscope data under ``/dev/uorb/``: ``sensor_accel<n>`` and
54+
``sensor_gyro<n>``, where ``n`` is the device number.
55+
56+
.. code-block:: c
57+
58+
/* Example uORB registration */
59+
60+
ret = qmi8658_uorb_register(0, i2c_bus, QMI8658_I2C_ADDR_DEFAULT);
61+
if (ret < 0)
62+
{
63+
syslog(LOG_ERR, "Couldn't register QMI8658 uORB: %d\n", ret);
64+
return ret;
65+
}
66+
67+
Configuration Options
68+
=====================
69+
70+
The QMI8658 driver supports several Kconfig options:
71+
72+
* ``CONFIG_SENSORS_QMI8658``: Enable QMI8658 driver support (requires UORB)
73+
* ``CONFIG_SENSORS_QMI8658_POLL``: Enable polling mode with configurable interval
74+
* ``CONFIG_SENSORS_QMI8658_POLL_INTERVAL``: Set polling interval (default 1s)
75+
* ``CONFIG_QMI8658_I2C_FREQUENCY``: Set I2C communication frequency (default 400kHz)
76+
77+
Supported Features
78+
==================
79+
80+
Accelerometer
81+
-------------
82+
83+
* **Full-Scale Ranges**: ±2g, ±4g, ±8g, ±16g
84+
* **Output Data Rates**: 1000Hz, 500Hz, 250Hz, 125Hz, 62.5Hz, 31.25Hz
85+
* **Low-Power ODR**: 128Hz, 21Hz, 11Hz, 3Hz
86+
* **Low-Pass Filters**: 4 different modes + OFF
87+
88+
Gyroscope
89+
---------
90+
91+
* **Full-Scale Ranges**: ±16, ±32, ±64, ±128, ±256, ±512, ±1024 dps
92+
* **Output Data Rates**: 7174.4Hz, 3587.2Hz, 1793.6Hz, 896.8Hz, 448.4Hz, 224.2Hz, 112.1Hz, 56.05Hz, 28.025Hz
93+
* **Low-Pass Filters**: 4 different modes + OFF
94+
95+
Additional Features
96+
-----------------==
97+
98+
* **Temperature Sensor**: 16-bit temperature data with 256 LSB/°C scale factor
99+
* **FIFO Buffer**: Configurable FIFO with watermark and interrupt support
100+
* **Sampling Modes**: Synchronous and asynchronous sampling
101+
* **Interrupt Support**: Data ready, FIFO watermark, motion detection
102+
* **Self-Test**: Built-in self-test capability for both sensors
103+
* **Calibration**: On-demand calibration support
104+
105+
IOCTL Commands
106+
==============
107+
108+
uORB IOCTLs
109+
-----------
110+
111+
* ``SNIOC_SETFULLSCALE``: Set full-scale range (argument in g for accel, dps for gyro)
112+
* ``SNIOC_SET_CALIBVALUE``: Set calibration offsets
113+
* ``SNIOC_SELFTEST``: Perform sensor self-test
114+
* ``SNIOC_WHO_AM_I``: Read device ID (should return 0x05)
115+
116+
Scale Factors
117+
=============
118+
119+
The driver provides predefined scale factors for converting raw sensor data
120+
to physical units:
121+
122+
Accelerometer Scale Factors (LSB/g):
123+
124+
.. code-block:: c
125+
126+
#define QMI8658_ACC_SCALE_2G (16384.0f)
127+
#define QMI8658_ACC_SCALE_4G (8192.0f)
128+
#define QMI8658_ACC_SCALE_8G (4096.0f)
129+
#define QMI8658_ACC_SCALE_16G (2048.0f)
130+
131+
Gyroscope Scale Factors (LSB/dps):
132+
133+
.. code-block:: c
134+
135+
#define QMI8658_GYRO_SCALE_16DPS (2048.0f)
136+
#define QMI8658_GYRO_SCALE_32DPS (1024.0f)
137+
#define QMI8658_GYRO_SCALE_64DPS (512.0f)
138+
#define QMI8658_GYRO_SCALE_128DPS (256.0f)
139+
#define QMI8658_GYRO_SCALE_256DPS (128.0f)
140+
#define QMI8658_GYRO_SCALE_512DPS (64.0f)
141+
#define QMI8658_GYRO_SCALE_1024DPS (32.0f)
142+
143+
Temperature Scale Factor (LSB/°C):
144+
145+
.. code-block:: c
146+
147+
#define QMI8658_TEMP_SCALE (256.0f)
148+
149+
Data Conversion
150+
===============
151+
152+
To convert raw sensor data to physical units:
153+
154+
.. code-block:: c
155+
156+
/* Convert accelerometer raw data to g */
157+
158+
float accel_x_g = (float)raw_accel_x / QMI8658_ACC_SCALE_8G;
159+
float accel_y_g = (float)raw_accel_y / QMI8658_ACC_SCALE_8G;
160+
float accel_z_g = (float)raw_accel_z / QMI8658_ACC_SCALE_8G;
161+
162+
/* Convert gyroscope raw data to dps */
163+
164+
float gyro_x_dps = (float)raw_gyro_x / QMI8658_GYRO_SCALE_512DPS;
165+
float gyro_y_dps = (float)raw_gyro_y / QMI8658_GYRO_SCALE_512DPS;
166+
float gyro_z_dps = (float)raw_gyro_z / QMI8658_GYRO_SCALE_512DPS;
167+
168+
/* Convert temperature raw data to °C */
169+
170+
float temp_c = (float)raw_temp / QMI8658_TEMP_SCALE;
171+
172+
Debugging and Testing
173+
=====================
174+
175+
To debug the QMI8658 device, you can:
176+
177+
1. **Enable Debug Output**: Set ``CONFIG_DEBUG_SENSORS`` and ``CONFIG_DEBUG_INFO``
178+
2. **Use uORB Listener**: Include ``uorb_listener`` application to monitor sensor data
179+
180+
Performance Considerations
181+
==========================
182+
183+
* **I2C Frequency**: Default 400kHz, configurable via ``CONFIG_QMI8658_I2C_FREQUENCY``
184+
* **Polling Overhead**: Use interrupt-driven mode when possible for better efficiency
185+
* **FIFO Usage**: Enable FIFO to reduce I2C traffic and CPU overhead
186+
* **Power Management**: Utilize low-power ODR settings for battery-powered applications
187+
188+
Limitations
189+
===========
190+
191+
* Currently supports I2C interface only (SPI support can be added)
192+
* Advanced features like tap detection and motion detection not yet implemented
193+
* FIFO interrupt handling not fully implemented
194+
* Some low-power modes require additional configuration
195+
196+
Hardware Connections
197+
====================
198+
199+
I2C Interface
200+
--------------
201+
202+
* **VDD**: Power supply (1.71V to 3.6V)
203+
* **GND**: Ground
204+
* **SDA/SDI**: I2C Serial Data
205+
* **SCL/SCLK**: I2C Serial Clock
206+
* **CS**: Chip Select (connect to VDD for I2C mode)
207+
* **INT1/INT2**: Interrupt pins (optional)
208+
209+
Typical I2C addresses:
210+
* **Primary**: 0x6B
211+
* **Secondary**: 0x6D (when SDO/SA0 pin is high)
212+
213+
.. note::
214+
Ensure proper pull-up resistors on SDA and SCL lines (typically 4.7kΩ for 3.3V).
215+
216+
Troubleshooting
217+
===============
218+
219+
**Device Not Responding**
220+
* Check I2C address and connections
221+
* Verify power supply voltage
222+
* Ensure CS pin is properly configured for I2C mode
223+
224+
**Incorrect Readings**
225+
* Verify full-scale range settings
226+
* Check scale factor calculations
227+
* Ensure sensor is properly calibrated
228+
229+
**Communication Errors**
230+
* Reduce I2C frequency
231+
* Check for signal integrity issues
232+
* Verify pull-up resistor values

Documentation/components/drivers/special/sensors/sensors_uorb.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ Implemented Drivers
496496
- mpu9250
497497
- ms56xx
498498
- :doc:`nau7802`
499+
- :doc:`qmi8658`
499500
- :doc:`sht4x`
500501
- :doc:`lsm6dso32`
501502
- wtgahrs2

drivers/sensors/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ if(CONFIG_SENSORS)
344344
list(APPEND SRCS tmp112.c)
345345
endif()
346346

347+
# QMI8658 6-axis IMU
348+
349+
if(CONFIG_SENSORS_QMI8658)
350+
list(APPEND SRCS qmi8658_uorb.c)
351+
endif()
352+
347353
endif() # CONFIG_I2C
348354

349355
# These drivers depend on SPI support

drivers/sensors/Kconfig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,4 +2151,35 @@ config TMP112_I2C_FREQUENCY
21512151

21522152
endif #SENSORS_TMP112
21532153

2154+
config SENSORS_QMI8658
2155+
bool "QST QMI8658 6-Axis IMU Sensor support"
2156+
default n
2157+
depends on I2C && UORB
2158+
---help---
2159+
Enable driver support for the QST QMI8658 6-axis IMU sensor.
2160+
2161+
if SENSORS_QMI8658
2162+
2163+
config SENSORS_QMI8658_POLL
2164+
bool "Enables polling sensor data"
2165+
default n
2166+
---help---
2167+
Enables polling of sensor data.
2168+
2169+
config SENSORS_QMI8658_POLL_INTERVAL
2170+
int "Polling interval in microseconds, default 1s"
2171+
depends on SENSORS_QMI8658_POLL
2172+
default 1000000
2173+
range 0 4294967295
2174+
---help---
2175+
The interval until a new sensor measurement will be triggered.
2176+
2177+
config QMI8658_I2C_FREQUENCY
2178+
int "QMI8658 I2C frequency"
2179+
default 400000
2180+
---help---
2181+
I2C frequency used to communicate with QMI8658.
2182+
2183+
endif # SENSORS_QMI8658
2184+
21542185
endif # SENSORS

drivers/sensors/Make.defs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ ifeq ($(CONFIG_SENSORS_MPU9250),y)
418418
CSRCS += mpu9250_uorb.c
419419
endif
420420

421+
# QMI8658 6-axis IMU
422+
423+
ifeq ($(CONFIG_SENSORS_QMI8658),y)
424+
CSRCS += qmi8658_uorb.c
425+
endif
426+
421427
# Quadrature encoder upper half
422428

423429
ifeq ($(CONFIG_SENSORS_QENCODER),y)

0 commit comments

Comments
 (0)