接前一篇文章:ICM20948 DMP代码详解(21)
上一回讲到了inv_icm20948_wakeup_mems函数,没有讲完,本回把余下的内容讲完。为了便于理解和回顾,再次贴出inv_icm20948_wakeup_mems函数代码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,如下:
/** Wakes up DMP3 (SMARTSENSOR).
*/
int inv_icm20948_wakeup_mems(struct inv_icm20948 *s)
{
unsigned char data;
int result = 0;
result = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);
if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {
s->base_state.user_ctrl |= BIT_I2C_IF_DIS;
inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);
}
data = 0x47; // FIXME, should set up according to sensor/engines enabled.
result |= inv_icm20948_write_mems_reg(s, REG_PWR_MGMT_2, 1, &data);
if(s->base_state.firmware_loaded == 1) {
s->base_state.user_ctrl |= BIT_DMP_EN | BIT_FIFO_EN;
result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);
}
result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);
return result;
}
余下的第1段代码片段如下:
data = 0x47; // FIXME, should set up according to sensor/engines enabled.
result |= inv_icm20948_write_mems_reg(s, REG_PWR_MGMT_2, 1, &data);
直接说功能。这段代码的意思是将PWR_MGMT_2寄存器的内容写为0x47。REG_PWR_MGMT_2宏在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Defs.h中定义,如下:
#define REG_PWR_MGMT_2 (BANK_0 | 0x07)
对应ICM20948芯片手册的内容如下:
综合来看,这段代码的意思就是禁止陀螺仪所有轴,但不禁止加速度计的所有轴。但是为什么是0x47就不得而知了,根据手册说明,正常应该是0x07才是。以目前笔者认知,最高两位bit7~6应该是与压力传感器相关。见REG_PWR_MGMT_2宏相关部分的完整代码:
#define REG_PWR_MGMT_2 (BANK_0 | 0x07)
#define BIT_PWR_PRESSURE_STBY 0x40
#define BIT_PWR_ACCEL_STBY 0x38
#define BIT_PWR_GYRO_STBY 0x07
#define BIT_PWR_ALL_OFF 0x7f
接下来是最后一段代码片段:
if(s->base_state.firmware_loaded == 1) {
s->base_state.user_ctrl |= BIT_DMP_EN | BIT_FIFO_EN;
result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);
}
这一段就是直接设置USER寄存器中的DMP_EN和FIFO_EN位为1,即使能DMP和FIFO。USER_CTRL在前文书讲解inv_icm20948_read_mems_reg函数的时候,已经做了解析,这里再看一下。
#define REG_USER_CTRL (BANK_0 | 0x03)
#define BIT_DMP_EN 0x80
#define BIT_FIFO_EN 0x40
#define BIT_I2C_MST_EN 0x20
#define BIT_I2C_IF_DIS 0x10
#define BIT_DMP_RST 0x08
#define BIT_DIAMOND_DMP_RST 0x04
但是注意,走到以上代码是有条件的,即要求s->base_state.firmware_loaded为1时,才会进入。而此时还是0,因为之前在inv_icm20948_initialize_lower_driver函数的一开始,整个s->base_state清零了。
至此, inv_icm20948_wakeup_mems函数就全部解析完了。再来总体看一下该函数功能:
唤醒芯片;如果使用的是SPI接口,则禁止I2C接口;禁止陀螺仪(所有轴)、但不禁止加速度计;使能DMP功能、使能FIFO操作模式;设置芯片低功耗使能。
回到inv_icm20948_initialize_lower_driver函数中,下一回继续往下解析。