Sense.I.9
9-DOF IMU driver for the Sense.I.9 tile (rev c).
Embeds the TDK InvenSense ICM-20948: 6-DOF IMU (accel + gyro) with co-packaged AK09916 3-DOF magnetometer.
Sensor specifications: - Accelerometer: 16-bit, ±2/4/8/16 G, up to 4.5 kHz ODR - Gyroscope: 16-bit, ±250/500/1000/2000 DPS, up to 9 kHz ODR - Magnetometer: 16-bit, ±4900 µT, up to 100 Hz ODR - Temperature: on-chip sensor
Quick Start
Quick start
tiles_hal_core_cfg_t cfg = { .i2c = &hi2c1, .buses = TILES_BUS_I2C };
tiles_hal_t hal;
tiles_hal_core_init(&hal, &cfg);
tile_t imu;
tile_sense_i_9_init(&hal, 0, &imu);
if (tile_is_ready(&imu)) {
int16_t accel[3], gyro[3], mag[3];
tile_sense_i_9_get_raw_accels(&imu, accel);
tile_sense_i_9_get_raw_gyros(&imu, gyro);
tile_sense_i_9_get_raw_mags(&imu, mag);
}Two tiles on one bus
tile_t imu_a, imu_b;
tile_sense_i_9_init(&hal, 0, &imu_a); // pad 2 floating (0x69)
tile_sense_i_9_init(&hal, 1, &imu_b); // pad 2 grounded (0x68)Types & Enums
sense_i_9_accel_range_t
Accelerometer full-scale range.
Sensitivity (LSB/g) for each range: SENSE_I_9_ACCEL_2G → 16384, SENSE_I_9_ACCEL_4G → 8192, SENSE_I_9_ACCEL_8G → 4096, SENSE_I_9_ACCEL_16G → 2048
| Value | Hex | Description |
|---|---|---|
| SENSE_I_9_ACCEL_2G | 0x00 | |
| SENSE_I_9_ACCEL_4G | 0x02 | bits [2:1] of ACCEL_CONFIG |
| SENSE_I_9_ACCEL_8G | 0x04 | |
| SENSE_I_9_ACCEL_16G | 0x06 |
sense_i_9_gyro_range_t
Gyroscope full-scale range.
Sensitivity (LSB/°/s) for each range: SENSE_I_9_GYRO_250DPS → 131.0, SENSE_I_9_GYRO_500DPS → 65.5, SENSE_I_9_GYRO_1000DPS → 32.8, SENSE_I_9_GYRO_2000DPS → 16.4
| Value | Hex | Description |
|---|---|---|
| SENSE_I_9_GYRO_250DPS | 0x00 | |
| SENSE_I_9_GYRO_500DPS | 0x02 | bits [2:1] of GYRO_CONFIG |
| SENSE_I_9_GYRO_1000DPS | 0x04 | |
| SENSE_I_9_GYRO_2000DPS | 0x06 |
sense_i_9_mag_mode_t
Magnetometer operating mode.
Single-measurement mode requires re-triggering for each read. Continuous modes free-run at the specified rate.
| Value | Hex | Description |
|---|---|---|
| SENSE_I_9_MAG_POWER_DOWN | 0x00 | |
| SENSE_I_9_MAG_SINGLE | 0x01 | |
| SENSE_I_9_MAG_CONTINUOUS_10HZ | 0x02 | |
| SENSE_I_9_MAG_CONTINUOUS_20HZ | 0x04 | |
| SENSE_I_9_MAG_CONTINUOUS_50HZ | 0x06 | |
| SENSE_I_9_MAG_CONTINUOUS_100HZ | 0x08 |
Initialization
uint8_t tile_sense_i_9_find(tiles_hal_t* hal, uint8_t instance);Check whether a Sense.I.9 is present on the I2C bus.
Performs an address-level probe only (no register reads).
Parameters
- hal
- Platform HAL handle
- instance
- Instance index (0 = default, see mapping table)
Returns
1 if device ACKs, 0 otherwise
void tile_sense_i_9_init(tiles_hal_t* hal, uint8_t instance, tile_t* tile);Initialize the ICM-20948 and AK09916.
Performs a soft reset, verifies WHO_AM_I, wakes the device, enables all accel + gyro axes, enables I2C bypass for direct magnetometer access, and starts the magnetometer in continuous 100 Hz mode.
Parameters
- hal
- Platform HAL handle
- instance
- Instance index (0 = default, see mapping table)
- tile
- Pointer to tile handle (populated by this function)
Blocks for ~50 ms during reset. Call once at startup.
Configuration
void tile_sense_i_9_set_accel_range(tile_t* tile, sense_i_9_accel_range_t range);Set the accelerometer full-scale range.
Parameters
- tile
- Pointer to tile handle
- range
- One of the sense_i_9_accel_range_t values
void tile_sense_i_9_set_gyro_range(tile_t* tile, sense_i_9_gyro_range_t range);Set the gyroscope full-scale range.
Parameters
- tile
- Pointer to tile handle
- range
- One of the sense_i_9_gyro_range_t values
void tile_sense_i_9_set_mag_mode(tile_t* tile, sense_i_9_mag_mode_t mode);Set the magnetometer operating mode.
Parameters
- tile
- Pointer to tile handle
- mode
- One of the sense_i_9_mag_mode_t values
Switching modes resets the AK09916 measurement cycle.
void tile_sense_i_9_set_accel_odr(tile_t* tile, uint16_t divider);Set the accelerometer output data rate.
ODR = 1125 / (1 + divider) Hz. Examples: divider = 0 → 1125 Hz divider = 4 → 225 Hz divider = 10 → ~102 Hz divider = 44 → 25 Hz
Parameters
- tile
- Pointer to tile handle
- divider
- 11-bit sample rate divider (0–4095)
void tile_sense_i_9_set_gyro_odr(tile_t* tile, uint8_t divider);Set the gyroscope output data rate.
ODR = 1100 / (1 + divider) Hz.
Parameters
- tile
- Pointer to tile handle
- divider
- 8-bit sample rate divider (0–255)
void tile_sense_i_9_reset(tile_t* tile);Perform a software reset.
Resets all registers to defaults. Blocks for ~50 ms. You must call tile_sense_i_9_init() again after reset.
Parameters
- tile
- Pointer to tile handle
Data
uint8_t tile_sense_i_9_data_ready(tile_t* tile);Check if new IMU data is available.
Reads the ICM-20948 interrupt status register.
Parameters
- tile
- Pointer to tile handle
Returns
1 if new data is available, 0 otherwise
void tile_sense_i_9_get_raw_accels(tile_t* tile, int16_t* buffer);Read raw accelerometer data (3-axis).
Returns signed 16-bit ADC counts. Convert to milli-g using the sensitivity for the configured range (e.g. ±2 G → 1 LSB ≈ 0.061 mg).
Parameters
- tile
- Pointer to tile handle
- buffer
- Output array, minimum 3 × int16_t [X, Y, Z]
void tile_sense_i_9_get_raw_gyros(tile_t* tile, int16_t* buffer);Read raw gyroscope data (3-axis).
Returns signed 16-bit ADC counts. Convert to °/s using the sensitivity for the configured range (e.g. ±250 DPS → 131 LSB/°/s).
Parameters
- tile
- Pointer to tile handle
- buffer
- Output array, minimum 3 × int16_t [X, Y, Z]
void tile_sense_i_9_get_raw_6dof(tile_t* tile, int16_t* buffer);Read raw accelerometer + gyroscope data in a single burst.
More efficient than calling get_raw_accels + get_raw_gyros separately (one I2C transaction instead of two). Data is time-coherent.
Parameters
- tile
- Pointer to tile handle
- buffer
- Output array, minimum 6 × int16_t [AX, AY, AZ, GX, GY, GZ]
void tile_sense_i_9_get_raw_mags(tile_t* tile, int16_t* buffer);Read raw magnetometer data (3-axis).
Returns signed 16-bit ADC counts from the AK09916. Sensitivity: 0.15 µT/LSB (all axes).
Parameters
- tile
- Pointer to tile handle
- buffer
- Output array, minimum 3 × int16_t [X, Y, Z]
Automatically reads the ST2 register to release the magnetometer data lock, enabling the next measurement.
int16_t tile_sense_i_9_get_temperature(tile_t* tile);Read the on-chip temperature sensor.
Convert raw value to °C: temp_degC = (raw / 333.87) + 21.0
Parameters
- tile
- Pointer to tile handle
Returns
Raw signed 16-bit temperature value
Power Management
void tile_sense_i_9_sleep(tile_t* tile);Enter low-power sleep mode.
Stops all sensor sampling. Current draw drops to ~8 µA. Call tile_sense_i_9_wake() to resume.
Parameters
- tile
- Pointer to tile handle
void tile_sense_i_9_wake(tile_t* tile);Wake from sleep mode and resume sampling.
Restores auto clock selection. Previously configured ranges and ODRs are preserved across sleep/wake cycles.
Parameters
- tile
- Pointer to tile handle
Auto-generated from tile_sense_i_9.h v2.0.0 — last synced 3/26/2026
