ICM20948 DMP代码详解(20)

news2024/11/15 19:41:01

接前一篇文章: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 asleep
		result = 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 disabled
		result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 0);  //Disable LP_EN
 
	result |= 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_EN
 
	return 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函数中,继续往下解析接下来的内容。

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

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

相关文章

在docker中安装 zendesk/maxwell 失败,解决方法

文章目录 1、拉取镜像失败2、一键设置镜像加速&#xff1a;修改文件 /etc/docker/daemon.json&#xff08;如果不存在则创建&#xff09;3、保存好之后 执行以下两条命令 1、拉取镜像失败 [rootlocalhost docker]# docker pull zendesk/maxwell Using default tag: latest Err…

有奖直播 | onsemi IPM 助力汽车电气革命及电子化时代冷热管理

在全球汽车行业向电气化和智能化转型的浪潮中&#xff0c;功率管理技术的创新和应用成为了关键驱动力。作为全球领先的半导体解决方案供应商&#xff0c;onsemi&#xff08;安森美&#xff09;致力于通过其先进的智能功率模块&#xff08;IPM&#xff09;技术&#xff0c;推动汽…

Java许可政策再变,Oracle JDK 17 免费期将结束!

原文地址&#xff1a;https://www.infoworld.com/article/3478122/get-ready-for-more-java-licensing-changes.html Oracle JDK 17的许可协议将于9月变更回Oracle Technology Network License Agreement&#xff0c;这将迫使用户重新评估他们的使用策略。 有句老话说&#xf…

【MyBatis---快速学习和复习】

学习视频&#xff08;强推&#xff09;&#xff1a;【MyBatis视频零基础入门到进阶&#xff0c;MyBatis全套视频教程源码级深入详解】 https://www.bilibili.com/video/BV1JP4y1Z73S/?p134&share_sourcecopy_web&vd_source4d877b7310d01a59f27364f1080e3382 MyBatis中…

【算法】-单调队列

目录 什么是单调队列 区域内最大值 区域内最小值 什么是单调队列 说到单调队列&#xff0c;其实就是一个双端队列&#xff0c; 顾名思义&#xff0c;单调队列的重点分为「单调」和「队列」。「单调」指的是元素的「规律」——递增&#xff08;或递减&#xff09;。「队列」指…

Python精选200Tips:126-130

Those who know are not as good as those who love, and those who love are not as good as those who enjoy 126 PyInstaller - 将 Python 程序打包成独立可执行文件的工具示例:图像变为灰度图像项目结构代码文件打包步骤运行可执行文件127 PyYAML - YAML 解析和生成工具示…

【机器学习(六)】分类和回归任务-LightGBM算法-Sentosa_DSML社区版

文章目录 一、算法概念二、算法原理&#xff08;一&#xff09;Histogram&#xff08;二&#xff09;GOSS1、信息增益2、近似误差 &#xff08;三&#xff09;EFB 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、LightGBM分类任务实现对比&a…

计算机毕业设计 财会信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【机器学习(四)】分类和回归任务-梯度提升决策树(GBDT)-Sentosa_DSML社区版

文章目录 一、算法概念一、算法原理&#xff08;一&#xff09; GBDT 及负梯度拟合原理&#xff08;二&#xff09; GBDT 回归和分类1、GBDT回归1、GBDT分类二元分类多元分类 &#xff08;三&#xff09;损失函数1、回归问题的损失函数2. 分类问题的损失函数&#xff1a; 三、G…

ThreeJS入门(002):学习思维路径

查看本专栏目录 - 本文是第 002篇入门文章 文章目录 如何使用这个思维导图 Three.js 学习思维导图可以帮助你系统地了解 Three.js 的各个组成部分及其关系。下面是一个简化的 Three.js 学习路径思维导图概述&#xff0c;它包含了学习 Three.js 的主要概念和组件。你可以根据这个…

CSP-J 之计算机基本结构

文章目录 前言计算机的宏观结构计算机的微观结构硬件部分软件部分 计算机硬件系统介绍主存储器与辅助存储器1. 主存储器&#xff08;Main Memory&#xff09;2. 辅助存储器&#xff08;Secondary Storage&#xff09;Cache&#xff08;缓存&#xff09;总线&#xff08;Bus&…

Java 行为型设计模式一口气讲完!*^____^*

Java 责任链模式 Java设计模式 -责任链模式 责任链模式为请求创建一个接收者对象列表。 这种模式是行为模式。 当使用责任链模式时&#xff0c;通常每个接收器包含对另一个接收器的引用。 如果一个对象不能处理请求&#xff0c;则它将相同的对象传递给下一个接收者&#xf…

vue的路由

v2用3版本&#xff0c;v3用4版本 import Vue from vue import VueRouter from vue-router Vue.use(VueRouter) const routes [] const router new VueRouter({ routes }) export default router import Vue from vue import App from ./App.vue import router from /router V…

【漏洞复现】科荣AIO moffice Sql注入漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

应用案例分享 | 智驾路试数据分析及 SiL/HiL 回灌案例介绍

概述 为有效利用海量的路试数据并发挥其价值&#xff0c;经纬恒润推出了OrienLink路试数据分析及开环/闭环回灌测试系统。该系统采用统一的数据存储标准平台&#xff0c;基于云计算技术提供的大规模存储、高带宽和高算力&#xff0c;能够对路试数据进行深入的场景挖掘。通过软件…

AI小项目4-用Pytorch从头实现Transformer(详细注解)

目录 一、前期准备工作学习如何读AI论文读Transformer原始论文用Pytorch从头实现Transformer 二、我的完整代码实现1.导入库2.基本组件创建词嵌入位置嵌入自注意力 3.编码器4.解码器5.完整架构6.简单测试一下代码创建模型和准备简单的训练数据训练一次&#xff08;前向传播&…

用Python实现时间序列模型实战——Day 20: 时间序列预测的综合练习

一、学习内容 在本节中&#xff0c;我们将综合应用前几周学习的时间序列分析与预测方法&#xff0c;完成一个完整的时间序列预测项目&#xff0c;包含从数据预处理、异常检测、模型选择、预测到评估的全流程。项目流程&#xff1a; 1. 数据获取与预处理 数据加载&#xff0c…

023.PL-SQL进阶—视图

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

跨越日语障碍2024轻松实现日语阅读的好帮手

不知道你喜欢看日本小说吗&#xff0c;之前的东野奎吾还有不少日本作家的书籍&#xff0c;如果想看一手的书籍那就只能看日语版本的啦。但是因为语言的问题日语不是很好的小伙伴阅读起来就有一定的难度。今天我就介绍几个日语翻译工具来解决这个问题咯。 1.福昕在线翻译 链接…

简单了解 JVM

目录 ♫什么是JVM ♫JVM的运行流程 ♫JVM运行时数据区 ♪虚拟机栈 ♪本地方法栈 ♪堆 ♪程序计数器 ♪方法区/元数据区 ♫类加载的过程 ♫双亲委派模型 ♫垃圾回收机制 ♫什么是JVM JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机。 虚拟机是指通过软件模…