ICM20948 DMP代码详解(21)

news2024/11/22 23:23:26

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

 

上一回终于解析完了inv_icm20948_read_mems_reg函数,本回回到inv_icm20948_initialize_lower_driver函数中,继续往下解析该函数接下来的内容。为了便于理解和分析,在此贴出inv_icm20948_initialize_lower_driver函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,如下:

/** Should be called once on power up. Loads DMP3, initializes internal variables needed 
*   for other lower driver functions.
*/
int inv_icm20948_initialize_lower_driver(struct inv_icm20948 * s, enum SMARTSENSOR_SERIAL_INTERFACE type, 
	const uint8_t *dmp3_image, uint32_t dmp3_image_size)
{
	int result = 0;
	static unsigned char data;
	// set static variable
	s->sAllowLpEn = 1;
	s->s_compass_available = 0;
	// ICM20948 do not support the proximity sensor for the moment.
	// s_proximity_available variable is nerver changes
	s->s_proximity_available = 0;

	// Set varialbes to default values
	memset(&s->base_state, 0, sizeof(s->base_state));
	s->base_state.pwr_mgmt_1 = BIT_CLK_PLL;
	s->base_state.pwr_mgmt_2 = BIT_PWR_ACCEL_STBY | BIT_PWR_GYRO_STBY | BIT_PWR_PRESSURE_STBY;
	s->base_state.serial_interface = type;
	result |= inv_icm20948_read_mems_reg(s, REG_USER_CTRL, 1, &s->base_state.user_ctrl);

	result |= inv_icm20948_wakeup_mems(s);

	result |= inv_icm20948_read_mems_reg(s, REG_WHO_AM_I, 1, &data);

	/* secondary cycle mode should be set all the time */
	data = BIT_I2C_MST_CYCLE|BIT_ACCEL_CYCLE|BIT_GYRO_CYCLE;

	// Set default mode to low power mode
	result |= inv_icm20948_set_lowpower_or_highperformance(s, 0);
	
	// Disable Ivory DMP.
	if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI)   
		s->base_state.user_ctrl = BIT_I2C_IF_DIS;
	else
		s->base_state.user_ctrl = 0;

	result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);

	//Setup Ivory DMP.
	result |= inv_icm20948_load_firmware(s, dmp3_image, dmp3_image_size);
	if(result)
		return result;
	else
		s->base_state.firmware_loaded = 1;
	result |= inv_icm20948_set_dmp_address(s);
	// Turn off all sensors on DMP by default.
	//result |= dmp_set_data_output_control1(0);   // FIXME in DMP, these should be off by default.
	result |= dmp_icm20948_reset_control_registers(s);
	
	// set FIFO watermark to 80% of actual FIFO size
	result |= dmp_icm20948_set_FIFO_watermark(s, 800);

	// Enable Interrupts.
	data = 0x2;
	result |= inv_icm20948_write_mems_reg(s, REG_INT_ENABLE, 1, &data); // Enable DMP Interrupt
	data = 0x1;
	result |= inv_icm20948_write_mems_reg(s, REG_INT_ENABLE_2, 1, &data); // Enable FIFO Overflow Interrupt

	// TRACKING : To have accelerometers datas and the interrupt without gyro enables.
	data = 0XE4;
	result |= inv_icm20948_write_mems_reg(s, REG_SINGLE_FIFO_PRIORITY_SEL, 1, &data);

	// Disable HW temp fix
	inv_icm20948_read_mems_reg(s, REG_HW_FIX_DISABLE,1,&data);
	data |= 0x08;
	inv_icm20948_write_mems_reg(s, REG_HW_FIX_DISABLE,1,&data);

	// Setup MEMs properties.
	s->base_state.accel_averaging = 1; //Change this value if higher sensor sample avergaing is required.
	s->base_state.gyro_averaging = 1;  //Change this value if higher sensor sample avergaing is required.
	inv_icm20948_set_gyro_divider(s, FIFO_DIVIDER);       //Initial sampling rate 1125Hz/19+1 = 56Hz.
	inv_icm20948_set_accel_divider(s, FIFO_DIVIDER);      //Initial sampling rate 1125Hz/19+1 = 56Hz.

	// Init the sample rate to 56 Hz for BAC,STEPC and B2S
	dmp_icm20948_set_bac_rate(s, DMP_ALGO_FREQ_56);
	dmp_icm20948_set_b2s_rate(s, DMP_ALGO_FREQ_56);

	// FIFO Setup.
	result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_CFG, BIT_SINGLE_FIFO_CFG); // FIFO Config. fixme do once? burst write?
	result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_RST, 0x1f); // Reset all FIFOs.
	result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_RST, 0x1e); // Keep all but Gyro FIFO in reset.
	result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_EN, 0x0); // Slave FIFO turned off.
	result |= inv_icm20948_write_single_mems_reg(s, REG_FIFO_EN_2, 0x0); // Hardware FIFO turned off.
    
	s->base_state.lp_en_support = 1;
	
	if(s->base_state.lp_en_support == 1)
		inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);

	result |= inv_icm20948_sleep_mems(s);   
        
	return result;
}

