ICM20948 DMP代码详解(16)

news2024/9/21 12:44:20

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

上一回讲到了inv_icm20948_initialize函数中的inv_icm20948_initialize_lower_driver函数中的inv_icm20948_read_mems_reg函数中的inv_icm20948_set_chip_power_state函数。再次贴出该函数源码:

/*!
 ******************************************************************************
 *   @brief     This function sets the power state of the Ivory chip 
 *				loop
 *   @param[in] Function - CHIP_AWAKE, CHIP_LP_ENABLE
 *   @param[in] On/Off - The functions are enabled if previously disabled and 
                disabled if previously enabled based on the value of On/Off.
 ******************************************************************************
 */ 
int inv_icm20948_set_chip_power_state(struct inv_icm20948 *s, unsigned char func, unsigned char on_off)
{
	int status = 0;
 
	switch(func) {
 
		case CHIP_AWAKE:    
			if(on_off){
				if((s->base_state.wake_state & CHIP_AWAKE) == 0) {// undo sleep_en
					s->base_state.pwr_mgmt_1 &= ~BIT_SLEEP;
					status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);
					s->base_state.wake_state |= CHIP_AWAKE;
					inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds
				}
			} else {
				if(s->base_state.wake_state & CHIP_AWAKE) {// set sleep_en
					s->base_state.pwr_mgmt_1 |= BIT_SLEEP;
					status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);
					s->base_state.wake_state &= ~CHIP_AWAKE;
					inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds
				}
			}
		break;
 
		case CHIP_LP_ENABLE:
			if(s->base_state.lp_en_support == 1) {
				if(on_off) {
					if( (inv_icm20948_get_lpen_control(s)) && ((s->base_state.wake_state & CHIP_LP_ENABLE) == 0)){
						s->base_state.pwr_mgmt_1 |= BIT_LP_EN; // lp_en ON
						status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);
						s->base_state.wake_state |= CHIP_LP_ENABLE;
					}
				} else {
					if(s->base_state.wake_state & CHIP_LP_ENABLE){
						s->base_state.pwr_mgmt_1 &= ~BIT_LP_EN; // lp_en off
						status = inv_icm20948_write_single_mems_reg_core(s, REG_PWR_MGMT_1, s->base_state.pwr_mgmt_1);
						s->base_state.wake_state &= ~CHIP_LP_ENABLE;
						inv_icm20948_sleep_100us(1); // after writing the bit wait 100 Micro Seconds
					}
				}
			}
		break;
 
		default:
		break;
 
	}// end switch
 
	return status;
}

上一回说其中还有3个函数需要解析,本回就来一一进行解析。

1)inv_icm20948_write_single_mems_reg_core函数

inv_icm20948_write_single_mems_reg_core函数在C:\Users\ns\Ykq\eMD-SmartMotion-ICM20948-1.1.1\EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,代码如下:

/**
*  @brief      Write single byte of data to a register on MEMs with no power control
*  @param[in]  Register address
*  @param[in]  Data to be written
*  @return     0 if successful.
*/
int inv_icm20948_write_single_mems_reg_core(struct inv_icm20948 *s, uint16_t reg, const uint8_t data)
{
	int result = 0;
	unsigned char regOnly = (unsigned char)(reg & 0x7F);

	result |= inv_set_bank(s, reg >> 7);
	result |= inv_icm20948_write_reg(s, regOnly, &data, 1);

	return result;
}

函数的功能是在没有电源控制的情况下,将单字节数据写入MEMs上的寄存器。实际上分为两步,先设置bank,后写bank中的寄存器。

inv_set_bank函数也在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,代码如下:

/**
*  @brief      Set up the register bank register for accessing registers in 20630.
*  @param[in]  register bank number
*  @return     0 if successful.
*/

static int inv_set_bank(struct inv_icm20948 *s, unsigned char bank)
{
	int result;
	//if bank reg was set before, just return
	if(bank==s->lastBank) 
		return 0;
	else 
		s->lastBank = bank;

	result = inv_icm20948_read_reg(s, REG_BANK_SEL, &s->reg, 1);

	if (result)
		return result;

	s->reg &= 0xce;
	s->reg |= (bank << 4);
	result = inv_icm20948_write_reg(s, REG_BANK_SEL, &s->reg, 1);

	return result;
}

其实还是通用的先读后写流程。先读取REG_BANK_SEL的内容,设置相关位,再写回去。

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

/* register for all banks */
#define REG_BANK_SEL            0x7F

对应于ICM20948芯片手册中的:

bit5:4正好对应的就是上边代码中的

	s->reg &= 0xce;
	s->reg |= (bank << 4);

inv_icm20948_write_reg函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Transport.c中,代码如下:

