ICM20948 DMP代码详解(19)

接前一篇文章:ICM20948 DMP代码详解(18)

上一回完成了对inv_icm20948_set_chip_power_state函数的完全解析。本回回到调用它的inv_icm20948_read_mems_reg函数中,继续往下解析。为了便于理解和回顾,再次贴出inv_icm20948_read_mems_reg函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,如下:

/**
*  @brief      Read data from a register on MEMs.
*  @param[in]  Register address
*  @param[in]  Length of data
*  @param[in]  Data to be written
*  @return     0 if successful.
*/
int inv_icm20948_read_mems_reg(struct inv_icm20948 * s, uint16_t reg, unsigned int length, unsigned char *data)
{
	int result = 0;
	unsigned int bytesRead = 0;
	unsigned char regOnly = (unsigned char)(reg & 0x7F);
	unsigned char i, dat[INV_MAX_SERIAL_READ];
	unsigned char power_state = inv_icm20948_get_chip_power_state(s);

	if((power_state & CHIP_AWAKE) == 0)   // Wake up chip since it is asleep
		result = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);

	if(check_reg_access_lp_disable(s, reg))   // Check if register needs LP_EN to be disabled
		result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_EN

	result |= inv_set_bank(s, reg >> 7);

	while (bytesRead<length) 
	{
		int thisLen = min(INV_MAX_SERIAL_READ, length-bytesRead);
		if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {
			result |= inv_icm20948_read_reg(s, regOnly+bytesRead, &dat[bytesRead], thisLen);
		} else {
			result |= inv_icm20948_read_reg(s, regOnly+bytesRead, &data[bytesRead],thisLen);
		}

		if (result)
			return result;

		bytesRead += thisLen;
	}

	if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {
		for (i=0; i< length; i++) {
			*data= dat[i];
			data++;
		}
	}

	if(check_reg_access_lp_disable(s, reg))    // Check if register needs LP_EN to be enabled  
		result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);  //Enable LP_EN

	return result;
}

check_reg_access_lp_disable函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,代码如下:

static uint8_t check_reg_access_lp_disable(struct inv_icm20948 *s, unsigned short reg)
{
	switch(reg){
	case REG_LP_CONFIG:      /** (BANK_0 | 0x05) */
	case REG_PWR_MGMT_1:     /** (BANK_0 | 0x06) */
	case REG_PWR_MGMT_2:     /** (BANK_0 | 0x07) */
	case REG_INT_PIN_CFG:    /** (BANK_0 | 0x0F) */
	case REG_INT_ENABLE:     /** (BANK_0 | 0x10) */
	case REG_FIFO_COUNT_H:   /** (BANK_0 | 0x70) */
	case REG_FIFO_COUNT_L:   /** (BANK_0 | 0x71) */
	case REG_FIFO_R_W:       /** (BANK_0 | 0x72) */
		return inv_icm20948_ctrl_get_batch_mode_status(s);
	case REG_FIFO_CFG:       /** (BANK_0 | 0x76) */
	case REG_MEM_BANK_SEL:   /** (BANK_0 | 0x7E) */
	case REG_BANK_SEL:       /** 0x7F */
	case REG_INT_STATUS:     /** (BANK_0 | 0x19) */
	case REG_DMP_INT_STATUS: /** (BANK_0 | 0x18) */
		return 0;
		break;
	default:
		break;
	}
	return 1;
}

此处在inv_icm20948_read_mems_reg函数中传给check_reg_access_lp_disable函数的实参是reg,而这个reg又是inv_icm20948_initialize_lower_driver函数传给inv_icm20948_read_mems_reg函数的,实际的寄存器是REG_USER_CTRL。

REG_USER_CTRL宏在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Defs.h中定义,如下:

#define REG_USER_CTRL           (BANK_0 | 0x03)

对应于ICM20948芯片手册中的USER_CTRL寄存器,如下所示:

由于REG_USER_CTRL不属于switch中的case,或者说属于default,因此函数check_reg_access_lp_disable直接返回1。

这样,inv_icm20948_read_mems_reg函数的以下代码片段的完整功能就明晰了。

	unsigned char power_state = inv_icm20948_get_chip_power_state(s);

	if((power_state & CHIP_AWAKE) == 0)   // Wake up chip since it is asleep
		result = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);

	if(check_reg_access_lp_disable(s, reg))   // Check if register needs LP_EN to be disabled
		result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_EN

1)首先通过inv_icm20948_get_chip_power_state函数得到power_state即s->base_state.wake_state;

2)如果power_state中的CHIP_AWAKE没有置位、即ICM20948芯片处于休眠状态,则调用inv_icm20948_set_chip_power_state函数将其唤醒;

3)之后检查USER_CTRL寄存器是否需要将LP_EN禁止;

4)如果需要,则再次通过inv_icm20948_set_chip_power_state函数禁止低功耗模式(注意是暂时性的,下边还会恢复低功耗模式)。

回到inv_icm20948_read_mems_reg函数中。接下来调用inv_set_bank函数设置bank。inv_set_bank函数前文书中已经解析过(参见https://phmatthaus.blog.csdn.net/article/details/142096690),在此不再赘述。

接下来就要开始实际的数据读取了,对于这部分的解析,放在下一回中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值