STM32CubeWL/Drivers/BSP/Components/iis2mdc/iis2mdc.c

574 lines
14 KiB
C

/**
******************************************************************************
* @file iis2mdc.c
* @author MEMS Software Solutions Team
* @brief IIS2MDC driver file
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "iis2mdc.h"
/** @addtogroup BSP BSP
* @{
*/
/** @addtogroup Component Component
* @{
*/
/** @defgroup IIS2MDC IIS2MDC
* @{
*/
/** @defgroup IIS2MDC_Exported_Variables IIS2MDC Exported Variables
* @{
*/
IIS2MDC_CommonDrv_t IIS2MDC_COMMON_Driver =
{
IIS2MDC_Init,
IIS2MDC_DeInit,
IIS2MDC_ReadID,
IIS2MDC_GetCapabilities,
};
IIS2MDC_MAG_Drv_t IIS2MDC_MAG_Driver =
{
IIS2MDC_MAG_Enable,
IIS2MDC_MAG_Disable,
IIS2MDC_MAG_GetSensitivity,
IIS2MDC_MAG_GetOutputDataRate,
IIS2MDC_MAG_SetOutputDataRate,
IIS2MDC_MAG_GetFullScale,
IIS2MDC_MAG_SetFullScale,
IIS2MDC_MAG_GetAxes,
IIS2MDC_MAG_GetAxesRaw,
};
/**
* @}
*/
/** @defgroup IIS2MDC_Private_Function_Prototypes IIS2MDC Private Function Prototypes
* @{
*/
static int32_t ReadMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length);
static int32_t WriteMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length);
/**
* @}
*/
/** @defgroup IIS2MDC_Exported_Functions IIS2MDC Exported Functions
* @{
*/
/**
* @brief Register Component Bus IO operations
* @param pObj the device pObj
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_RegisterBusIO(IIS2MDC_Object_t *pObj, IIS2MDC_IO_t *pIO)
{
int32_t ret = IIS2MDC_OK;
if (pObj == NULL)
{
ret = IIS2MDC_ERROR;
}
else
{
pObj->IO.Init = pIO->Init;
pObj->IO.DeInit = pIO->DeInit;
pObj->IO.BusType = pIO->BusType;
pObj->IO.Address = pIO->Address;
pObj->IO.WriteReg = pIO->WriteReg;
pObj->IO.ReadReg = pIO->ReadReg;
pObj->IO.GetTick = pIO->GetTick;
pObj->Ctx.read_reg = ReadMagRegWrap;
pObj->Ctx.write_reg = WriteMagRegWrap;
pObj->Ctx.handle = pObj;
if (pObj->IO.Init == NULL)
{
ret = IIS2MDC_ERROR;
}
else if (pObj->IO.Init() != IIS2MDC_OK)
{
ret = IIS2MDC_ERROR;
}
else
{
if (pObj->IO.BusType != IIS2MDC_I2C_BUS) /* If the bus type is not I2C */
{
/* Disable I2C interface support only the first time */
if (pObj->is_initialized == 0U)
{
/* Disable I2C interface on the component */
if (iis2mdc_i2c_interface_set(&(pObj->Ctx), IIS2MDC_I2C_DISABLE) != IIS2MDC_OK)
{
ret = IIS2MDC_ERROR;
}
}
}
}
}
return ret;
}
/**
* @brief Initialize the IIS2MDC sensor
* @param pObj the device pObj
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_Init(IIS2MDC_Object_t *pObj)
{
/* Enable BDU */
if (iis2mdc_block_data_update_set(&(pObj->Ctx), PROPERTY_ENABLE) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
/* Operating mode selection - power down */
if (iis2mdc_operating_mode_set(&(pObj->Ctx), IIS2MDC_POWER_DOWN) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
/* Output data rate selection */
if (iis2mdc_data_rate_set(&(pObj->Ctx), IIS2MDC_ODR_100Hz) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
/* Self Test disabled. */
if (iis2mdc_self_test_set(&(pObj->Ctx), PROPERTY_DISABLE) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
pObj->is_initialized = 1;
return IIS2MDC_OK;
}
/**
* @brief Deinitialize the IIS2MDC magnetometer sensor
* @param pObj the device pObj
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_DeInit(IIS2MDC_Object_t *pObj)
{
/* Disable the component */
if (IIS2MDC_MAG_Disable(pObj) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
pObj->is_initialized = 0;
return IIS2MDC_OK;
}
/**
* @brief Read component ID
* @param pObj the device pObj
* @param Id the WHO_AM_I value
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_ReadID(IIS2MDC_Object_t *pObj, uint8_t *Id)
{
if (iis2mdc_device_id_get(&(pObj->Ctx), Id) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
return IIS2MDC_OK;
}
/**
* @brief Get IIS2MDC magnetometer sensor capabilities
* @param pObj Component object pointer
* @param Capabilities pointer to IIS2MDC magnetometer sensor capabilities
* @retval Component status
*/
int32_t IIS2MDC_GetCapabilities(IIS2MDC_Object_t *pObj, IIS2MDC_Capabilities_t *Capabilities)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
Capabilities->Acc = 0;
Capabilities->Gyro = 0;
Capabilities->Magneto = 1;
Capabilities->LowPower = 0;
Capabilities->GyroMaxFS = 0;
Capabilities->AccMaxFS = 0;
Capabilities->MagMaxFS = 50;
Capabilities->GyroMaxOdr = 0.0f;
Capabilities->AccMaxOdr = 0.0f;
Capabilities->MagMaxOdr = 100.0f;
return IIS2MDC_OK;
}
/**
* @brief Enable the IIS2MDC magnetometer sensor
* @param pObj the device pObj
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_Enable(IIS2MDC_Object_t *pObj)
{
/* Check if the component is already enabled */
if (pObj->mag_is_enabled == 1U)
{
return IIS2MDC_OK;
}
/* Output data rate selection. */
if (iis2mdc_operating_mode_set(&(pObj->Ctx), IIS2MDC_CONTINUOUS_MODE) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
pObj->mag_is_enabled = 1;
return IIS2MDC_OK;
}
/**
* @brief Disable the IIS2MDC magnetometer sensor
* @param pObj the device pObj
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_Disable(IIS2MDC_Object_t *pObj)
{
/* Check if the component is already disabled */
if (pObj->mag_is_enabled == 0U)
{
return IIS2MDC_OK;
}
/* Output data rate selection - power down. */
if (iis2mdc_operating_mode_set(&(pObj->Ctx), IIS2MDC_POWER_DOWN) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
pObj->mag_is_enabled = 0;
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC magnetometer sensor sensitivity
* @param pObj the device pObj
* @param Sensitivity pointer
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_GetSensitivity(IIS2MDC_Object_t *pObj, float *Sensitivity)
{
UNUSED(pObj);
*Sensitivity = IIS2MDC_MAG_SENSITIVITY_FS_50GAUSS;
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC magnetometer sensor output data rate
* @param pObj the device pObj
* @param Odr pointer where the output data rate is written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_GetOutputDataRate(IIS2MDC_Object_t *pObj, float *Odr)
{
int32_t ret = IIS2MDC_OK;
iis2mdc_odr_t odr_low_level;
/* Get current output data rate. */
if (iis2mdc_data_rate_get(&(pObj->Ctx), &odr_low_level) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
switch (odr_low_level)
{
case IIS2MDC_ODR_10Hz:
*Odr = 10.0f;
break;
case IIS2MDC_ODR_20Hz:
*Odr = 20.0f;
break;
case IIS2MDC_ODR_50Hz:
*Odr = 50.0f;
break;
case IIS2MDC_ODR_100Hz:
*Odr = 100.0f;
break;
default:
ret = IIS2MDC_ERROR;
break;
}
return ret;
}
/**
* @brief Set the IIS2MDC magnetometer sensor output data rate
* @param pObj the device pObj
* @param Odr the output data rate value to be set
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_SetOutputDataRate(IIS2MDC_Object_t *pObj, float Odr)
{
iis2mdc_odr_t new_odr;
new_odr = (Odr <= 10.000f) ? IIS2MDC_ODR_10Hz
: (Odr <= 20.000f) ? IIS2MDC_ODR_20Hz
: (Odr <= 50.000f) ? IIS2MDC_ODR_50Hz
: IIS2MDC_ODR_100Hz;
if (iis2mdc_data_rate_set(&(pObj->Ctx), new_odr) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC magnetometer sensor full scale
* @param pObj the device pObj
* @param FullScale pointer where the full scale is written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_GetFullScale(IIS2MDC_Object_t *pObj, int32_t *FullScale)
{
UNUSED(pObj);
*FullScale = 50;
return IIS2MDC_OK;
}
/**
* @brief Set the IIS2MDC magnetometer sensor full scale
* @param pObj the device pObj
* @param FullScale the functional full scale to be set
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_SetFullScale(IIS2MDC_Object_t *pObj, int32_t FullScale)
{
UNUSED(pObj);
UNUSED(FullScale);
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC magnetometer sensor raw axes
* @param pObj the device pObj
* @param Value pointer where the raw values of the axes are written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_GetAxesRaw(IIS2MDC_Object_t *pObj, IIS2MDC_AxesRaw_t *Value)
{
iis2mdc_axis3bit16_t data_raw;
/* Read raw data values. */
if (iis2mdc_magnetic_raw_get(&(pObj->Ctx), data_raw.i16bit) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
/* Format the data. */
Value->x = data_raw.i16bit[0];
Value->y = data_raw.i16bit[1];
Value->z = data_raw.i16bit[2];
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC magnetometer sensor axes
* @param pObj the device pObj
* @param MagneticField pointer where the values of the axes are written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_GetAxes(IIS2MDC_Object_t *pObj, IIS2MDC_Axes_t *MagneticField)
{
iis2mdc_axis3bit16_t data_raw;
float sensitivity;
/* Read raw data values. */
if (iis2mdc_magnetic_raw_get(&(pObj->Ctx), data_raw.i16bit) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
/* Get IIS2MDC actual sensitivity. */
(void)IIS2MDC_MAG_GetSensitivity(pObj, &sensitivity);
/* Calculate the data. */
MagneticField->x = (int32_t)((float)((float)data_raw.i16bit[0] * sensitivity));
MagneticField->y = (int32_t)((float)((float)data_raw.i16bit[1] * sensitivity));
MagneticField->z = (int32_t)((float)((float)data_raw.i16bit[2] * sensitivity));
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC register value for magnetic sensor
* @param pObj the device pObj
* @param Reg address to be read
* @param Data pointer where the value is written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_Read_Reg(IIS2MDC_Object_t *pObj, uint8_t Reg, uint8_t *Data)
{
if (iis2mdc_read_reg(&(pObj->Ctx), Reg, Data, 1) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
return IIS2MDC_OK;
}
/**
* @brief Set the IIS2MDC register value for magnetic sensor
* @param pObj the device pObj
* @param Reg address to be written
* @param Data value to be written
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_Write_Reg(IIS2MDC_Object_t *pObj, uint8_t Reg, uint8_t Data)
{
if (iis2mdc_write_reg(&(pObj->Ctx), Reg, &Data, 1) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC MAG data ready bit value
* @param pObj the device pObj
* @param Status the status of data ready bit
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_Get_DRDY_Status(IIS2MDC_Object_t *pObj, uint8_t *Status)
{
if (iis2mdc_mag_data_ready_get(&(pObj->Ctx), Status) != IIS2MDC_OK)
{
return IIS2MDC_ERROR;
}
return IIS2MDC_OK;
}
/**
* @brief Get the IIS2MDC MAG initialization status
* @param pObj the device pObj
* @param Status 1 if initialized, 0 otherwise
* @retval 0 in case of success, an error code otherwise
*/
int32_t IIS2MDC_MAG_Get_Init_Status(IIS2MDC_Object_t *pObj, uint8_t *Status)
{
if (pObj == NULL)
{
return IIS2MDC_ERROR;
}
*Status = pObj->is_initialized;
return IIS2MDC_OK;
}
/**
* @}
*/
/** @defgroup IIS2MDC_Private_Functions IIS2MDC Private Functions
* @{
*/
/**
* @brief Wrap Read register component function to Bus IO function
* @param Handle the device handler
* @param Reg the register address
* @param pData the stored data pointer
* @param Length the length
* @retval 0 in case of success, an error code otherwise
*/
static int32_t ReadMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length)
{
IIS2MDC_Object_t *pObj = (IIS2MDC_Object_t *)Handle;
if (pObj->IO.BusType == IIS2MDC_I2C_BUS) /* I2C */
{
/* Enable Multi-byte read */
return pObj->IO.ReadReg(pObj->IO.Address, (Reg | 0x80U), pData, Length);
}
else /* SPI 3-Wires */
{
/* Enable Multi-byte read */
return pObj->IO.ReadReg(pObj->IO.Address, (Reg | 0x40U), pData, Length);
}
}
/**
* @brief Wrap Write register component function to Bus IO function
* @param Handle the device handler
* @param Reg the register address
* @param pData the stored data pointer
* @param Length the length
* @retval 0 in case of success, an error code otherwise
*/
static int32_t WriteMagRegWrap(void *Handle, uint8_t Reg, uint8_t *pData, uint16_t Length)
{
IIS2MDC_Object_t *pObj = (IIS2MDC_Object_t *)Handle;
if (pObj->IO.BusType == IIS2MDC_I2C_BUS) /* I2C */
{
/* Enable Multi-byte write */
return pObj->IO.WriteReg(pObj->IO.Address, (Reg | 0x80U), pData, Length);
}
else /* SPI 3-Wires */
{
/* Enable Multi-byte write */
return pObj->IO.WriteReg(pObj->IO.Address, (Reg | 0x40U), pData, Length);
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/