当前位置: 首页 > article >正文

ICM20948 DMP代码详解(34)

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

 

上一回解析了inv_icm20948_initialize_lower_driver函数中设置FIFO_RST和FIFO_CFG寄存器相关的代码,本回继续往下解析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;
}

当前来到以下代码片段:

	// 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.

3)FIFO_EN和FIFO_EN_2寄存器

对应代码片段如下:

	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.

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

#define REG_FIFO_EN             (BANK_0 | 0x66)
#define BIT_SLV_0_FIFO_EN               0x01

#define REG_FIFO_EN_2           (BANK_0 | 0x67)
#define BIT_PRS_FIFO_EN                 0x20
#define BIT_ACCEL_FIFO_EN               0x10
#define BITS_GYRO_FIFO_EN               0x0E

对应芯片手册中的以下内容:

30beb3cf6a2549e3be8de50487f38c6e.png

e476533c26dd417d8f85480773d1e1b6.png

76b5b93ca71f47089244d33fc9082bae.png

综上,这两句代码的意思是:第1步,设置从设备FIFO(slave FIFO)禁止;第2步,设置加速度计、陀螺仪X、Y、Z轴以及温度传感器不使能。

接下来,来到inv_icm20948_initialize_lower_driver函数的以下代码片段:

	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); 

lp_en_support在此之前为0,因为在inv_icm20948_initialize_lower_driver函数的一开始,就将s->base_state清零了。见上边代码片段:

8251d822cc25424585001445c4e6ef9e.png

那么,在此就将s->base_state.lp_en_support设置为1。

紧接着由于lp_en_support当前值为1了,因此执行判断体中的:

    inv_icm20948_set_chip_power_state(s, CHIP_LP_ENABLE, 1);

这个函数前文书多次讲过,使能ICM20948芯片的低功耗模式。详情参见:ICM20948 DMP代码详解(15)-CSDN博客

再往下就来到了inv_icm20948_initialize_lower_driver函数的最后一个函数调用:

    result |= inv_icm20948_sleep_mems(s); 

这个函数前文书也讲过,就是将ICM20948芯片置为(最)低功耗模式。这里不再重复深入细节了,只是为了回顾再贴一下代码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948DataBaseDriver.c中,如下:

/** Puts DMP3 (SMARTSENSOR) into the lowest power state. Assumes sensors are all off.
*/
int inv_icm20948_sleep_mems(struct inv_icm20948 * s)
{
	int result;
	unsigned char data;

	data = 0x7F;
	result = inv_icm20948_write_mems_reg(s, REG_PWR_MGMT_2, 1, &data);

	result |= inv_icm20948_set_chip_power_state(s, CHIP_AWAKE, 0);

	return result;
}

至此,inv_icm20948_initialize_lower_driver函数就全部解析完了(用了得有小20篇文章),回到实际调用它的位置即icm20948_sensor_setup函数中,下一回继续对于icm20948_sensor_setup后续的内容进行解析。

 


http://www.kler.cn/a/314407.html

相关文章:

  • vue2.7.14 + vant + vue cli脚手架转vite启动运行问题记录
  • 新版 idea 编写 idea 插件时,启动出现 ClassNotFound
  • Elastic Observability 8.16:增强的 OpenTelemetry 支持、高级日志分析和简化的入门流程
  • C++初阶——list
  • rockylinux 8安装 gcc11.2
  • 前端知识点---Javascript的对象(Javascript)
  • 欧美游戏市场的差异
  • 漏洞复现_永恒之蓝
  • AI助力低代码平台:从智能化到高效交付的全新变革
  • 山体滑坡检测系统源码分享
  • STM32 通过 SPI 驱动 W25Q128
  • 【JS】垃圾回收机制与内存泄漏
  • mxnet 的显存分配机制
  • Gitlab学习(009 gitlab冲突提交)
  • 小程序与APP的区别
  • 大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
  • 面试八股--MySQL命名规范
  • 前端组件库
  • 机器翻译之数据处理
  • 基于redis的HyperLogLog数据结构实现的布隆过滤器在信息流中历史数据的应用
  • 分布式锁优化之 防死锁 及 过期时间的原子性保证(优化之设置锁的过期时间)
  • 创新驱动,技术引领:2025年广州见证汽车电子技术新高度
  • git安装包夸克网盘下载
  • 江协科技STM32学习- P15 TIM输出比较
  • MongoDB在Linux系统中的安装与配置指南
  • 亿发工单系统:让任务风平浪静