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 measuringvoid Start(void)
- start the automatic/continuous measurevoid Sleep() / void Wakeup()
put to sleep/wakeup sensorvoid Reset()
reinitialise sensoruint8_t GetDataStatus(void)
return 1, when data is ready to readbool IsReady()
get status information. The state can be changed by Start/Stop methodsuint8_t IsSleep()
return 1, is device is in sleep modevoid 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, ifconfig
is not NULLvoid 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 readaxisesI *GetData(void)
- return pointer to measured data. Data have to be previously read by ICM20948::Read methodbool Read(axisesI *)
peform local read from single sensorbool 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();
}
}
}