| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822 |
- /*
- * @file icm20948.c
- *
- * Created on: Dec 26, 2020
- * Author: mokhwasomssi (ANSII C version)
- *
- * Modified: Juraj Dudak (C++ version)
- * Date: 30.12.2022
- */
- #include "icm20948.h"
- uint16_t ACCEL_SampleRate_Table[15] = {
- 1,
- 3,
- 5,
- 7,
- 10,
- 15,
- 22,
- 31,
- 34,
- 127,
- 255,
- 513,
- 1022,
- 2044,
- 4095,
- };
- uint16_t GYRO_SampleRate_Table[16] = {
- 1,
- 2,
- 3,
- 4,
- 5,
- 7,
- 8,
- 10,
- 15,
- 16,
- 22,
- 31,
- 32,
- 63,
- 64,
- 255,
- };
- Icm20948::Icm20948(SpiManager *spi, icm20948_Config *config){
- _activeDevice = spi->addSlave(config->pinCS);
- _spi = spi;
- accSensor = new SensorAccel(spi, _activeDevice);
- gyroSensor = new SensorGyro(spi, _activeDevice);
- magSensor = new SensorMag(spi, _activeDevice);
- while(!this->icm20948_who_am_i());
- this->accSensor->data.type = ICM20948_ACCEL + _activeDevice;
- this->gyroSensor->data.type = ICM20948_GYRO + _activeDevice;
- this->magSensor->data.type = ICM20948_MAG + _activeDevice;
- this->Reset(1);
- this->Wakeup();
- //this->Calibrate(config);
- this->SetInterruptSource(config->int_source);
- this->gyroSensor->SetLowPassFilter(config->gyro.low_pass_filter);
- this->accSensor->SetLowPassFilter(config->accel.low_pass_filter);
- this->gyroSensor->SetSampleRate(config->gyro.sample_rate);
- this->accSensor->SetSampleRate(config->accel.sample_rate);
- this->accSensor->SetRange(config->accel.full_scale);
- this->gyroSensor->SetRange(config->gyro.full_scale);
- this->ak09916_init(&config->mag);
- _sensor_ready = true;
- }
- void Icm20948::Calibrate(icm20948_Config *config)
- {
- this->SetInterruptSource(config->int_source);
- this->accSensor->Calibrate();
- this->gyroSensor->Calibrate();
- this->gyroSensor->SetLowPassFilter(config->gyro.low_pass_filter);
- this->accSensor->SetLowPassFilter(config->accel.low_pass_filter);
- this->gyroSensor->SetSampleRate(config->gyro.sample_rate);
- this->accSensor->SetSampleRate(config->accel.sample_rate);
- this->accSensor->SetRange(config->accel.full_scale);
- this->gyroSensor->SetRange(config->gyro.full_scale);
- this->ak09916_init(&config->mag);
- }
- bool Icm20948::icm20948_who_am_i()
- {
- uint8_t icm20948_id = _spi->read_single_reg(_activeDevice, ub_0, B0_WHO_AM_I);
- if(icm20948_id == ICM20948_ID)
- return true;
- else
- return false;
- }
- void Icm20948::Reset(uint8_t toSleep)
- {
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1, 0x80 | toSleep == 1 ? 0x41 : 0x01); // reset, sleep, source PLL auto
- HAL_Delay(100);
- this->Wakeup();
- //if(toSleep == 0) // reset without sleep - set internal settings
- {
- this->icm20948_clock_source(1);
- this->icm20948_odr_align_enable();
- this->icm20948_spi_slave_enable();
- }
- }
- void Icm20948::Wakeup(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1);
- new_val &= 0xBF;
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1, new_val);
- HAL_Delay(50);
- }
- uint8_t Icm20948::IsSleep(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1);
- return new_val & 0x40;
- }
- bool Icm20948::IsReady(void)
- {
- return _sensor_ready;
- }
- void Icm20948::Stop(void)
- {
- _sensor_ready = false;
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_2, 0x3F);
- }
- void Icm20948::Start(void)
- {
- _sensor_ready = true;
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_2, 0x0);
- }
- void Icm20948::Sleep(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1);
- new_val |= 0x40;
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1, new_val);
- HAL_Delay(100);
- }
- void Icm20948::icm20948_spi_slave_enable()
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_USER_CTRL);
- new_val |= 0x10;
- _spi->write_single_reg(_activeDevice, ub_0, B0_USER_CTRL, new_val);
- }
- void Icm20948::icm20948_i2c_master_reset()
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_USER_CTRL);
- new_val |= 0x02;
- _spi->write_single_reg(_activeDevice, ub_0, B0_USER_CTRL, new_val);
- }
- void Icm20948::icm20948_i2c_master_enable()
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_USER_CTRL);
- new_val |= 0x20;
- _spi->write_single_reg(_activeDevice, ub_0, B0_USER_CTRL, new_val);
- HAL_Delay(100);
- }
- void Icm20948::icm20948_i2c_master_clk_frq(uint8_t config)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_3, B3_I2C_MST_CTRL);
- new_val |= config;
- _spi->write_single_reg(_activeDevice, ub_3, B3_I2C_MST_CTRL, new_val);
- }
- void Icm20948::icm20948_clock_source(uint8_t source)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1);
- new_val |= source;
- _spi->write_single_reg(_activeDevice, ub_0, B0_PWR_MGMT_1, new_val);
- }
- void Icm20948::icm20948_odr_align_enable()
- {
- _spi->write_single_reg(_activeDevice, ub_2, B2_ODR_ALIGN_EN, 0x01);
- }
- void Icm20948::SetInterruptSource(interrupt_source_enum int_source)
- {
- _spi->write_single_reg(_activeDevice, ub_0, B0_INT_PIN_CFG, (INT_PIN_CFG_2CLEAR)); // ( INT_PIN_CFG_LATCH | ...
- uint8_t source1 = (uint8_t)(int_source & 0xFF);
- uint8_t source2 = (uint8_t)((int_source >> 8) & 0xFF);
- _spi->write_single_reg(_activeDevice, ub_0, B0_INT_ENABLE, source1);
- _spi->write_single_reg(_activeDevice, ub_0, B0_INT_ENABLE_1, source2);
- }
- void Icm20948::Read(void)
- {
- uint8_t* temp =_spi->read_multiple_reg(_activeDevice, ub_0, B0_ACCEL_XOUT_H, 12);
- this->accSensor->data.x = (int16_t)(temp[0] << 8 | temp[1]);
- this->accSensor->data.y = (int16_t)(temp[2] << 8 | temp[3]);
- this->accSensor->data.z = (int16_t)(temp[4] << 8 | temp[5]) + this->accSensor->_scaleFactor;
- // Add scale factor because calibration function offset gravity acceleration.
- this->gyroSensor->data.x = (int16_t)(temp[6] << 8 | temp[7]);
- this->gyroSensor->data.y = (int16_t)(temp[8] << 8 | temp[9]);
- this->gyroSensor->data.z = (int16_t)(temp[10] << 8 | temp[11]);
- if(this->_ak09916_enable){
- if(this->magSensor->Read(&this->magSensor->data) == false){
- this->magSensor->data.x = 0;
- this->magSensor->data.y = 0;
- this->magSensor->data.z = 0;
- }
- }
- }
- uint8_t Icm20948::GetDataStatus(void)
- {
- // same register for ACC and GYRO sensor
- return this->accSensor->GetDataStatus();
- }
- /// ---------------------- MAGNETOEMTER -----------------------------------
- void Icm20948::ak09916_init(Config_Mag_t *config)
- {
- this->icm20948_i2c_master_reset();
- this->icm20948_i2c_master_enable();
- this->icm20948_i2c_master_clk_frq(7);
- while(!this->ak09916_who_am_i());
- this->ak09916_soft_reset();
- this->ak09916_operation_mode_setting(config->mode);
- if (config->mode == mag_mode_power_down) {
- this->_ak09916_enable = false;
- } else {
- this->_ak09916_enable = true;
- }
- }
- void Icm20948::ak09916_soft_reset()
- {
- _spi->write_single_external_reg(_activeDevice, MAG_CNTL3, 0x01);
- HAL_Delay(100);
- }
- bool Icm20948::ak09916_who_am_i()
- {
- uint8_t ak09916_id = _spi->read_single_external_reg(_activeDevice, MAG_WIA2);
- if(ak09916_id == AK09916_ID)
- return true;
- else
- return false;
- }
- void Icm20948::ak09916_operation_mode_setting(AK09916_operation_mode mode)
- {
- _spi->write_single_external_reg(_activeDevice, MAG_CNTL2, mode);
- HAL_Delay(100);
- }
- uint8_t Icm20948::GetIndexZeroBased(void)
- {
- return this->_activeDevice;
- }
- uint8_t Icm20948::GetIndex(void)
- {
- return this->_activeDevice + 1;
- }
- /* ----------------- SENSORS --------------------
- * 1) Sensor Accel
- * 2) Sensor Gyro
- * 3) Sensor Mag
- * ---------------------------------------------- */
- Sensor::Sensor(SpiManager *spi, int8_t activeDevice){
- _spi = spi;
- _activeDevice = activeDevice;
- _scaleFactor = 1.0f;
- offset_x = 0;
- offset_y = 0;
- offset_z = 0;
- }
- /**
- * @brief Interrupt status regiter - INT_STATUS_1
- * @return 1 – Sensor Register Raw Data, from all sensors, is updated and ready to be read.
- */
- uint8_t Sensor::GetDataStatus(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_0, B0_INT_STATUS_1);
- return new_val & 0x01;
- }
- bool Sensor::_read_without_scale_factor(axises* data)
- {
- return this->Read(data);
- }
- SensorGyro::SensorGyro(SpiManager *spi, int8_t activeDevice):Sensor(spi, activeDevice){
- }
- SensorAccel::SensorAccel(SpiManager *spi, int8_t activeDevice):Sensor(spi, activeDevice){
- }
- SensorMag::SensorMag(SpiManager *spi, int8_t activeDevice):Sensor(spi, activeDevice){
- }
- void Sensor::SetScaleFactor(float sf){
- _scaleFactor = sf;
- }
- uint8_t Sensor::GetLowPassFilter(void){
- return 0xFF;
- }
- uint8_t Sensor::GetSampleRate(void)
- {
- return 0xFF;
- }
- uint8_t Sensor::GetRange(void){
- return 0;
- }
- bool SensorGyro::Read(axises* data)
- {
- uint8_t* temp = this->_spi->read_multiple_reg(this->_activeDevice, ub_0, B0_GYRO_XOUT_H, 6);
- data->x = (int16_t)(temp[0] << 8 | temp[1]);
- data->y = (int16_t)(temp[2] << 8 | temp[3]);
- data->z = (int16_t)(temp[4] << 8 | temp[5]);
- return true;
- }
- bool SensorAccel::Read(axises* data)
- {
- uint8_t* temp = this->_spi->read_multiple_reg(this->_activeDevice, ub_0, B0_ACCEL_XOUT_H, 6);
- data->x = (int16_t)(temp[0] << 8 | temp[1]);
- data->y = (int16_t)(temp[2] << 8 | temp[3]);
- data->z = (int16_t)(temp[4] << 8 | temp[5]) + this->_scaleFactor;
- // Add scale factor because calibraiton function offset gravity acceleration.
- return true;
- }
- /**
- * Do not use this function to read final data. It is only for calibration of sensor.
- */
- bool SensorAccel::_read_without_scale_factor(axises* data)
- {
- uint8_t* temp = this->_spi->read_multiple_reg(this->_activeDevice, ub_0, B0_ACCEL_XOUT_H, 6);
- data->x = (int16_t)(temp[0] << 8 | temp[1]);
- data->y = (int16_t)(temp[2] << 8 | temp[3]);
- data->z = (int16_t)(temp[4] << 8 | temp[5]);
- // Add scale factor because calibraiton function offset gravity acceleration.
- return true;
- }
- bool SensorMag::Read(axises* data)
- {
- uint8_t* temp;
- uint8_t drdy; // data ready
- uint8_t hofl; // overflow
- drdy = this->_spi->read_single_external_reg(this->_activeDevice, MAG_ST1) & 0x01;
- if(!drdy) return false;
- temp = this->_spi->read_multiple_external_reg(this->_activeDevice, MAG_HXL, 6);
- hofl = this->_spi->read_single_external_reg(this->_activeDevice, MAG_ST2) & 0x08;
- if(hofl) return false;
- data->x = (int16_t)(temp[1] << 8 | temp[0]);
- data->y = (int16_t)(temp[3] << 8 | temp[2]);
- data->z = (int16_t)(temp[5] << 8 | temp[4]);
- return true;
- }
- bool SensorGyro::ReadUnit(axises* data)
- {
- this->Read(data);
- data->x /= this->_scaleFactor;
- data->y /= this->_scaleFactor;
- data->z /= this->_scaleFactor;
- return true;
- }
- bool SensorAccel::ReadUnit(axises* data)
- {
- this->Read(data);
- data->x /= this->_scaleFactor;
- data->y /= this->_scaleFactor;
- data->z /= this->_scaleFactor;
- return true;
- }
- bool SensorMag::ReadUnit(axises* data)
- {
- axises temp;
- bool new_data = this->Read(&temp);
- if(!new_data) return false;
- data->x = (float)(temp.x * 0.15);
- data->y = (float)(temp.y * 0.15);
- data->z = (float)(temp.z * 0.15);
- return true;
- }
- axises *SensorAccel::GetData()
- {
- return &this->data;
- }
- axises *SensorGyro::GetData()
- {
- return &this->data;
- }
- axises *SensorMag::GetData()
- {
- return &this->data;
- }
- void SensorAccel::SetRange(accel_full_scale full_scale)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG);
- new_val = new_val & 0xF9; // remova ACCEL_FS_SEL bites [1-2]
- float accel_scale_factor;
- switch(full_scale)
- {
- case _2g :
- new_val |= 0x00;
- accel_scale_factor = 16384;
- break;
- case _4g :
- new_val |= 0x02;
- accel_scale_factor = 8192;
- break;
- case _8g :
- new_val |= 0x04;
- accel_scale_factor = 4096;
- break;
- case _16g :
- new_val |= 0x06;
- accel_scale_factor = 2048;
- break;
- }
- this->SetScaleFactor(accel_scale_factor);
- _spi->write_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG, new_val);
- }
- void SensorGyro::SetRange(gyro_full_scale full_scale)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1);
- float gyro_scale_factor = 1;
- switch(full_scale)
- {
- case _250dps :
- new_val |= 0x00;
- gyro_scale_factor = 131.0;
- break;
- case _500dps :
- new_val |= 0x02;
- gyro_scale_factor = 65.5;
- break;
- case _1000dps :
- new_val |= 0x04;
- gyro_scale_factor = 32.8;
- break;
- case _2000dps :
- new_val |= 0x06;
- gyro_scale_factor = 16.4;
- break;
- }
- this->SetScaleFactor(gyro_scale_factor);
- _spi->write_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1, new_val);
- }
- uint8_t SensorGyro::GetLowPassFilter(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1);
- return (new_val>>3) & 0x07;
- }
- void SensorGyro::SetLowPassFilter(gyro_dlp_cfg config)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1);
- uint8_t gyro_fchoice = 1;
- uint8_t config_val = (uint8_t)config;
- if (config == GYRO_low_pass_OFF){
- gyro_fchoice = 0;
- config_val = 0;
- }
- new_val = (new_val & 0xC7) | (config_val<<3) | gyro_fchoice; // mask Gyro range settings
- _spi->write_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1, new_val);
- }
- uint8_t SensorAccel::CheckLowPassInputValue(uint8_t value)
- {
- uint8_t valid = 0;
- switch(value) {
- case ACCEL_lpf_246Hz:
- case ACCEL_lpf_114_4Hz:
- case ACCEL_lpf_050_4Hz:
- case ACCEL_lpf_023_9Hz:
- case ACCEL_lpf_011_5Hz:
- case ACCEL_lpf_005_7Hz:
- case ACCEL_lpf_473Hz:
- case ACCEL_lpf_OFF:
- valid = 1;
- break;
- default:
- valid = 0;
- };
- return valid;
- }
- uint8_t SensorGyro::CheckLowPassInputValue(uint8_t value)
- {
- uint8_t valid = 0;
- switch(value) {
- case GYRO_low_pass_OFF:
- case GYRO_lpf_005_7Hz:
- case GYRO_lpf_011_6Hz:
- case GYRO_lpf_023_9Hz:
- case GYRO_lpf_051_2Hz:
- case GYRO_lpf_119_5Hz:
- case GYRO_lpf_151_8Hz:
- case GYRO_lpf_196_6Hz:
- case GYRO_lpf_361_4Hz:
- valid = 1;
- break;
- default:
- valid = 0;
- };
- return valid;
- }
- /**
- * @brief Configure Low-pass filter:
- * @param config:
- */
- void SensorAccel::SetLowPassFilter(accel_dlp_cfg config)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG);
- uint8_t accel_fchoice = 1;
- if (config == ACCEL_lpf_OFF){
- accel_fchoice = 0;
- }
- new_val = (new_val & 0xC7) | (config<<3) | accel_fchoice; // mask Accel range settings
- _spi->write_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG, new_val);
- }
- uint8_t SensorAccel::GetLowPassFilter(void)
- {
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG);
- new_val = (new_val>>3) & 0x07;
- if(new_val == 0){ // cofig value 0 and 1 has same LPF frequency: 246Hz
- new_val = 1;
- }
- return new_val;
- }
- uint8_t SensorGyro::SetSampleRate(gyro_samplerate divider)
- {
- if(divider < 0 || divider >= 16){
- return 0;
- }
- uint8_t sr = GYRO_SampleRate_Table[divider];
- _spi->write_single_reg(_activeDevice, ub_2, B2_GYRO_SMPLRT_DIV, sr);
- return 1;
- }
- uint8_t SensorGyro::GetSampleRate(void)
- {
- uint8_t value = _spi->read_single_reg(_activeDevice, ub_2, B2_GYRO_SMPLRT_DIV);
- uint8_t sr_index = 0;
- for(uint8_t i=0 ; i < 16 ; i++){
- if(value == GYRO_SampleRate_Table[i]){
- sr_index = i;
- }
- }
- return sr_index;
- }
- uint8_t SensorAccel::SetSampleRate(accel_samplerate smplrt)
- {
- if(smplrt < 0 || smplrt >= 15){
- return 0;
- }
- uint16_t sr = ACCEL_SampleRate_Table[smplrt];
- uint8_t data[2] = {(uint8_t)((sr>> 8) & 0x0F), (uint8_t)(sr & 0xFF)}; // MSB, LSB
- _spi->write_multiple_reg(_activeDevice, ub_2, B2_ACCEL_SMPLRT_DIV_1, data, 2);
- return 1;
- }
- uint8_t SensorAccel::GetSampleRate(void)
- {
- uint8_t d1 = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_SMPLRT_DIV_1);
- uint8_t d2 = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_SMPLRT_DIV_2);
- uint16_t value = (d1<<8 | d2);
- uint8_t sr_index = 0;
- for(uint8_t i=0 ; i < 15 ; i++){
- if(value == ACCEL_SampleRate_Table[i]){
- sr_index = i;
- }
- }
- return sr_index;
- }
- uint8_t SensorAccel::GetRange(void){
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_ACCEL_CONFIG);
- return (new_val >> 1) & 0x03;
- }
- uint8_t SensorGyro::GetRange(void){
- uint8_t new_val = _spi->read_single_reg(_activeDevice, ub_2, B2_GYRO_CONFIG_1);
- return (new_val >> 1) & 0x03;
- }
- void SensorGyro::Calibrate(void)
- {
- axises temp;
- int32_t gyro_bias[3] = {0};
- for(int i = 0; i < 100; i++)
- {
- while(this->GetDataStatus() == 0);
- this->Read(&temp);
- gyro_bias[0] += temp.x;
- gyro_bias[1] += temp.y;
- gyro_bias[2] += temp.z;
- }
- gyro_bias[0] /= 100;
- gyro_bias[1] /= 100;
- gyro_bias[2] /= 100;
- this->offset_x = gyro_bias[0];
- this->offset_y = gyro_bias[1];
- this->offset_z = gyro_bias[2];
- this->SaveOffset();
- }
- void SensorGyro::SaveOffset(void)
- {
- if((this->offset_x+this->offset_y+this->offset_z)==0)
- {
- return;
- }
- uint8_t gyro_offset[6] = {0};
- // Construct the gyro biases for push to the hardware gyro bias registers,
- // which are reset to zero upon device startup.
- // Divide by 4 to get 32.9 LSB per deg/s to conform to expected bias input format.
- // Biases are additive, so change sign on calculated average gyro biases
- gyro_offset[0] = (-this->offset_x / 4 >> 8) & 0xFF;
- gyro_offset[1] = (-this->offset_x / 4) & 0xFF;
- gyro_offset[2] = (-this->offset_y / 4 >> 8) & 0xFF;
- gyro_offset[3] = (-this->offset_y / 4) & 0xFF;
- gyro_offset[4] = (-this->offset_z / 4 >> 8) & 0xFF;
- gyro_offset[5] = (-this->offset_z / 4) & 0xFF;
- _spi->write_multiple_reg(_activeDevice, ub_2, B2_XG_OFFS_USRH, gyro_offset, 6);
- }
- void SensorAccel::Calibrate()
- {
- axises temp;
- uint8_t* temp2;
- uint8_t* temp3;
- uint8_t* temp4;
- int32_t accel_bias[3] = {0};
- int32_t accel_bias_reg[3] = {0};
- for(int q = 0; q < 3; q++)
- {
- for(int i = 0; i < 100; i++)
- {
- while(this->GetDataStatus() == 0);
- this->_read_without_scale_factor(&temp);
- accel_bias[0] += temp.x;
- accel_bias[1] += temp.y;
- accel_bias[2] += temp.z;
- }
- HAL_Delay(25);
- }
- accel_bias[0] /= 300;
- accel_bias[1] /= 300;
- accel_bias[2] /= 300;
- temp2 = _spi->read_multiple_reg(_activeDevice, ub_1, B1_XA_OFFS_H, 2);
- accel_bias_reg[0] = (int32_t)(temp2[0] << 8 | temp2[1]);
- temp3 = _spi->read_multiple_reg(_activeDevice, ub_1, B1_YA_OFFS_H, 2);
- accel_bias_reg[1] = (int32_t)(temp3[0] << 8 | temp3[1]);
- temp4 = _spi->read_multiple_reg(_activeDevice, ub_1, B1_ZA_OFFS_H, 2);
- accel_bias_reg[2] = (int32_t)(temp4[0] << 8 | temp4[1]);
- accel_bias_reg[0] -= (accel_bias[0]/8 );
- accel_bias_reg[1] -= (accel_bias[1]/8 );
- accel_bias_reg[2] -= (accel_bias[2]/8 ); // (accel_bias[2]/8)
- this->offset_x = accel_bias_reg[0];
- this->offset_y = accel_bias_reg[1];
- this->offset_z = accel_bias_reg[2];
- this->SaveOffset();
- }
- void SensorAccel::SaveOffset(void)
- {
- if((this->offset_x+this->offset_y+this->offset_z)==0)
- {
- return;
- }
- uint8_t accel_offset[6] = {0};
- accel_offset[0] = (this->offset_x >> 8) & 0xFF;
- accel_offset[1] = (this->offset_x) & 0xFE;
- accel_offset[2] = (this->offset_y >> 8) & 0xFF;
- accel_offset[3] = (this->offset_y) & 0xFE;
- accel_offset[4] = (this->offset_z >> 8) & 0xFF;
- accel_offset[5] = (this->offset_z) & 0xFE;
- _spi->write_multiple_reg(_activeDevice, ub_1, B1_XA_OFFS_H, &accel_offset[0], 2);
- _spi->write_multiple_reg(_activeDevice, ub_1, B1_YA_OFFS_H, &accel_offset[2], 2);
- _spi->write_multiple_reg(_activeDevice, ub_1, B1_ZA_OFFS_H, &accel_offset[4], 2);
- }
|