ICM20948 DMP代码详解(37)
接前一篇文章:ICM20948 DMP代码详解(36)
上一回开始分析icm20948_sensor_setup() ---> inv_icm20948_initialize_auxiliary函数 ---> 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_init_secondary(s);// Set up the secondary I2C bus on 20630.inv_icm20948_set_secondary(s);
3)inv_icm20948_init_secondary函数
inv_icm20948_init_secondary函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948AuxTransport.c中,代码如下:
void inv_icm20948_init_secondary(struct inv_icm20948 *s)
{s->secondary_state.slv_reg[0].addr = REG_I2C_SLV0_ADDR;s->secondary_state.slv_reg[0].reg = REG_I2C_SLV0_REG;s->secondary_state.slv_reg[0].ctrl = REG_I2C_SLV0_CTRL;s->secondary_state.slv_reg[0].d0 = REG_I2C_SLV0_DO;s->secondary_state.slv_reg[1].addr = REG_I2C_SLV1_ADDR;s->secondary_state.slv_reg[1].reg = REG_I2C_SLV1_REG;s->secondary_state.slv_reg[1].ctrl = REG_I2C_SLV1_CTRL;s->secondary_state.slv_reg[1].d0 = REG_I2C_SLV1_DO;s->secondary_state.slv_reg[2].addr = REG_I2C_SLV2_ADDR;s->secondary_state.slv_reg[2].reg = REG_I2C_SLV2_REG;s->secondary_state.slv_reg[2].ctrl = REG_I2C_SLV2_CTRL;s->secondary_state.slv_reg[2].d0 = REG_I2C_SLV2_DO;s->secondary_state.slv_reg[3].addr = REG_I2C_SLV3_ADDR;s->secondary_state.slv_reg[3].reg = REG_I2C_SLV3_REG;s->secondary_state.slv_reg[3].ctrl = REG_I2C_SLV3_CTRL;s->secondary_state.slv_reg[3].d0 = REG_I2C_SLV3_DO;/* Make sure that by default all channels are disabled To not inherit from a previous configuration from a previous run*/inv_icm20948_secondary_stop_channel(s, 0);inv_icm20948_secondary_stop_channel(s, 1);inv_icm20948_secondary_stop_channel(s, 2);inv_icm20948_secondary_stop_channel(s, 3);
}
REG_I2C_SLV0_ADDR等相关的宏在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Defs.h中,定义如下:
#define REG_I2C_SLV0_ADDR (BANK_3 | 0x03)
#define REG_I2C_SLV0_REG (BANK_3 | 0x04)
#define REG_I2C_SLV0_CTRL (BANK_3 | 0x05)
#define REG_I2C_SLV0_DO (BANK_3 | 0x06)#define REG_I2C_SLV1_ADDR (BANK_3 | 0x07)
#define REG_I2C_SLV1_REG (BANK_3 | 0x08)
#define REG_I2C_SLV1_CTRL (BANK_3 | 0x09)
#define REG_I2C_SLV1_DO (BANK_3 | 0x0A)#define REG_I2C_SLV2_ADDR (BANK_3 | 0x0B)
#define REG_I2C_SLV2_REG (BANK_3 | 0x0C)
#define REG_I2C_SLV2_CTRL (BANK_3 | 0x0D)
#define REG_I2C_SLV2_DO (BANK_3 | 0x0E)#define REG_I2C_SLV3_ADDR (BANK_3 | 0x0F)
#define REG_I2C_SLV3_REG (BANK_3 | 0x10)
#define REG_I2C_SLV3_CTRL (BANK_3 | 0x11)
#define REG_I2C_SLV3_DO (BANK_3 | 0x12)#define REG_I2C_SLV4_CTRL (BANK_3 | 0x15)
对应ICM20948芯片手册中的以下内容:
这里I2C_SLV0~I2C_SLV3的各个寄存器都是一个意思,因此只以I2C_SLV0_XXX寄存器为例进行解析。
inv_icm20948_secondary_stop_channel函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948AuxTransport.c中,代码如下:
int inv_icm20948_secondary_stop_channel(struct inv_icm20948 *s, int index)
{return inv_icm20948_write_single_mems_reg(s, s->secondary_state.slv_reg[index].ctrl, 0);
}
s->secondary_state.slv_reg[index].ctrl对应的就是上边REG_I2C_SLVx_CTRL,把CTRL寄存器中的所有位都清零,也就是I2C_SLVx_EN、I2C_SLVx_BYTE_SW、I2C_SLVx_REG_SW、I2C_SLVx_GRP、I2C_SLVx_LENG[3:0]。
综合来看,inv_icm20948_init_secondary函数的功能正如其注释中所说:确保默认情况下禁用所有(I2C SLAVE)通道,不从上次运行的先前配置继承。
……
至此,inv_icm20948_init_secondary函数就解析完了。下一回继续后续内容的解析。