ICM20948 DMP代码详解(46)

news2024/11/18 7:46:10

接前一篇文章: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.coloradmin.cn/o/2169525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网口为什么叫RJ45接口,名字的由来?

大家有没有注意到很多地方“网口”都被称作“RJ45”接口。但是&#xff0c;您是否曾经好奇过&#xff0c;这个小小的插孔为何被称为“RJ-45”&#xff1f;这个名字背后又有着怎样的故事呢&#xff1f; RJ-45的全称与定义 首先&#xff0c;我们需要了解“RJ-45”的全称是“Regi…

jetlinks物联网平台学习3:mqtt协议及物模型

mqtt协议及物模型 1、创建产品2、配备设备接入方式3、上传消息协议4、填写网关信息5、配置mqtt认证信息6、配置物模型7、创建设备8、使用MQTT X模拟设备接入9、mqttx实现设备->平台 平台->设备 消息发送9.1、属性上报9.2、获取最新属性值&#xff08;读取属性&#xff09…

EEPROM手册笔记

目录 一、特征描述二、功能描述三、总线特性四、设备寻址五、写入操作1.字节写入2.页写入 六、读取操作1.当前地址读取2.随机读取3.顺序读取 一、特征描述 1.Microchip Technology Inc. 24AA04/24LC04B &#xff08;24XX04*&#xff09; 是一款 4 Kbit 电气可擦除 PROM。该器件…

ChatDev:基于对话的多智能体协同软件开发框架

相关代码资源见文末 论文地址:ChatDev: Communicative Agents for Software Development - ACL Anthologyhttps://aclanthology.org/2024.acl-long.810/ 1. 概述 1.1. 当前的挑战 软件开发是一个复杂且多层次的过程,要求具备不同技能的团队成员之间密切合作。例如,架构师…

老人跌倒扶不扶?涪城三职工给出响亮答案

一、关键时刻的选择 于绵阳市三江湖湿地公园&#xff0c;平凡午后&#xff0c;三名环卫人员刘后刚、严荣礼及杨树坤正紧张作业。突闻呼救声&#xff0c;一位老人在石阶上跌倒需援手。在紧急关头&#xff0c;他们果断抛却工具&#xff0c;疾速赶至老人身边。此举不仅展现了他们…

了解网络的相关信息

文章目录 前言了解网络的相关信息1. ip是什么?1.1. 公网IP:1.2. 私有IP:1.2.1. 示例 2. 子网掩码3. 子网掩码的划分网段是什么4. 特殊的回路IP网段(127.0.0.1)5. 端口 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#x…

学习C++的第七天!

1.虚函数是在基类中用 virtual 关键字声明的函数&#xff0c;可以在派生类中被重写。纯虚函数是在虚函数的基础上&#xff0c;在基类中被初始化为 0 的函数&#xff0c;含有纯虚函数的类是抽象类&#xff0c;不能被实例化。 2.如果基类的析构函数不是虚函数&#xff0c;当通过…

(done TODO:从频谱到时域要考虑负频波和余弦波?) 傅里叶变换知识补充

参考&#xff1a;https://www.bilibili.com/video/BV1rC4y1E7FD/?vd_source7a1a0bc74158c6993c7355c5490fc600 sinx 和 sin2x sin3x 等整数倍频率的正弦波都是正交的 cosx 和 cos2x cos3x 等整数倍频率的余弦波都是正交的 这成为三角函数系的正交性 up主从分解出来的波恢复成…

buuctf [ACTF2020 新生赛]Include

学习笔记。 开启靶机。 进入靶场&#xff1a; 我们跟进 tips瞅瞅&#xff1a; 额&#xff0c;纯小白&#xff0c;能想到的就是先F12看看&#xff0c;在CTRLu、以及抓包。 得&#xff0c;不会了&#xff0c;看wp呗&#xff0c;不会死磕没脑子0,0&#xff1f; 参考&#xff1a;…

解决 Adobe 盗版弹窗

