ICM20948 DMP代码详解(10)

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

 

上一回解析完了icm20948_sensor_setup函数第1段代码中的inv_icm20948_get_whoami函数,也把源码工程中I2C读取寄存器的流程梳理了一下。本回回到第1段代码中,把剩余的部分解析完。再次贴出源码:

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

接下来调用interface_is_SPI()判断使用的是I2C方式还是SPI方式。interface_is_SPI函数前文书(https://phmatthaus.blog.youkuaiyun.com/article/details/141950357)也讲过:

9112aca037a5464a8d24286ef5023c4e.png

如果使用的是SPI方式,则返回true;否则返回false。这里假设使用的是I2C方式,那么会进入判断体中。

	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_icm20948_get_whoami函数得到的whoami的值为0xff,则说明没有读到内容,则 调用switch_I2C_to_revA(),之后再次调用inv_icm20948_get_whoami函数尝试读取。

switch_I2C_to_revA函数也在EMD-App\src\ICM20948\system.c中,代码如下:

void switch_I2C_to_revA(void){
#if SERIF_TYPE_I2C
	I2C_Address = ICM_I2C_ADDR_REVA;
#endif	
}

ICM_I2C_ADDR_REVA宏在EMD-App\src\ICM20948\system.h中,定义如下:

#define ICM_I2C_ADDR_REVA			0x68 	/* I2C slave address for INV device on Rev A board */
#define ICM_I2C_ADDR_REVB			0x69 	/* I2C slave address for INV device on Rev B board */

I2C_Address是一个全局变量,在同文件(EMD-App\src\ICM20948\system.c)中,定义如下:

#if SERIF_TYPE_I2C
/*
* Variable for storing I2C Address
*/
uint8_t I2C_Address = ICM_I2C_ADDR_REVB;
#endif

默认用的是Rev B板子,其中ICM20948的I2C地址为0x69。如果读不到,则可能是Rev A板子,I2C地址为0x68,再次尝试读取WHO_AM_I寄存器的内容。这里的0x68和0x69在ICM20948的芯片手册中有说明,如下:

88a37cb7c206442f8619997ecfa50d28.png

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

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

EXPECTED_WHOAMI在EMD-App\src\ICM20948\sensor.c中,代码如下:

static const uint8_t EXPECTED_WHOAMI[] = { 0xEA }; /* WHOAMI value for ICM20948 or derivative */

sizeof(EXPECTED_WHOAMI)/sizeof(EXPECTED_WHOAMI[0])的值为1,因此for循环也只执行1次。循环体中判断读取到的WHO_AM_I寄存器值,如果为0xEA则跳出,注意此时i的值为0;否则循环体结束后退出,注意此时i的值为1。

这个0xEA也是在ICM20948手册中的,如下所示:

ee5605d1576a425480ee3678a16eabf3.png

接下来判断i的值,如果为1,则说明是走过了完整for循环,也就代表了没有读到0xEA这个值,则需要给出提示,并返回rc值(应该是错误值)。

至此,icm20948_sensor_setup函数第1段代码就解析完了。这一步骤符合一般流程,即先读取WHO_AM_I寄存器(id),看看能否通过I2C与ICM20948正常通信。

icm20948_sensor_setup函数其余代码的解析请看下回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蓝天居士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值