int inv_icm20948_write_reg(struct inv_icm20948 *s, uint8_t reg, const uint8_t *buf, uint32_t len)
{
	return inv_icm20948_serif_write_reg(&s->serif, reg, buf, len);
}

参考前文书解析的inv_icm20948_read_reg函数的调用流程(ICM20948 DMP代码详解(9)-CSDN博客):

inv_icm20948_read_reg_one函数   --->

        inv_icm20948_read_reg函数   --->

                inv_icm20948_serif_read_reg函数   --->

                        idd_io_hal_read_reg函数

inv_icm20948_write_reg函数的调用流程也是类似的。这里也列一下。

inv_icm20948_serif_write_reg函数在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Serif.h中,代码如下:

static inline int inv_icm20948_serif_write_reg(struct inv_icm20948_serif * s,
		uint8_t reg, const uint8_t * buf, uint32_t len)
{
	assert(s);

	if(len > s->max_write)
		return INV_ERROR_SIZE;

	if(s->write_reg(s->context, reg, buf, len) != 0)
		return INV_ERROR_TRANSPORT;

	return 0;
}

s->wrire_reg对应的就是idd_io_hal_write_reg函数。

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

int idd_io_hal_write_reg(void * context, uint8_t reg, const uint8_t * wbuffer, uint32_t wlen){
	(void)context;
#if SERIF_TYPE_SPI
	return spi_master_transfer_tx(NULL, reg, wbuffer, wlen);
#else /* SERIF_TYPE_I2C */
	return i2c_master_write_register(I2C_Address, reg, wlen, wbuffer);
#endif	
}

和idd_io_hal_read_reg函数一样,idd_io_hal_write_reg函数中调用的i2c_master_write_register函数如果是自己的板子,也是要换成自己平台下的i2c写函数。

本回内容比较多了,余下内容放到下一回继续解析。

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

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

相关文章

[SUCTF 2019]CheckIn

1、文件上传题 2、先上传.user.ini&#xff0c;抓包&#xff0c;然后放包 .user.ini内容为&#xff1a; GIF89a auto_prepend_filetest.jpg 3、接着上传test.jpg&#xff0c;抓包&#xff0c;放包 test.jpg内容&#xff1a; GIF89a? <script languag…

一个基于Spring实现的热更新插件开发框架

前言 对于其他解释性语言来说&#xff0c;热更新根本不是什么事&#xff0c;但对于Java来说是多么的不容易&#xff0c;现在使用Java开发的热更新系统&#xff0c;基本使用JS编写脚本&#xff0c;然后用Java的JavaScript引擎来跑脚本。 spring-hot-plugin 现在有一款开源的S…

PDB自启动设置

1、自启动说明 方案一&#xff1a;oracle12.1只能使用触发器 方案二&#xff1a;oracle12.2可用ALTER pluggable DATABASE ALL save state; 高版本建议优先使用第二种模式 2、触发器模式 CREATE TRIGGER open_all_pdbs AFTER STARTUP ON DATABASE BEGIN EXECUTE IMMEDIA…

通过C# 裁剪PDF页面

在处理PDF文档时&#xff0c;有时需要精确地裁剪页面以适应特定需求&#xff0c;比如去除广告、背景信息或者仅仅是为了简化文档内容。 本文将指导如何使用免费.NET控件通过C#实现裁剪PDF页面。 免费库 Free Spire.PDF for .NET 支持在 .NET (C#, VB.NET, ASP.NET, .NET Core)…

JAVA优化物流生态聚合快递与云洋系统小程序源码

优化物流生态&#xff0c;聚合快递与云洋系统小程序 &#x1f69a; 开篇&#xff1a;物流新生态&#xff0c;从这里启航 在这个快节奏的时代&#xff0c;物流不仅是商品传递的桥梁&#xff0c;更是连接消费者与商家的关键纽带。你是否厌倦了繁琐的物流查询、不稳定的配送时效&…

[Python学习日记-16] 细讲数据类型——元组

[Python学习日记-16] 细讲数据类型——元组 简介 元组的创建和查看 元组的切片 元组的循环 元组的嵌套 简介 有些时候我们的列表数据不想被人修改时怎么办&#xff1f;就可以用元组存放。元组&#xff08;tuple&#xff09;其实是列表的兄弟类型&#xff0c;他们非常的相似…

springboot项目中 前端浏览器访问时遇到跨域请求问题CORS怎么解决?has been blocked by CORS policy

文章目录 现象解决方案1. **全局配置 CORS**2. **使用 CrossOrigin 注解**3. **配置 Spring Security**4. **自定义 CORS 过滤器** Spring Security 6.x 及其后续版本解决方案1. 使用 SecurityFilterChain 配置 CORS2. 重要配置说明3. 在生产环境中的最佳实践 现象 前端浏览器…

【题解】CF2008G