先来看以下代码片段:

	result |= inv_icm20948_read_mems_reg(s, REG_USER_CTRL, 1, &s->base_state.user_ctrl);

前几回就是从这一行代码开始,深入到inv_icm20948_read_mems_reg函数中进行解析的。现在总体再看一下这行代码的作用,实际上就是读取USER_CTRL寄存器的内容,保存到s->base_state.user_ctrl中。当然,inv_icm20948_read_mems_reg函数并不是简单进行读取(简单读取的函数是inv_icm20948_read_reg),而是先唤醒芯片,再禁止低功耗模式,读取完寄存器内容,再恢复低功耗模式。

接下来来到以下一行:

	result |= inv_icm20948_wakeup_mems(s);

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

/** Wakes up DMP3 (SMARTSENSOR).
*/
int inv_icm20948_wakeup_mems(struct inv_icm20948 *s)
{
	unsigned char data;
	int result = 0;

	result = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);

	if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {
		s->base_state.user_ctrl |= BIT_I2C_IF_DIS;
		inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);  
	}

	data = 0x47;	// FIXME, should set up according to sensor/engines enabled.
	result |= inv_icm20948_write_mems_reg(s, REG_PWR_MGMT_2, 1, &data);

	if(s->base_state.firmware_loaded == 1) {
		s->base_state.user_ctrl |= BIT_DMP_EN | BIT_FIFO_EN;
		result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);  
	}

	result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);
	return result;
}

一头一尾的两段代码

	result = inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 1);
	result |= inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);

在前文书解析inv_icm20948_read_mems_reg函数的时候已经讲过了,在此不再赘述。只是注意一点,inv_icm20948_wakeup_mems函数中并没有inv_icm20948_read_mems_reg函数中的禁止LP_EN一段代码,不知是遗漏了还是特意没有加。

70fa883fe0bc40d3ab0970b204a65e08.png

重点来看inv_icm20948_wakeup_mems函数中的以下代码片段:

	if(s->base_state.serial_interface == SERIAL_INTERFACE_SPI) {
		s->base_state.user_ctrl |= BIT_I2C_IF_DIS;
		inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);  
	}

	data = 0x47;	// FIXME, should set up according to sensor/engines enabled.
	result |= inv_icm20948_write_mems_reg(s, REG_PWR_MGMT_2, 1, &data);

	if(s->base_state.firmware_loaded == 1) {
		s->base_state.user_ctrl |= BIT_DMP_EN | BIT_FIFO_EN;
		result |= inv_icm20948_write_single_mems_reg(s, REG_USER_CTRL, s->base_state.user_ctrl);  
	}

如果接口是SPI,则调用inv_icm20948_write_single_mem_regs将USER_CTRL寄存器的I2C_IF_DIS位置1。对应于芯片手册中的以下内容:

f78b6e1ec72148d78792a4fef59981ef.png

e96c58658d594a20b1eb6f431dbb0c83.png

257f2c65facf4cb2b152c7ce360e1477.png

