ICM-20948 Driver Low-Lever driver pre IMU ICM-20948

ICM 20948 driver for STM32

Basic driver for TDK InvenSense ICM-20948. It support 2 modes:

  • pooling
  • interrupt

Public API

Class Icm20948

  • void Stop(void) - stop the continuous measuring
  • void Start(void) - start the automatic/continuous measure
  • void Sleep() / void Wakeup() put to sleep/wakeup sensor
  • void Reset() reinitialise sensor
  • uint8_t GetDataStatus(void) return 1, when data is ready to read
  • bool IsReady() get status information. The state can be changed by Start/Stop methods
  • uint8_t IsSleep() return 1, is device is in sleep mode
  • void Read() perform data read from device; from all sensors: accelerometer, gyroscope and Magnetometer (if is enabled)
  • void Calibrate(*config) - perform calibration and put configuration (Low pass filter, sample rate, scale) fo sensors, if config is not NULL
  • void SetInterruptSource(source) Source can be: interrupt_disable, interrupt_DMP_INT1_EN, interrupt_PLL_RDY_EN, interrupt_WOM_INT_EN, interrupt_REG_WOF_EN, interrupt_RAW_DATA_0_RDY_EN
  • public members: -- SensorAccel - accelerometer -- SensorGyro - gyroscope -- SensorMag - magneometer

Public methods in class for sensor representation Sensor:

  • void SetScaleFactor(float sf)
  • void SetRange(range) / uint8_t GetRange()
  • void SetLowPassFilter(filter) / uint8_t GetLowPassFilter()
  • uint8_t SetSampleRate(value) / uint8_t GetSampleRate()
  • void Calibrate(void)
  • uint8_t GetDataStatus(void) return 1 whed data are ready to read
  • axisesI *GetData(void) - return pointer to measured data. Data have to be previously read by ICM20948::Read method
  • bool Read(axisesI *) peform local read from single sensor
  • bool ReadUnit(axisesF*)peform local read from single sensor, make recalculation to real values (acceleration, angular speed) as floats

Working modes

Pooling

#include <stdlib.h>
#include "icm20948.h"

int main(void)
{
  // HAL_Init, etc...

  SpiManager manager(&hspi2);

  icm20948_Config config;
  config.pinCS = &pinCS;
  config.gyro.low_pass_filter = GYRO_lpf_196_6Hz;
  config.gyro.sample_rate = GYRO_samplerate_281_3Hz;
  config.accel.low_pass_filter = ACCEL_lpf_246Hz;
  config.accel.sample_rate = ACCEL_samplerate_281_3Hz;

  Icm20948 sensor(&manager, &config2);

 axisesF sensor_dataF;  // float values
 axisesI sensor_dataI;  // int16 values

  while (1)
  {
    // read raw values
    if(sensor.GetDataStatus() == 1 ){
      //read raw data
      sensor.accSensor->Read(&sensor_dataI);
      sensor.gyroSensor->Read(&sensor_dataI);
      sensor.magSensor->Read(&sensor_dataI);

      // or unit conversion
      sensor.accSensor->ReadUnit(&sensor_dataF);
      sensor.gyroSensor->ReadUnit(&sensor_dataF);
      sensor.magSensor->ReadUnit(&sensor_dataF);
    }

  }
}

Interrupt


#include "icm20948.h"

Device_TypeDef *module;
volatile uint8_t icm_ready;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == ICM_INT_Pin){
    icm_ready = 1;
  }
}

int main(void)
{

  // HAL_Init, etc...

  axises *my_gyro1 = NULL;
  axises *my_accel1 = NULL;

  SpiManager manager(&hspi2);

  icm20948_Config config1;
  config1.pinCS = &pinCS;
  config1.pinINT = &pinINT;
  config1.gyro.low_pass_filter = GYRO_lpf_196_6Hz;
  config1.gyro.sample_rate = GYRO_samplerate_281_3Hz;
  config1.accel.low_pass_filter = ACCEL_lpf_246Hz;
  config1.accel.sample_rate = ACCEL_samplerate_281_3Hz;
  config1.mag.mode = mag_mode_cont_measurement_100hz;
  config1.int_source = interrupt_RAW_DATA_0_RDY_EN;

  while (1)
  {
    if(icm_ready1 == 1){
      icm_ready1 = 0;

      sensor1.Read();   // read data from sensors

      my_accel1 = sensor1.accSensor->GetData(); // only return prepared data
      my_gyro1 = sensor1.gyroSensor->GetData();
      my_mag1 = sensor1.magSensor->GetData();
    }
  }
}
Contributors 1
Juraj Ďuďák 100.0%
Languages
  • C++ [69.17%]
  • C [30.83%]
  • Relations
    simplefs
    similar
    gait-analyser
    depended
    dataframe
    similar
    Created at 30.12.2022
    Last update 13.01.2025, 22:35:28