# 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 ```c #include #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 ```c #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(); } } } ```