inv_icm20948_write_single_mems_reg函数与inv_icm20948_read_single_mems_reg函数流程基本一致,在此也不再详细解析。

inv_icm20948_wakeup_mems函数余下的代码,放在下一回中进行解析。

 

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

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

相关文章

[进阶]面向对象之多态(练习)

需求: //父类animal package polymorphism.Test;public abstract class Animal {private int age;private String color;public Animal() {}public Animal(int age, String color) {this.age age;this.color color;}public int getAge() {return age;}public void setAge(i…

深入理解 C 语言中的结构体 —— 原理与实践

引言 在 C 语言中,结构体是一种非常强大的数据类型,用于组织不同类型的数据成员。通过结构体,我们可以创建复杂的数据结构,用于表示现实生活中的对象。本文将详细介绍 C 语言中结构体的基本概念、语法、使用方法以及一些高级主题…

c++中的二叉搜索树

一概念: 静图展示: 动图展示: ①左子树不为空,则左子树节点值小于根节点值。 ②右子树不为空,则右子树节点值大于根节点值。 ③左右子树均为二叉搜索树。 ④对于它可以插入相等的也可以插入不相等的,这里如果插入的…

MATLAB系列02:MATLAB基础

MATLAB系列02:MATLAB基础 2. MATLAB基础2.1 变量和数组2.2 MATLAB变量的初始化2.2.1 用赋值语句初始化变量2.2.2 用捷径表达式赋值2.2.3 使用内置函数来初始化2.2.4 使用关键字input来初始化 2.3 多维数组2.3.1 创建多维数组2.3.2 多维数组在内存中的存储2.3.3 用单…

深入理解FastAPI中的root_path:提升API部署灵活性的关键配置

在Web开发领域,FastAPI因其高性能、易于使用和类型提示功能而备受开发者喜爱。然而,当涉及到在生产环境中部署FastAPI应用程序时,我们常常需要面对一些挑战,比如如何正确处理代理服务器添加的路径前缀。这时,root_path…

关于java同步调用多个接口并返回数据

在现代软件开发中,应用程序经常需要与多个远程API接口进行交互以获取数据。Java作为一种流行的编程语言,提供了多种方式来实现这一需求。本文将探讨如何在Java中同步调用多个API接口,并有效地处理和返回数据。 同步调用的必要性 在某些场景下…

vue table id一样的列合并

合并场景:如果id一样,则主表列合并,子表列不做合并,可实现单行、多行合并,亲测!!! 展示效果如图示: 组件代码: // table组件 :span-method"objectSpa…

网络安全 DVWA通关指南 DVWA SQL Injection (Blind SQL盲注)

