Слияние кода завершено, страница обновится автоматически
/**
*!
* \file b_drv_ICM20948.c
* \version v0.0.1
* \date 2020/03/25
* \author Bean(notrynohigh@outlook.com)
*******************************************************************************
* @attention
*
* Copyright (c) 2020 Bean
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************
*/
/*Includes ----------------------------------------------*/
#include "drivers/inc/b_drv_icm20948.h"
/**
* \addtogroup B_DRIVER
* \{
*/
/**
* \addtogroup ICM20948
* \{
*/
/**
* \defgroup ICM20948_Private_TypesDefinitions
* \{
*/
/**
* \}
*/
/**
* \defgroup ICM20948_Private_Defines
* \{
*/
#define DRIVER_NAME ICM20948
/* define ICM-20948 Register */
#define ICM20948_ID 0xEAU
#define I2C_ADD_ICM20948 0xD0
#define I2C_ADD_ICM20948_AK09916 0x0C
#define I2C_ADD_ICM20948_AK09916_READ 0x80
/* user bank 0 register */
#define REG_ADD_WHO_AM_I 0x00
#define REG_VAL_WIA 0xEA
#define REG_ADD_USER_CTRL 0x03
#define REG_VAL_BIT_DMP_EN 0x80
#define REG_VAL_BIT_FIFO_EN 0x40
#define REG_VAL_BIT_I2C_MST_EN 0x20
#define REG_VAL_BIT_I2C_IF_DIS 0x10
#define REG_VAL_BIT_DMP_RST 0x08
#define REG_VAL_BIT_DIAMOND_DMP_RST 0x04
#define REG_ADD_PWR_MIGMT_1 0x06
#define REG_VAL_ALL_RGE_RESET 0x80
#define REG_VAL_RUN_MODE 0x01 // Non low-power mode
#define REG_ADD_LP_CONFIG 0x05
#define REG_ADD_PWR_MGMT_1 0x06
#define REG_ADD_PWR_MGMT_2 0x07
#define REG_VAL_MGMNT_2_SEN_ENABLE 0x00
#define REG_ADD_ACCEL_XOUT_H 0x2D
#define REG_ADD_ACCEL_XOUT_L 0x2E
#define REG_ADD_ACCEL_YOUT_H 0x2F
#define REG_ADD_ACCEL_YOUT_L 0x30
#define REG_ADD_ACCEL_ZOUT_H 0x31
#define REG_ADD_ACCEL_ZOUT_L 0x32
#define REG_ADD_GYRO_XOUT_H 0x33
#define REG_ADD_GYRO_XOUT_L 0x34
#define REG_ADD_GYRO_YOUT_H 0x35
#define REG_ADD_GYRO_YOUT_L 0x36
#define REG_ADD_GYRO_ZOUT_H 0x37
#define REG_ADD_GYRO_ZOUT_L 0x38
#define REG_ADD_EXT_SENS_DATA_00 0x3B
#define REG_ADD_REG_BANK_SEL 0x7F
#define REG_VAL_REG_BANK_0 0x00
#define REG_VAL_REG_BANK_1 0x10
#define REG_VAL_REG_BANK_2 0x20
#define REG_VAL_REG_BANK_3 0x30
/* user bank 1 register */
/* user bank 2 register */
#define REG_ADD_GYRO_SMPLRT_DIV 0x00
#define REG_ADD_GYRO_CONFIG_1 0x01
#define REG_VAL_BIT_GYRO_DLPCFG_2 0x10 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_DLPCFG_4 0x20 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_DLPCFG_6 0x30 /* bit[5:3] */
#define REG_VAL_BIT_GYRO_FS_250DPS 0x00 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_500DPS 0x02 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_1000DPS 0x04 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_FS_2000DPS 0x06 /* bit[2:1] */
#define REG_VAL_BIT_GYRO_DLPF 0x01 /* bit[0] */
#define REG_ADD_ACCEL_SMPLRT_DIV_2 0x11
#define REG_ADD_ACCEL_CONFIG 0x14
#define REG_VAL_BIT_ACCEL_DLPCFG_2 0x10 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_DLPCFG_4 0x20 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_DLPCFG_6 0x30 /* bit[5:3] */
#define REG_VAL_BIT_ACCEL_FS_2g 0x00 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_4g 0x02 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_8g 0x04 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_FS_16g 0x06 /* bit[2:1] */
#define REG_VAL_BIT_ACCEL_DLPF 0x01 /* bit[0] */
/* user bank 3 register */
#define REG_ADD_I2C_MST_CTRL 0x01
#define REG_ADD_I2C_MST_CTRL_CLK_400KHZ \
0x07 // Gives 345.6kHz and is recommended to achieve max 400kHz
#define REG_ADD_I2C_SLV0_ADDR 0x03
#define REG_ADD_I2C_SLV0_REG 0x04
#define REG_ADD_I2C_SLV0_CTRL 0x05
#define REG_VAL_BIT_SLV0_EN 0x80
#define REG_VAL_BIT_MASK_LEN 0x07
#define REG_ADD_I2C_SLV0_DO 0x06
#define REG_ADD_I2C_SLV1_ADDR 0x07
#define REG_ADD_I2C_SLV1_REG 0x08
#define REG_ADD_I2C_SLV1_CTRL 0x09
#define REG_ADD_I2C_SLV1_DO 0x0A
#define REG_ADD_MAG_WIA1 0x00
#define REG_VAL_MAG_WIA1 0x48
#define REG_ADD_MAG_WIA2 0x01
#define REG_VAL_MAG_WIA2 0x09
#define REG_ADD_MAG_ST2 0x10
#define REG_ADD_MAG_DATA 0x11
#define REG_ADD_MAG_CNTL2 0x31
#define REG_VAL_MAG_MODE_PD 0x00
#define REG_VAL_MAG_MODE_SM 0x01
#define REG_VAL_MAG_MODE_10HZ 0x02
#define REG_VAL_MAG_MODE_20HZ 0x04
#define REG_VAL_MAG_MODE_50HZ 0x05
#define REG_VAL_MAG_MODE_100HZ 0x08
#define REG_VAL_MAG_MODE_ST 0x10
#define REG_ADD_MAG_CNTL3 0x32
#define REG_VAL_MAG_CNTL3_RESET 0x01
#define TEMP_SENSITIVITY_REG 333.87f
/**
* \}
*/
/**
* \defgroup ICM20948_Private_Macros
* \{
*/
#define F_IIC_WriteByte(a, b, c) \
do \
{ \
w_data = c; \
_bICM20948WriteRegs(pdrv, b, &w_data, 1); \
} while (0);
#define F_IIC_ReadByte(a, b, e) \
do \
{ \
e = _bICM20948ReadRegs(pdrv, b, &r_data, 1); \
} while (0);
#define ICM20948_Mag_Read(a, b, c, d) \
do \
{ \
bICM20948_Mag_Read(pdrv, a, b, c, d); \
} while (0);
#define ICM20948_Mag_Write(a, b, c) \
do \
{ \
bICM20948_Mag_Write(pdrv, a, b, c); \
} while (0);
#define ICM20948_Mag_Reset() \
do \
{ \
bICM20948_Mag_Reset(pdrv); \
} while (0);
#define F_IIC_ReadBytes(a, b, c, d, e) \
do \
{ \
e = _bICM20948ReadRegs(pdrv, b, c, d); \
} while (0);
#define F_Delay_ms(a) bHalDelayMs(a)
/**
* \}
*/
/**
* \defgroup ICM20948_Private_Variables
* \{
*/
bDRIVER_HALIF_TABLE(bICM20948_HalIf_t, DRIVER_NAME);
/**
* \}
*/
/**
* \defgroup ICM20948_Private_FunctionPrototypes
* \{
*/
/**
* \}
*/
/**
* \defgroup ICM20948_Private_Functions
* \{
*/
//----------------------------------------------------------------
static int _bICM20948ReadRegs(bDriverInterface_t *pdrv, uint8_t reg, uint8_t *data, uint16_t len)
{
bDRIVER_GET_HALIF(_if, bICM20948_HalIf_t, pdrv);
// reg = reg | 0x80;
if (bHalI2CMemRead(_if, reg, 1, data, len) < 0)
{
return -1;
}
else
{
return len;
}
}
static int _bICM20948WriteRegs(bDriverInterface_t *pdrv, uint8_t reg, uint8_t *data, uint16_t len)
{
bDRIVER_GET_HALIF(_if, bICM20948_HalIf_t, pdrv);
bHalI2CMemWrite(_if, reg, 1, data, len);
return len;
}
static int _ICM20948GetID(bDriverInterface_t *pdrv, uint8_t *id)
{
int retval = 0;
// uint8_t w_data = 0;
uint8_t r_data = 0;
// F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_0);
F_IIC_ReadByte(I2C_ADD_ICM20948, REG_ADD_WHO_AM_I, retval);
if (retval <= 0)
{
return -1;
}
*id = r_data;
return retval;
}
int F_ICM20948_GetData(bDriverInterface_t *pdrv, int32_t *pData_acc, int32_t *pData_gyro,
int32_t *pData_mag, float *tempreature)
{
int retval = 0;
uint8_t tempBuf[20];
int16_t pDataRaw_x[3];
int16_t pDataRaw_g[3];
int16_t pDataRaw_m[3];
int16_t tempreature_r;
F_IIC_ReadBytes(I2C_ADD_ICM20948, REG_ADD_ACCEL_XOUT_H, &tempBuf[0], 20, retval);
if (retval < 0)
{
return -1;
}
pDataRaw_x[0] = ((((int16_t)tempBuf[0]) << 8) + (int16_t)tempBuf[1]);
pDataRaw_x[1] = ((((int16_t)tempBuf[2]) << 8) + (int16_t)tempBuf[3]);
pDataRaw_x[2] = ((((int16_t)tempBuf[4]) << 8) + (int16_t)tempBuf[5]);
pDataRaw_g[0] = ((((int16_t)tempBuf[6]) << 8) + (int16_t)tempBuf[7]);
pDataRaw_g[1] = ((((int16_t)tempBuf[8]) << 8) + (int16_t)tempBuf[9]);
pDataRaw_g[2] = ((((int16_t)tempBuf[10]) << 8) + (int16_t)tempBuf[11]);
tempreature_r = ((((int16_t)tempBuf[12]) << 8) + (int16_t)tempBuf[13]);
pDataRaw_m[0] = ((((int16_t)tempBuf[15]) << 8) + (int16_t)tempBuf[14]);
pDataRaw_m[1] = ((((int16_t)tempBuf[17]) << 8) + (int16_t)tempBuf[16]);
pDataRaw_m[2] = ((((int16_t)tempBuf[19]) << 8) + (int16_t)tempBuf[18]);
*tempreature = (float)(tempreature_r / TEMP_SENSITIVITY_REG);
pData_gyro[0] = pDataRaw_g[0] * 60.9756097561f;
pData_gyro[1] = pDataRaw_g[1] * 60.9756097561f;
pData_gyro[2] = pDataRaw_g[2] * 60.9756097561f;
pData_acc[0] = (int32_t)(pDataRaw_x[0] * 0.061035156f);
pData_acc[1] = (int32_t)(pDataRaw_x[1] * 0.061035156f);
pData_acc[2] = (int32_t)(pDataRaw_x[2] * 0.061035156f);
pData_mag[0] = (int32_t)(pDataRaw_m[0] * 1.0f);
pData_mag[1] = (int32_t)(pDataRaw_m[1] * 1.0f);
pData_mag[2] = (int32_t)(pDataRaw_m[2] * 1.0f);
return retval;
}
static void bICM20948_Mag_Read(bDriverInterface_t *pdrv, uint8_t I2CAddr, uint8_t RegAddr,
uint8_t Len, uint8_t *pdata)
{
uint8_t w_data = 0;
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_3); // swtich bank3
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_ADDR,
I2CAddr | I2C_ADD_ICM20948_AK09916_READ);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_REG, RegAddr);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_CTRL, REG_VAL_BIT_SLV0_EN | Len);
F_Delay_ms(10);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_0); // swtich bank0
for (uint8_t i = 0; i < Len; i++)
{
_bICM20948ReadRegs(pdrv, REG_ADD_EXT_SENS_DATA_00 + i, pdata + i, 1);
}
}
static void bICM20948_Mag_Write(bDriverInterface_t *pdrv, uint8_t I2CAddr, uint8_t RegAddr,
uint8_t data)
{
uint8_t w_data = 0;
uint8_t r_data = 0;
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_3); // swtich bank3
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_ADDR, I2CAddr);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_REG, RegAddr);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_DO, data);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_SLV0_CTRL, REG_VAL_BIT_SLV0_EN | 1);
F_Delay_ms(50);
ICM20948_Mag_Read(I2CAddr, RegAddr, 1, &r_data);
}
static void bICM20948_Mag_Reset(bDriverInterface_t *pdrv)
{
uint8_t w_data = 0;
ICM20948_Mag_Write(I2C_ADD_ICM20948_AK09916, REG_ADD_MAG_CNTL2, 0x00);
F_Delay_ms(10);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_0);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_PWR_MGMT_1, REG_VAL_ALL_RGE_RESET);
F_Delay_ms(10);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_PWR_MGMT_1, REG_VAL_RUN_MODE);
F_Delay_ms(10);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_PWR_MGMT_2, REG_VAL_MGMNT_2_SEN_ENABLE);
F_Delay_ms(10);
ICM20948_Mag_Write(I2C_ADD_ICM20948_AK09916, REG_ADD_MAG_CNTL3, REG_VAL_MAG_CNTL3_RESET);
F_Delay_ms(10);
}
static int _bICM20948Read(bDriverInterface_t *pdrv, uint32_t off, uint8_t *pbuf, uint32_t len)
{
int retval = 0;
bICM20948_9Axis_t *ptmp = (bICM20948_9Axis_t *)pbuf;
if (len < sizeof(bICM20948_9Axis_t))
{
return 0;
}
retval =
F_ICM20948_GetData(pdrv, ptmp->acc_arr, ptmp->gyro_arr, ptmp->mag_arr, &ptmp->temperature);
return retval;
}
static int _bICM20948Ctl(struct bDriverIf *pdrv, uint8_t cmd, void *param)
{
int retval = 0;
switch (cmd)
{
case bCMD_ICM20948_SET_STATUS_ERR:
{
pdrv->status = -1;
}
break;
default:
retval = -1;
break;
}
return retval;
}
/**
* \}
*/
/**
* \addtogroup ICM20948_Exported_Functions
* \{
*/
int bICM20948_Init(bDriverInterface_t *pdrv)
{
uint8_t w_data = 0;
uint8_t r_data = 0;
uint8_t data[8];
bDRIVER_STRUCT_INIT(pdrv, DRIVER_NAME, bICM20948_Init);
pdrv->read = _bICM20948Read;
pdrv->ctl = _bICM20948Ctl;
if (_ICM20948GetID(pdrv, &r_data) < 0)
{
return -1;
}
if (r_data != ICM20948_ID)
{
return -1;
}
ICM20948_Mag_Reset();
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_3);
/* Reset I2C master clock. */
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_MST_CTRL, 0);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_0);
_bICM20948ReadRegs(pdrv, 0x03, &r_data, 1);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_USER_CTRL, r_data | REG_VAL_BIT_I2C_MST_EN);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_3);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_I2C_MST_CTRL, REG_ADD_I2C_MST_CTRL_CLK_400KHZ);
F_Delay_ms(10);
// configure gyro
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_2);
F_IIC_WriteByte(
I2C_ADD_ICM20948, REG_ADD_GYRO_CONFIG_1,
REG_VAL_BIT_GYRO_DLPCFG_6 | REG_VAL_BIT_GYRO_FS_2000DPS | REG_VAL_BIT_GYRO_DLPF);
// configure acc
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_ACCEL_SMPLRT_DIV_2, 0x00);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_ACCEL_CONFIG,
REG_VAL_BIT_ACCEL_DLPCFG_6 | REG_VAL_BIT_ACCEL_FS_4g | REG_VAL_BIT_ACCEL_DLPF);
// checkMag
uint8_t ret[2];
ICM20948_Mag_Read(I2C_ADD_ICM20948_AK09916, REG_ADD_MAG_WIA1, 2, ret);
if (!((ret[0] == REG_VAL_MAG_WIA1) && (ret[1] == REG_VAL_MAG_WIA2)))
{
return -2;
}
F_Delay_ms(10);
ICM20948_Mag_Write(I2C_ADD_ICM20948_AK09916, REG_ADD_MAG_CNTL2, REG_VAL_MAG_MODE_100HZ);
F_Delay_ms(10);
ICM20948_Mag_Read(I2C_ADD_ICM20948_AK09916, REG_ADD_MAG_DATA, 8, data);
F_IIC_WriteByte(I2C_ADD_ICM20948, REG_ADD_REG_BANK_SEL, REG_VAL_REG_BANK_0);
return 0;
}
#ifdef BSECTION_NEED_PRAGMA
#pragma section driver_init
#endif
bDRIVER_REG_INIT(B_DRIVER_ICM20948, bICM20948_Init);
#ifdef BSECTION_NEED_PRAGMA
#pragma section
#endif
/**
* \}
*/
/**
* \}
*/
/**
* \}
*/
/************************ Copyright (c) 2020 Bean *****END OF FILE****/
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )