您的位置:首页 > 房产 > 建筑 > ICM20948 DMP代码详解(20)

ICM20948 DMP代码详解(20)

2025/3/10 14:31:47 来源:https://blog.csdn.net/phmatthaus/article/details/142139119  浏览:    关键词:ICM20948 DMP代码详解(20)

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

本回继续对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 asleepresult = 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 disabledresult |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_ENresult |= 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_ENreturn result;
}

接下来进入while循环,开始数据的接收。代码片段如下:

	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;}

先讲一下regOnly,它在inv_icm20948_read_mems_reg函数的开头处赋值:

	unsigned char regOnly = (unsigned char)(reg & 0x7F);

代码中是将寄存器和其所属的bank联合起来进行表示的,bit0~6是寄存器,bit7~8代表其所属的bank。这个regOnly表示的就是不带bank、只带寄存器的值。也就是取下图中红色框中的部分:

回到上边while循环。一开始bytesRead的值为0,length的值为1,因此会进入循环。

thisLen为INV_MAX_SERIAL_READ与length-bytesRead(1-0=1)的较小值。INV_MAX_SERIAL_READ宏在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.h中定义,如下:

/** @brief Max size that can be read across I2C or SPI data lines */
#define INV_MAX_SERIAL_READ 16
/** @brief Max size that can be written across I2C or SPI data lines */
#define INV_MAX_SERIAL_WRITE 16

那么thisLen的值这里就是1。

接下来走I2C的分支:

        else{result |= inv_icm20948_read_reg(s, regOnly+bytesRead, &data[bytesRead], thisLen);}

inv_ivm20948_read_reg函数前边已经讲过多次,在此不赘述。直接看一下传给它的实参:

regOnly+bytesRead就是regOnly;&data[bytesRead]第一次进入循环的时候是&data[0];thisLen的值是1。这句代码的实际意义就是读取USER_CTRL寄存器,读取1个字节,保存到&data[0]。也就是获取USER_CTRL寄存器的内容。

由于只读取1个字节的内容,因此读一次之后就跳出while循环了。

接下来来到以下代码片段:

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

对于SPI接口来说,还要从dat[]到data[]“倒”一下。笔者不太理解为何要这样做,不过当前是用I2C接口,也不用“深抠”这一块了。

接下来就到最后一段了:

	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

check_reg_access_lp_disable函数上一回讲过,对于USER_CTRL寄存器,总是返回1,会执行inv_icm20948_set_chip_power_state函数。这一句代码的意思是恢复置位LP_EN,也即恢复低功耗使能状态。

至此,inv_icm20948_read_mems_reg函数就都解析完了。其功能概括如下:

唤醒芯片;退出低功耗模式;设置(选择)bank;读取指定寄存器数据;恢复低功耗模式。

下一回将回到inv_icm20948_initialize_lower_driver函数中,继续往下解析接下来的内容。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com