DVWA SQL Injection (Blind) 文章目录 DVWA SQL Injection (Blind)Low布尔盲注时间盲注sqlmap MediumHighImpossible 参考文献 WEB 安全靶场通关指南 Low 0、分析网页源代码 <?phpif( isset( $_GET[ Submit ] ) ) {// Get input$id $_GET[ id ];// Check database$geti…

基于spring boot的车辆故障综合服务平台设计与实现----附源码 73314

摘 要 近年来&#xff0c;随着社会科技的不断发展&#xff0c;人们的生活方方面面进入了信息化时代。计算机的普及&#xff0c;使得我们的生活更加丰富多彩。本论文基于Spring Boot框架&#xff0c;设计并实现了一个车辆故障综合服务平台&#xff0c;旨在提供便捷、高效的汽车…

c++类模板为什么不能编译到动态库中来使用

在使用c的时候&#xff0c;我们习惯于将类的定义声明在头文件中&#xff0c;即.h文件&#xff1b;将类函数的实现定义在源文件中&#xff0c;即.cpp文件。如果我们要提供的是一个动态库&#xff0c;那么这种方式更常用&#xff0c;使用动态库的时候&#xff0c;包含头文件&…

如何注册Liberty大学并获取Perplexity Pro

俗称白嫖 Perplexity Pro 会员 如何注册Liberty大学并获取Perplexity Pro 1. 访问官网 首先&#xff0c;进入Liberty大学官网 https://www.liberty.edu&#xff0c;点击“Apply”按钮。 2. 选择课程 选择“Online”课程&#xff0c;选择“Certificate”&#xff0c;然后随便…

深入理解Docke工作原理:UnionFS文件系统详解

在容器技术的世界中&#xff0c;文件系统的设计和实现是其关键组成部分&#xff0c;影响着镜像的构建效率、容器的启动速度以及资源的利用率。**UnionFS&#xff08;联合文件系统&#xff09;**作为Docker的核心文件系统技术&#xff0c;通过其独特的分层结构和写时复制&#x…

5 - ZYNQ SDK学习记录(2)

文章目录 1 Vivado工程基本设计2 Vivado工程位置不变2.1 修改设计1 - 增加PS侧QSPI外设2.2 修改设计2 - 增加PL侧AXI GPIO外设2.3 总结 3 Vivado工程位置变动3.1 先修改BD后打开SDK3.2 先打开SDK后修改BD3.3 总结 1 Vivado工程基本设计 Step 1&#xff1a; Vivado版本Vivado …

【观影聊数学】聊聊电影《孤注一掷》中的数学逻辑

反电诈题材影片《孤注一掷》取材于真实案例&#xff0c;揭秘了境外电信网络诈骗黑色产业链的骇人内幕。境外诈骗集团往往以高薪招聘为诱饵&#xff0c;吸引有发财梦的人去境外淘金&#xff0c;一旦人们走出国门&#xff0c;跳入犯罪分子设下的陷阱里&#xff0c;等待他们的将是…

【python爬虫】之scrapy框架介绍

一.什么是Scrapy&#xff1f; Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架&#xff0c;非常出名&#xff0c;非常强悍。所谓的框架就是一个已经被集成了各种功能&#xff08;高性能异步下载&#xff0c;队列&#xff0c;分布式&#xff0c;解析&a…

SpringBoot开发——使用@Slf4j注解实现日志输出

文章目录 1、Lombok简介2、SLF4J简介3、实现步骤3.1 创建SpringBoot项目3.2 添加依赖3.3 使用 Slf4j 注解3.4 输出日志信息 4、结论 在现代Java开发中&#xff0c;日志记录是至关重要的。它不仅帮助开发者调试代码&#xff0c;还便于监控系统运行状态和性能。 Lombok 和 SLF4J …

了解水凝胶纤维制造?自润滑纺丝来帮忙!高韧性纤维用途广!

大家好&#xff0c;今天我们来了解一篇水凝胶纤维文章——《Continuous Spinning of High‐Tough Hydrogel Fibers for Flexible Electronics by Using Regional Heterogeneous Polymerization》发表于《Advanced Science》。在柔性电子领域&#xff0c;水凝胶纤维因其独特的性…

检查一个复数C的实部a和虚部b是否都是有限数值即a和b都不是无限数值、空值cmath.isfinite(x)

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 检查一个复数C的实部a和虚部b 是否都是有限数值 即a和b都不是无限数值、空值 cmath.isfinite(x) [太阳]选择题 根据给定的Python代码&#xff0c;哪个选项是错误的&#xff1f; import cma…

适合小客厅使用的投影仪推荐:2024年当贝X5S小户型客厅的最佳选择

我们在买投影前都会先看看家里的环境、预算以及自己的需求去选择适合自己的家的那款&#xff1b;正好最近有朋友向我资讯&#xff1a;我家客厅面积不大&#xff0c;有没有适合的家用投影仪推荐啊&#xff1f;对于这种家庭使用环境不大的小客厅我们该如何挑选投影仪&#xff1f;…

人员抽烟AI检测算法在智慧安防领域的创新应用,助力监控智能化

随着人工智能技术的飞速发展&#xff0c;计算机视觉和深度学习算法在各个领域的应用日益广泛。其中&#xff0c;人员抽烟AI检测算法以其高效、精准的特点&#xff0c;成为公共场所、工厂、学校等场景中的得力助手。本文将介绍TSINGSEE青犀AI智能分析网关V4人员抽烟检测算法的基…