接前一篇文章: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 I2C
if (whoami == 0xff) { // if whoami fails try the other I2C Address
switch_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 Compass
result = inv_icm20948_setup_compass_akm(s);
//Setup Compass mounting matrix into DMP
result |= 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函数较为复杂,其中调用了很多子函数。下一回开始,对于该函数进行解析。