接前一篇文章:ICM20948 DMP代码详解(34)
上一回终于解析完了inv_icm20948_initialize_lower_driver函数,本回回到icm20948_sensor_setup函数,继续往下进行解析。为了便于理解和回顾,再次贴出icm20948_sensor_setup函数代码,在EMD-App\src\ICM20948\sensor.c中,如下:
int icm20948_sensor_setup(void)
{int rc;uint8_t i, whoami = 0xff;/** Just get the whoami*/rc = inv_icm20948_get_whoami(&icm_device, &whoami);if (interface_is_SPI() == 0) { // If we're using I2Cif (whoami == 0xff) { // if whoami fails try the other I2C Addressswitch_I2C_to_revA();rc = inv_icm20948_get_whoami(&icm_device, &whoami);}}INV_MSG(INV_MSG_LEVEL_INFO, "ICM20948 WHOAMI value=0x%02x", whoami);/** Check if WHOAMI value corresponds to any value from EXPECTED_WHOAMI array*/for(i = 0; i < sizeof(EXPECTED_WHOAMI)/sizeof(EXPECTED_WHOAMI[0]); ++i) {if(whoami == EXPECTED_WHOAMI[i]) {break;}}if(i == sizeof(EXPECTED_WHOAMI)/sizeof(EXPECTED_WHOAMI[0])) {INV_MSG(INV_MSG_LEVEL_ERROR, "Bad WHOAMI value. Got 0x%02x.", whoami);return rc;}/* Setup accel and gyro mounting matrix and associated angle for current board */inv_icm20948_init_matrix(&icm_device);/* set default power mode */INV_MSG(INV_MSG_LEVEL_VERBOSE, "Putting Icm20948 in sleep mode...");rc = inv_icm20948_initialize(&icm_device, dmp3_image, sizeof(dmp3_image));if (rc != 0) {INV_MSG(INV_MSG_LEVEL_ERROR, "Initialization failed. Error loading DMP3...");return rc;}/** Configure and initialize the ICM20948 for normal use*/INV_MSG(INV_MSG_LEVEL_INFO, "Booting up icm20948...");/* Initialize auxiliary sensors */inv_icm20948_register_aux_compass( &icm_device, INV_ICM20948_COMPASS_ID_AK09916, AK0991x_DEFAULT_I2C_ADDR);rc = inv_icm20948_initialize_auxiliary(&icm_device);if (rc == -1) {INV_MSG(INV_MSG_LEVEL_ERROR, "Compass not detected...");}icm20948_apply_mounting_matrix();icm20948_set_fsr();/* re-initialize base state structure */inv_icm20948_init_structure(&icm_device);/* we should be good to go ! */INV_MSG(INV_MSG_LEVEL_VERBOSE, "We're good to go !");return 0;
}
之前走到了这了里(从ICM20948 DMP代码详解(14)_struct for the fifo. this contains the sensor data-CSDN博客开始):
/* set default power mode */INV_MSG(INV_MSG_LEVEL_VERBOSE, "Putting Icm20948 in sleep mode...");rc = inv_icm20948_initialize(&icm_device, dmp3_image, sizeof(dmp3_image));if (rc != 0) {INV_MSG(INV_MSG_LEVEL_ERROR, "Initialization failed. Error loading DMP3...");return rc;}
由此展开了长达20篇文章的解析。现在终于回来了,继续往下走。接下来的代码片段是:
/** Configure and initialize the ICM20948 for normal use*/INV_MSG(INV_MSG_LEVEL_INFO, "Booting up icm20948...");/* Initialize auxiliary sensors */inv_icm20948_register_aux_compass(&icm_device, INV_ICM20948_COMPASS_ID_AK09916, AK0991x_DEFAULT_I2C_ADDR);rc = inv_icm20948_initialize_auxiliary(&icm_device);if (rc == -1) {INV_MSG(INV_MSG_LEVEL_ERROR, "Compass not detected...");}
inv_icm20948_register_aux_compass函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948AuxCompassAkm.c中,代码如下:
void inv_icm20948_register_aux_compass(struct inv_icm20948 *s,enum inv_icm20948_compass_id compass_id, uint8_t compass_i2c_addr)
{switch(compass_id) {case INV_ICM20948_COMPASS_ID_AK09911:s->secondary_state.compass_slave_id = HW_AK09911;s->secondary_state.compass_chip_addr = compass_i2c_addr;s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;/* initialise mounting matrix of compass to identity akm9911 */s->mounting_matrix_secondary_compass[0] = -1 ;s->mounting_matrix_secondary_compass[4] = -1;s->mounting_matrix_secondary_compass[8] = 1;break;case INV_ICM20948_COMPASS_ID_AK09912:s->secondary_state.compass_slave_id = HW_AK09912;s->secondary_state.compass_chip_addr = compass_i2c_addr;s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;/* initialise mounting matrix of compass to identity akm9912 */s->mounting_matrix_secondary_compass[0] = 1 ;s->mounting_matrix_secondary_compass[4] = 1;s->mounting_matrix_secondary_compass[8] = 1;break;case INV_ICM20948_COMPASS_ID_AK08963:s->secondary_state.compass_slave_id = HW_AK8963;s->secondary_state.compass_chip_addr = compass_i2c_addr;s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;/* initialise mounting matrix of compass to identity akm8963 */s->mounting_matrix_secondary_compass[0] = 1;s->mounting_matrix_secondary_compass[4] = 1;s->mounting_matrix_secondary_compass[8] = 1;break;case INV_ICM20948_COMPASS_ID_AK09916:s->secondary_state.compass_slave_id = HW_AK09916;s->secondary_state.compass_chip_addr = compass_i2c_addr;s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;/* initialise mounting matrix of compass to identity akm9916 */s->mounting_matrix_secondary_compass[0] = 1 ;s->mounting_matrix_secondary_compass[4] = -1;s->mounting_matrix_secondary_compass[8] = -1;break;default:s->secondary_state.compass_slave_id = 0;s->secondary_state.compass_chip_addr = 0;s->secondary_state.compass_state = INV_ICM20948_COMPASS_RESET;}
}
实际上这一句代码早在icm20948_sensor_setup函数前就已经调用过了,也对此函数进行了解析,参见ICM20948 DMP代码详解(8)-CSDN博客:
在此不赘述了。
接下来调用了:
rc = inv_icm20948_initialize_auxiliary(&icm_device);if (rc == -1) {INV_MSG(INV_MSG_LEVEL_ERROR, "Compass not detected...");}
inv_icm20948_initialize_auxiliary函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Setup.c中,代码如下:
int inv_icm20948_initialize_auxiliary(struct inv_icm20948 *s)
{if (inv_icm20948_set_slave_compass_id(s, s->secondary_state.compass_slave_id))return -1;return 0;
}
inv_icm20948_set_slave_compass_id函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,代码如下:
int inv_icm20948_set_slave_compass_id(struct inv_icm20948 * s, int id)
{int result = 0;(void)id;//result = inv_icm20948_wakeup_mems(s);//if (result)// return result;inv_icm20948_prevent_lpen_control(s);activate_compass(s);inv_icm20948_init_secondary(s);// Set up the secondary I2C bus on 20630.inv_icm20948_set_secondary(s);//Setup Compassresult = inv_icm20948_setup_compass_akm(s);//Setup Compass mounting matrix into DMPresult |= inv_icm20948_compass_dmp_cal(s, s->mounting_matrix, s->mounting_matrix_secondary_compass);if (result)desactivate_compass(s);//result = inv_icm20948_sleep_mems(s);inv_icm20948_allow_lpen_control(s);return result;
}
可以看到inv_icm20948_set_slave_compass_id函数较为复杂,其中调用了很多子函数。下一回开始,对于该函数进行解析。