在这个文件夹下删除 Adobe CCXProcess 然后重装。 Adobe Premiere Pro 2024 (v24.6.1) Multilingual :: Варез от m0nkrusa [Warez by m0nkrus] (monkrus.ws) Adobe Photoshop 2024 (v25.12) Multilingual :: Варез от m0nkrusa [Warez by m0nkrus] (monkrus.…

FastAPI 第五课 -- 基本路由

目录 一. 前言 二. 根路径路由 三. 路径参数 四. 启动应用和测试路由 一. 前言 在 FastAPI 中&#xff0c;基本路由是定义 API 端点的关键。每个路由都映射到应用程序中的一个函数&#xff0c;用于处理特定的 HTTP 请求&#xff0c;并返回相应的响应。 二. 根路径路由 创…

矩阵求逆的几种方法

1. 定义 对于矩阵的运算中定义了加减法、乘法&#xff08;包含数乘&#xff09;但未定义矩阵除法&#xff0c;可以简单认为矩阵的逆即为矩阵除法。矩阵求逆是线性代数中的一个重要概念&#xff0c;在很多应用领域都有广泛的应用。对于一个给定的方阵 ( A )&#xff0c;如果存在…

全志A133开发板安卓系统调试串口复用成普通串口方法-触觉智能EVB1309

本文介绍了在开发板/主板串口接口不够的情况下&#xff0c;可将调试串口改为普通串口使用&#xff0c;下面为大家分享修改方法。基于触觉智能EVB1309开发板演示&#xff0c;搭载全志A133芯片&#xff0c;具有高性能超低功耗优势&#xff0c;待机功耗低至15mW。 1、内核配置 源…

FortiGate 无线组网

无线管理与配置 FortiAP 连接 internal 接口之后自动获得 ip 地址&#xff1a;192.168.1.xxx/24在 FortiGate 中创建 SSIDFortiGate 自动发现 FortiAP&#xff0c;将 FortiAP 添加到 FortiGate将 SSID 和 FortiAP 关联创建防火墙策略 下面我们就来一起看看在 FortiGate 中该如…

【HTTP 和 HTTPS详解】3

HTTP 状态代码 HTTP 状态代码是服务器发送给客户端的三位数字&#xff0c;用于指示客户端请求的结果。它们分为五类&#xff1a;信息性&#xff08;100-199&#xff09;、成功&#xff08;200-299&#xff09;、重定向&#xff08;300-399&#xff09;、客户端错误&#xff08…

【java笔记】 5 接口使用举例

// 导入Swing库中的消息对话框组件 import javax.swing.*; // 定义一个Circle类&#xff0c;该类实现了ShapeInterface接口 public class Circle implements ShapeInterface { // 定义一个私有变量radius来保存圆的半径 private double radius; // 默认构造函数&#xff0c;初…

第十一章 Java多线程--阻塞队列--PriorityBlockingQueue

目录 一、PriorityBlockingQueue基础概念 主要特点 常用方法 使用示例 二、PriorityBlockingQueue深入了解 1 PriorityBlockingQueue介绍 2 二叉堆结构介绍 3 PriorityBlockingQueue核心属性 4 PriorityBlockingQueue的写入操作 4.1 offer基本流程 4.2 offer扩容操作…

【伺服】Servo入坑学习记录①

前言 这是一个自我摸索的过程&#xff0c;如果有什么良好的、或严厉的批评和建议&#xff0c;恳请指教&#xff0c; 万分感谢经典控制理论中&#xff0c;有几个重要的概念和工具&#xff0c;用于分析和设计控制系统。以下是对 传递函数、伯德图、奈奎斯特图、稳定裕度 和 带宽 …

【Elasticsearch】-文本向量化

由于使用了QAnything 本地知识库应答平台 内部已集成Embedding 文本向量化服务&#xff0c;因此不在单独部署。 基于 transformers 如果需要单独部署&#xff0c;可以参看 BCEmbedding/README_zh.md at master netease-youdao/BCEmbedding GitHub 从启动脚本中可以看出&am…

脚手架是什么?详细版+通俗易懂版!!!!!!

脚手架&#xff08;Scaffolding&#xff09;在软件开发领域&#xff0c;特别是在前端开发和全栈开发环境中&#xff0c;是一个术语&#xff0c;用来描述一个辅助工具或框架&#xff0c;它旨在帮助开发者快速搭建项目的基础结构和开发环境。这些基础结构可能包括项目的目录结构、…