当前位置: 首页 > news >正文

ICM20948 DMP代码详解(46)

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

 

上一回讲到了inv_icm20948_setup_compass_akm函数中的以下代码片段:

	/* Set compass in power down through I2C SLV for compass */result = inv_icm20948_execute_write_secondary(s, COMPASS_I2C_SLV_WRITE, s->secondary_state.compass_chip_addr, s->secondary_state.mode_reg_addr, DATA_AKM_MODE_PD);if (result)return result;

本会就对于inv_icm20948_execute_write_secondary函数以及其中调用的inv_icm20948_write_secondary函数代码进行解析。

再次贴出inv_icm20948_execute_write_secondary函数代码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948AuxTransport.c中,如下:

int inv_icm20948_execute_write_secondary(struct inv_icm20948 *s, int index, unsigned char addr, int reg, uint8_t v)
{int result = 0;result |= inv_icm20948_write_secondary(s, index, addr, reg, v);result |= inv_icm20948_secondary_enable_i2c(s);inv_icm20948_sleep_us(SECONDARY_INIT_WAIT*1000);result |= inv_icm20948_secondary_disable_i2c(s);result |= inv_icm20948_secondary_stop_channel(s, index);return result;
}

inv_icm20948_write_secondary函数在同文件中,就在inv_icm20948_execute_write_secondary函数的上边,代码如下:

/*
* inv_icm20948_write_secondary(): set secondary registers for writing?.
The chip must be set as bank 3 before calling.
* This is derived from inv_icm20948_write_secondary in linux...
* for now, uses a very simple data struct for the registers
* 
* index gives the mapping to the particular SLVx registers
* addr is the physical address of the device to be accessed
* reg is the device register we wish to access
* len is the number of bytes to be read
* 
*/
int inv_icm20948_write_secondary(struct inv_icm20948 *s, int index, unsigned char addr, unsigned char reg, char v)
{int result = 0;unsigned char data;data = (unsigned char)addr;result |= inv_icm20948_write_mems_reg(s, s->secondary_state.slv_reg[index].addr, 1, &data);data = reg;result |= inv_icm20948_write_mems_reg(s, s->secondary_state.slv_reg[index].reg, 1, &data);data = v;result |= inv_icm20948_write_mems_reg(s, s->secondary_state.slv_reg[index].d0, 1, &data);data = INV_MPU_BIT_SLV_EN | 1;result |= inv_icm20948_write_mems_reg(s, s->secondary_state.slv_reg[index].ctrl, 1, &data);return result;
}

可以对比着前文书对于inv_icm20948_read_secondary函数的解析过程来看。

4894ecce0d6048c3abe69e6d59c5afcd.png

7baf817243a14d6dbf220b6faaa08b1e.png

第1段代码如下:

    data = (unsigned char)addr;result |= inv_icm20948_write_mems_reg(s, s->secondary_state.slv_reg[index].addr, 1, &data);

data是addr,即AK09916芯片的地址0x0C。注意,此处由于是写,因此并没有INV_MPU_BIT_I2C_READ | addr。

第2行代码中的s->secondary_state.slv_reg[index].addr是在前文书解析的inv_icm20948_init_secondary函数中初始化的(参见https://phmatthaus.blog.csdn.net/article/details/142306413)。

d7de791f173f4566b6fd1f154ab78020.png

注意,此处的index和inv_icm20948_read_secondary函数不同了,对应的实参是在inv_icm20948_setup_compass_akm函数中传入的,为COMPASS_I2C_SLV_WRITE,就是上一回所说的写通道。

/** @brief I2C from secondary device can stand on up to 4 channels. To perform automatic read and feed DMP :
- channel 0 is reserved for compass reading data
- channel 1 is reserved for compass writing one-shot acquisition register
- channel 2 is reserved for als reading data */
#define COMPASS_I2C_SLV_READ		0
#define COMPASS_I2C_SLV_WRITE		1
#define ALS_I2C_SLV					2

也就是此处的index为1,表示通道1,其用于设置指南针(磁力计芯片)的寄存器。

这样,s->secondary_state.slv_reg[index].addr就是s->secondary_state.slv_reg[1].addr,在inv_icm20948_init_secondary函数中赋的值是REG_I2C_SLV1_ADDR。REG_I2C_SLV1_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)

也就是BANK_3 | 0x07 = (3 << 7) | 0x07。

对应于ICM20948芯片手册中的以下内容:

7eb7402b757549a6b3cee5da7b8aa8eb.png

286ae7f479904fd3bf2a566476b1e585.png

综上,inv_icm20948_read_secondary函数第1段代码的意思是:向I2C _SLV1_ADDR寄存器写入1个字节数据,该字节内容为0x0C,由于I2C_SLV1_RN位(bit 7)为低,因此代表准备写入数据。实际上就是选通AK09916磁力计芯片,准备写入数据。

inv_icm20948_write_secondary函数余下代码的解析,请看下回。

 


http://www.mrgr.cn/news/37263.html

相关文章:

  • 个人文章汇总(MyBatis)
  • 解决 Adobe 盗版弹窗
  • Linux在桌面和服务器领域的最新技术趋势,包括3D桌面、虚拟技术、安全性提升等维度。
  • 11 函数的定义和使用
  • FastAPI 第五课 -- 基本路由
  • 显示技术概念极简理解(分辨率、英寸、PPI、DPI)
  • 2:数据结构:列表与元组
  • sicp每日一题[2.30]
  • Java中的注解处理器:自定义注解与APT工具的应用场景
  • YOLOv8默认使用的优化器是什么?optimizer默认值auto指定的是什么优化器?
  • 【玩转贪心算法专题】738. 单调递增的数字【中等】
  • 【Gitee自动化测试2】Git,TortoiseGit,Github,Gitlab,Gitee
  • 心觉:如何重塑高效学习的潜意识(3)东西很好,但用不起,怎么破?
  • C++学习笔记----8、掌握类与对象(一)---- 对象中的动态内存分配(4)
  • 【项目经验分享】深度学习点云算法毕业设计项目案例定制
  • 【机器学习】探索LSTM:深度学习领域的强大时间序列处理能力
  • Mysql InnoDB引擎的四大核心特性
  • 衡石分析平台系统管理手册-功能配置之全局 CSS 设置
  • Github 2024-09-27 Java开源项目日报Top8
  • python-list-comprehension-find-pair-given-sum-two-arrays