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

ICM20948 DMP代码详解(16)

接前一篇文章: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_ens->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_ens->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 ONstatus = 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 offstatus = 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 switchreturn 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 returnif(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_SPIreturn 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.mrgr.cn/news/25092.html

相关文章:

  • 大舍传媒-日本媒体发稿推荐今日东京tokyotoday
  • 什么?blender可以云渲染了!
  • “点餐API”的核心功能以及详细解析
  • java spring validation 自动、手动校验
  • python库安装失败问题
  • 使用阿里OCR身份证识别
  • 计算机网络(Hub 集线器、交换机、路由器)
  • 在对接电影票API时如何快速进行错误处理和调试
  • 情感支持与疏导:帮助自闭症家属走出困境
  • 组件的使用
  • 项目管理:如何确保目标的实现?
  • 关于项目中的内存问题、死锁问题如何定位?——Valgrind
  • 【工资计算 / 2】
  • Python爱心射线(完整代码)
  • GaussDB关键技术原理:高弹性(四)
  • 【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现
  • Debezium数据同步基础概论
  • QtC++截图支持获取鼠标光标
  • 120张网络安全等保拓扑大全,零基础入门到精通,收藏这一篇就够了
  • audio耳麦拔插显示图标逻辑