/**
******************************************************************************
* @file lis25ba_reg.c
* @author Sensors Software Solution Team
* @brief LIS25BA driver file
******************************************************************************
* @attention
*
*
© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#include "lis25ba_reg.h"
/**
* @defgroup LIS25BA
* @brief This file provides a set of functions needed to drive the
* lis25ba enhanced inertial module.
* @{
*
*/
/**
* @defgroup LIS25BA_Interfaces_Functions
* @brief This section provide a set of functions used to read and
* write a generic register of the device.
* MANDATORY: return 0 -> no Error.
* @{
*
*/
/**
* @brief Read generic device register
*
* @param ctx communication interface handler.(ptr)
* @param reg first register address to read.
* @param data buffer for data read.(ptr)
* @param len number of consecutive register to read.
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t __weak lis25ba_read_reg(const stmdev_ctx_t *ctx, uint8_t reg,
uint8_t *data,
uint16_t len)
{
int32_t ret;
if (ctx == NULL)
{
return -1;
}
ret = ctx->read_reg(ctx->handle, reg, data, len);
return ret;
}
/**
* @brief Write generic device register
*
* @param ctx communication interface handler.(ptr)
* @param reg first register address to write.
* @param data the buffer contains data to be written.(ptr)
* @param len number of consecutive register to write.
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t __weak lis25ba_write_reg(const stmdev_ctx_t *ctx, uint8_t reg,
uint8_t *data,
uint16_t len)
{
int32_t ret;
if (ctx == NULL)
{
return -1;
}
ret = ctx->write_reg(ctx->handle, reg, data, len);
return ret;
}
/**
* @}
*
*/
/**
* @defgroup LIS25BA_Private_functions
* @brief Section collect all the utility functions needed by APIs.
* @{
*
*/
static void bytecpy(uint8_t *target, uint8_t *source)
{
if ((target != NULL) && (source != NULL))
{
*target = *source;
}
}
/**
* @}
*
*/
/**
* @defgroup LIS25BA_Sensitivity
* @brief These functions convert raw-data into engineering units.
* @{
*
*/
float_t lis25ba_from_raw_to_mg(int16_t lsb)
{
return ((float_t)lsb) * 0.122f;
}
/**
* @}
*
*/
/**
* @defgroup Basic configuration
* @brief This section groups all the functions concerning
* device basic configuration.
* @{
*
*/
/**
* @brief Device "Who am I".[get]
*
* @param ctx communication interface handler.(ptr)
* @param val ID values read from the I2C interface.
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_id_get(const stmdev_ctx_t *ctx, lis25ba_id_t *val)
{
int32_t ret = 0;
if (ctx != NULL)
{
ret = lis25ba_read_reg(ctx, LIS25BA_WHO_AM_I, (uint8_t *) & (val->id), 1);
}
return ret;
}
/**
* @brief Configures the bus operating mode.[set]
*
* @param ctx communication interface handler.(ptr)
* @param val configures the TDM bus operating mode.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_bus_mode_set(const stmdev_ctx_t *ctx,
lis25ba_bus_mode_t *val)
{
lis25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
lis25ba_tdm_cmax_h_t tdm_cmax_h;
lis25ba_tdm_cmax_l_t tdm_cmax_l;
uint8_t reg[2];
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CTRL_REG,
(uint8_t *)&tdm_ctrl_reg, 1);
if (ret == 0)
{
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CMAX_H, reg, 2);
bytecpy((uint8_t *)&tdm_cmax_h, ®[0]);
bytecpy((uint8_t *)&tdm_cmax_l, ®[1]);
tdm_ctrl_reg.tdm_pd = ~val->tdm.en;
tdm_ctrl_reg.data_valid = val->tdm.clk_pol;
tdm_ctrl_reg.delayed = val->tdm.clk_edge;
tdm_ctrl_reg.wclk_fq = val->tdm.mapping;
tdm_cmax_h.tdm_cmax = (uint8_t)(val->tdm.cmax / 256U);
tdm_cmax_l.tdm_cmax = (uint8_t)(val->tdm.cmax - tdm_cmax_h.tdm_cmax);
}
if (ret == 0)
{
ret = lis25ba_write_reg(ctx, LIS25BA_TDM_CTRL_REG,
(uint8_t *)&tdm_ctrl_reg, 1);
}
if (ret == 0)
{
bytecpy(®[0], (uint8_t *)&tdm_cmax_h);
bytecpy(®[1], (uint8_t *)&tdm_cmax_l);
ret = lis25ba_write_reg(ctx, LIS25BA_TDM_CMAX_H, reg, 2);
}
return ret;
}
/**
* @brief Get the bus operating mode.[get]
*
* @param ctx communication interface handler.(ptr)
* @param val configures the TDM bus operating mode.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_bus_mode_get(const stmdev_ctx_t *ctx,
lis25ba_bus_mode_t *val)
{
lis25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
lis25ba_tdm_cmax_h_t tdm_cmax_h;
lis25ba_tdm_cmax_l_t tdm_cmax_l;
uint8_t reg[2];
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CTRL_REG,
(uint8_t *)&tdm_ctrl_reg, 1);
if (ret == 0)
{
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CMAX_H, reg, 2);
bytecpy((uint8_t *)&tdm_cmax_h, ®[0]);
bytecpy((uint8_t *)&tdm_cmax_l, ®[1]);
}
val->tdm.en = ~tdm_ctrl_reg.tdm_pd;
val->tdm.clk_pol = tdm_ctrl_reg.data_valid;
val->tdm.clk_edge = tdm_ctrl_reg.delayed;
val->tdm.mapping = tdm_ctrl_reg.wclk_fq;
val->tdm.cmax = tdm_cmax_h.tdm_cmax * 256U;
val->tdm.cmax += tdm_cmax_l.tdm_cmax;
return ret;
}
/**
* @brief Sensor conversion parameters selection.[set]
*
* @param ctx communication interface handler.(ptr)
* @param val set the sensor conversion parameters by checking
* the constraints of the device.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_mode_set(const stmdev_ctx_t *ctx, lis25ba_md_t *val)
{
lis25ba_axes_ctrl_reg_t axes_ctrl_reg;
lis25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
lis25ba_ctrl_reg_t ctrl_reg;
uint8_t reg[2];
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_CTRL_REG, (uint8_t *)&ctrl_reg, 1);
if (ret == 0)
{
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CTRL_REG, reg, 2);
bytecpy((uint8_t *)&tdm_ctrl_reg, ®[0]);
bytecpy((uint8_t *)&axes_ctrl_reg, ®[1]);
}
ctrl_reg.pd = (uint8_t)val->xl.odr & 0x01U;
tdm_ctrl_reg.wclk_fq = ((uint8_t)val->xl.odr & 0x06U) >> 1;
axes_ctrl_reg.odr_auto_en = ((uint8_t)val->xl.odr & 0x10U) >> 4;
axes_ctrl_reg.axisx_en = val->xl.axis.x;
axes_ctrl_reg.axisy_en = val->xl.axis.y;
axes_ctrl_reg.axisz_en = val->xl.axis.z;
if (ret == 0)
{
ret = lis25ba_write_reg(ctx, LIS25BA_CTRL_REG, (uint8_t *)&ctrl_reg, 1);
}
/* writing checked configuration */
bytecpy(®[0], (uint8_t *)&tdm_ctrl_reg);
bytecpy(®[1], (uint8_t *)&axes_ctrl_reg);
if (ret == 0)
{
ret = lis25ba_write_reg(ctx, LIS25BA_TDM_CTRL_REG, (uint8_t *)®,
2);
}
return ret;
}
/**
* @brief Sensor conversion parameters selection.[get]
*
* @param ctx communication interface handler.(ptr)
* @param val get the sensor conversion parameters.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_mode_get(const stmdev_ctx_t *ctx, lis25ba_md_t *val)
{
lis25ba_axes_ctrl_reg_t axes_ctrl_reg;
lis25ba_tdm_ctrl_reg_t tdm_ctrl_reg;
lis25ba_ctrl_reg_t ctrl_reg;
uint8_t reg[2];
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_CTRL_REG, (uint8_t *)&ctrl_reg, 1);
if (ret == 0)
{
ret = lis25ba_read_reg(ctx, LIS25BA_TDM_CTRL_REG, reg, 2);
bytecpy((uint8_t *)&tdm_ctrl_reg, ®[0]);
bytecpy((uint8_t *)&axes_ctrl_reg, ®[1]);
}
val->xl.axis.x = axes_ctrl_reg.axisx_en;
val->xl.axis.y = axes_ctrl_reg.axisy_en;
val->xl.axis.z = axes_ctrl_reg.axisz_en;
switch ((axes_ctrl_reg.odr_auto_en << 4) | (tdm_ctrl_reg.wclk_fq <<
1) |
ctrl_reg.pd)
{
case LIS25BA_XL_OFF:
val->xl.odr = LIS25BA_XL_OFF;
break;
case LIS25BA_XL_8kHz:
val->xl.odr = LIS25BA_XL_8kHz;
break;
case LIS25BA_XL_16kHz:
val->xl.odr = LIS25BA_XL_16kHz;
break;
case LIS25BA_XL_24kHz:
val->xl.odr = LIS25BA_XL_24kHz;
break;
case LIS25BA_XL_HW_SEL:
val->xl.odr = LIS25BA_XL_HW_SEL;
break;
default:
val->xl.odr = LIS25BA_XL_OFF;
break;
}
return ret;
}
/**
* @brief Read data in engineering unit.[get]
*
* @param tdm_stream data stream from TDM interface.(ptr)
* @param md the TDM interface configuration.(ptr)
* @param data data read by the sensor.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_data_get(uint16_t *tdm_stream, lis25ba_bus_mode_t *md,
lis25ba_data_t *data)
{
uint8_t offset;
uint8_t i;
if (md->tdm.mapping == PROPERTY_DISABLE)
{
offset = 0; /* slot0-1-2 */
}
else
{
offset = 4; /* slot4-5-6 */
}
for (i = 0U; i < 3U; i++)
{
data->xl.raw[i] = (int16_t) tdm_stream[i + offset];
data->xl.mg[i] = lis25ba_from_raw_to_mg(data->xl.raw[i]);
}
return 0;
}
/**
* @brief Linear acceleration sensor self-test enable.[set]
*
* @param ctx read / write interface definitions.(ptr)
* @param val enable/ disable selftest
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_self_test_set(const stmdev_ctx_t *ctx, uint8_t val)
{
lis25ba_test_reg_t test_reg;
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
if (ret == 0)
{
test_reg.st = val;
ret = lis25ba_write_reg(ctx, LIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
}
return ret;
}
/**
* @brief Linear acceleration sensor self-test enable.[get]
*
* @param ctx read / write interface definitions.(ptr)
* @param val enable/ disable selftest.(ptr)
*
* @retval interface status (MANDATORY: return 0 -> no Error).
*
*/
int32_t lis25ba_self_test_get(const stmdev_ctx_t *ctx, uint8_t *val)
{
lis25ba_test_reg_t test_reg;
int32_t ret;
ret = lis25ba_read_reg(ctx, LIS25BA_TEST_REG, (uint8_t *)&test_reg, 1);
*val = test_reg.st;
return ret;
}
/**
* @}
*
*/
/**
* @}
*
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/