题意翻译 原题链接CF2008G 思路 由于操作次数不限&#xff0c;观察到所有操作都是可逆的&#xff0c;所以可以随便搞。然后观察mex函数&#xff0c;发现让所有数在不重复的情况下尽可能地小是最优的&#xff08;重复就浪费了&#xff09;。      先不考虑重复和 0 0 0&a…

Ali_Yun Port

Ali_Yun Port 云服务器端口

【信创】加装硬盘后如何迁移微信数据到新磁盘 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【信创】Linux加装硬盘后如何迁移微信数据到新磁盘 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在Linux系统中加装新硬盘后&#xff0c;如何将微信等数据迁移到新磁盘的文章。在使用过程中&#xff0c;随着数据量的…

拱式桥安全结构健康监测解决方案

拱式桥作为一种常见的桥梁结构&#xff0c;其拱形设计不仅美观&#xff0c;还具有较高的承载能力。然而&#xff0c;随着使用年限的增加和环境因素的影响&#xff0c;拱式桥的结构健康和稳定需要持续监测和评估。自动化监测技术的应用&#xff0c;可以提升拱式桥的监测效率和准…

快速使用react 全局状态管理工具--redux

redux Redux 是 JavaScript 应用中管理应用状态的工具&#xff0c;特别适用于复杂的、需要共享状态的中大型应用。Redux 的核心思想是将应用的所有状态存储在一个单一的、不可变的状态树&#xff08;state tree&#xff09;中&#xff0c;状态只能通过触发特定的 action 来更新…

代码随想录训练营 Day58打卡 图论part08 拓扑排序 dijkstra(朴素版)

代码随想录训练营 Day58打卡 图论part08 一、拓扑排序 例题&#xff1a;卡码117. 软件构建 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果…

用Python实现时间序列模型实战——Day 18: 时间序列中的季节性与周期性预测

一、学习内容 1. 季节性调整与周期性预测 季节性调整 是在时间序列分析中常用的技术&#xff0c;旨在去除数据中因季节性波动导致的周期性变化&#xff0c;使数据更易于解释和预测。通常&#xff0c;我们可以使用季节性分解方法来分离时间序列中的趋势、季节性和随机成分。 …

JAVA实现压缩包解压兼容Windows系统和MacOs

目标&#xff1a;JAVA实现压缩包解压获取图片素材 问题&#xff1a;Windows系统和MacOs压缩出来的zip内容有区别 MacOs会多出来 以及本身一个文件夹 而windows则不会。为了解决这个问题。兼容mac的压缩包增加一层过滤 要知道 ZipInputStream 可以读取 ZIP 文件中的条目&…

KTV 营业明细+员工提成—SAAS本地化及未来之窗行业应用跨平台架构

一、ktv 绩效必要性 1. 激励员工积极性&#xff1a;提成制度能够直接将员工的努力和收入挂钩&#xff0c;促使员工更加积极主动地工作&#xff0c;以获取更高的收入。 2. 提高工作效率和业绩&#xff1a;为了获得更多提成&#xff0c;员工会努力提高工作效率&#xff0c;增加业…

别中招!从“超低利率“到“包过承诺“,揭秘贷款几大陷阱!

今天咱们聊聊贷款时得防的那些坑&#xff0c;免得一不小心就被套路了。你以为找了个靠谱帮手&#xff0c;结果却是步步陷阱&#xff0c;咱们一起来揭秘这些招数&#xff0c;也给大伙儿提个醒。 第一招&#xff0c;低利率诱惑。正常普通信用贷款服务费是2-15%个点内&#xff0c;…

第十七节:学习Hutool上传文件(自学Spring boot 3.x的第四天)

这节记录下如何使用Hutool库上传本地的文件到服务器端&#xff08;因为是练习&#xff0c;所以是本地端&#xff09;。 第一步&#xff1a;引入Hutool库最新版本&#xff0c;通过maven方式。&#xff08;最新版本需去maven仓库查询&#xff09; 第二步&#xff1a;编写一个post…

Django路由访问及查询数据

1、在应用模块下&#xff0c;创建urls文件&#xff0c;用来存放访问路由 2、在项目总访问url里面注册路由 3、在view文件里&#xff0c;定义方法参数 from django.core import serializers from django.db import connection from django.http import HttpResponse, JsonRespo…

【佳学基因检测】在织梦网站中, 创建或修改目录:/var/www/html/cp 失败! DedeTag Engine Create File False

【佳学基因检测】在织梦网站中, 创建或修改目录&#xff1a;/var/www/html/cp 失败&#xff01; DedeTag Engine Create File False 在使用 DedeCMS&#xff08;一个常用的内容管理系统&#xff09;时&#xff0c;如果遇到“创建或修改目录&#xff1a;/var/www/html/cp 失败&…