2023-11-22 15:17:09 +01:00

413 lines
11 KiB
C

/**
******************************************************************************
* @file lis3dsh.c
* @author MCD Application Team
* @version V2.0.0
* @date 03-August-2015
* @brief This file provides a set of functions needed to manage the LIS3DSH
* MEMS Accelerometer.
******************************************************************************
* @attention
*
* Copyright (c) 2015 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 "lis3dsh.h"
/** @addtogroup BSP
* @{
*/
/** @addtogroup Components
* @{
*/
/** @addtogroup LIS3DSH
* @brief This file includes the motion sensor driver for LIS3DSH motion sensor
* devices.
* @{
*/
/** @defgroup LIS3DSH_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup LIS3DSH_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup LIS3DSH_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup LIS3DSH_Private_Variables
* @{
*/
ACCELERO_DrvTypeDef Lis3dshDrv =
{
LIS3DSH_Init,
LIS3DSH_DeInit,
LIS3DSH_ReadID,
LIS3DSH_RebootCmd,
LIS3DSH_Click_IntConfig,
0,
0,
0,
0,
0,
0,
0,
LIS3DSH_ReadACC,
};
/**
* @}
*/
/** @defgroup LIS3DSH_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup LIS3DSH_Private_Functions
* @{
*/
/**
* @brief Set LIS3DSH Initialization.
* @param InitStruct: contains mask of different init parameters
* @retval None
*/
void LIS3DSH_Init(uint16_t InitStruct)
{
uint8_t ctrl = 0x00;
/* Configure the low level interface */
ACCELERO_IO_Init();
/* Configure MEMS: power mode(ODR) and axes enable */
ctrl = (uint8_t) (InitStruct);
/* Write value to MEMS CTRL_REG4 register */
ACCELERO_IO_Write(&ctrl, LIS3DSH_CTRL_REG4_ADDR, 1);
/* Configure MEMS: full scale and self test */
ctrl = (uint8_t) (InitStruct >> 8);
/* Write value to MEMS CTRL_REG5 register */
ACCELERO_IO_Write(&ctrl, LIS3DSH_CTRL_REG5_ADDR, 1);
}
/**
* @brief LIS3DSH De-Initialization.
* @param None
* @retval None.
*/
void LIS3DSH_DeInit(void)
{
}
/**
* @brief Read LIS3DSH device ID.
* @param None
* @retval The Device ID (two bytes).
*/
uint8_t LIS3DSH_ReadID(void)
{
uint8_t tmp = 0;
/* Configure the low level interface */
ACCELERO_IO_Init();
/* Read WHO_AM_I register */
ACCELERO_IO_Read(&tmp, LIS3DSH_WHO_AM_I_ADDR, 1);
/* Return the ID */
return (uint16_t)tmp;
}
/**
* @brief Set LIS3DSH Interrupt configuration
* @param LIS3DSH_InterruptConfig_TypeDef: pointer to a LIS3DSH_InterruptConfig_TypeDef
* structure that contains the configuration setting for the LIS3DSH Interrupt.
* @retval None
*/
void LIS3DSH_InterruptConfig(LIS3DSH_InterruptConfigTypeDef *LIS3DSH_IntConfigStruct)
{
uint8_t ctrl = 0x00;
/* Configure Interrupt Selection , Request and Signal */
ctrl = (uint8_t)(LIS3DSH_IntConfigStruct->Interrupt_Selection_Enable | \
LIS3DSH_IntConfigStruct->Interrupt_Request | \
LIS3DSH_IntConfigStruct->Interrupt_Signal);
/* Write value to MEMS CTRL_REG3 register */
ACCELERO_IO_Write(&ctrl, LIS3DSH_CTRL_REG3_ADDR, 1);
/* Configure State Machine 1 */
ctrl = (uint8_t)(LIS3DSH_IntConfigStruct->State_Machine1_Enable | \
LIS3DSH_IntConfigStruct->State_Machine1_Interrupt);
/* Write value to MEMS CTRL_REG1 register */
ACCELERO_IO_Write(&ctrl, LIS3DSH_CTRL_REG1_ADDR, 1);
/* Configure State Machine 2 */
ctrl = (uint8_t)(LIS3DSH_IntConfigStruct->State_Machine2_Enable | \
LIS3DSH_IntConfigStruct->State_Machine2_Interrupt);
/* Write value to MEMS CTRL_REG2 register */
ACCELERO_IO_Write(&ctrl, LIS3DSH_CTRL_REG2_ADDR, 1);
}
/**
* @brief Set LIS3DSH for click detection
* @param None
* @retval None
*/
void LIS3DSH_Click_IntConfig(void)
{
uint8_t ctrl = 0x00;
LIS3DSH_InterruptConfigTypeDef LIS3DSH_InterruptStruct;
ACCELERO_IO_ITConfig();
/* Set LIS3DSH Interrupt configuration */
LIS3DSH_InterruptStruct.Interrupt_Selection_Enable = LIS3DSH_INTERRUPT_2_ENABLE;
LIS3DSH_InterruptStruct.Interrupt_Request = LIS3DSH_INTERRUPT_REQUEST_LATCHED;
LIS3DSH_InterruptStruct.Interrupt_Signal = LIS3DSH_INTERRUPT_SIGNAL_HIGH;
LIS3DSH_InterruptStruct.State_Machine1_Enable = LIS3DSH_SM_DISABLE;
LIS3DSH_InterruptStruct.State_Machine2_Enable = LIS3DSH_SM_ENABLE;
LIS3DSH_InterruptStruct.State_Machine2_Interrupt = LIS3DSH_SM_INT1;
LIS3DSH_InterruptConfig(&LIS3DSH_InterruptStruct);
/* Set LIS3DSH State Machines configuration */
ctrl=0x03;
ACCELERO_IO_Write(&ctrl, LIS3DSH_TIM2_1_L_ADDR,1);
ctrl=0xC8;
ACCELERO_IO_Write(&ctrl, LIS3DSH_TIM1_1_L_ADDR,1);
ctrl=0x45;
ACCELERO_IO_Write(&ctrl, LIS3DSH_THRS2_1_ADDR,1);
ctrl=0xFC;
ACCELERO_IO_Write(&ctrl, LIS3DSH_MASK1_A_ADDR,1);
ctrl=0xA1;
ACCELERO_IO_Write(&ctrl, LIS3DSH_SETT1_ADDR,1);
ctrl=0x01;
ACCELERO_IO_Write(&ctrl, LIS3DSH_PR1_ADDR,1);
ACCELERO_IO_Write(&ctrl, LIS3DSH_SETT2_ADDR,1);
/* Configure State Machine 2 to detect single click */
ACCELERO_IO_Write(&ctrl, LIS3DSH_ST2_1_ADDR,1);
ctrl=0x06;
ACCELERO_IO_Write(&ctrl, LIS3DSH_ST2_2_ADDR,1);
ctrl=0x28;
ACCELERO_IO_Write(&ctrl, LIS3DSH_ST2_3_ADDR,1);
ctrl=0x11;
ACCELERO_IO_Write(&ctrl, LIS3DSH_ST2_4_ADDR,1);
}
/**
* @brief Change the lowpower mode for LIS3DSH.
* @param LowPowerMode: new state for the lowpower mode.
* This parameter can be one of the following values:
* @arg LIS3DSH_DATARATE_POWERDOWN: Power down mode
* @arg LIS3DSH_DATARATE_3_125: Normal mode. ODR: 3.125 Hz
* @arg LIS3DSH_DATARATE_6_25: Normal mode. ODR: 6.25 Hz
* @arg LIS3DSH_DATARATE_12_5: Normal mode. ODR: 12.5 Hz
* @arg LIS3DSH_DATARATE_25: Normal mode. ODR: 25 Hz
* @arg LIS3DSH_DATARATE_50: Normal mode. ODR: 50 Hz
* @arg LIS3DSH_DATARATE_100: Normal mode. ODR: 100 Hz
* @arg LIS3DSH_DATARATE_400: Normal mode. ODR: 400 Hz
* @arg LIS3DSH_DATARATE_800: Normal mode. ODR: 800 Hz
* @arg LIS3DSH_DATARATE_1600: Normal mode. ODR: 1600 Hz
* @retval None
*/
void LIS3DSH_ODR_LowpowerCmd(uint8_t ODR_LowPowerMode)
{
uint8_t tmpreg;
/* Read CTRL_REG4 register */
ACCELERO_IO_Read(&tmpreg, LIS3DSH_CTRL_REG4_ADDR, 1);
/* Set new low power mode configuration */
tmpreg &= (uint8_t)~LIS3DSH_DATARATE_100;
tmpreg |= ODR_LowPowerMode;
/* Write value to MEMS CTRL_REG4 register */
ACCELERO_IO_Write(&tmpreg, LIS3DSH_CTRL_REG4_ADDR, 1);
}
/**
* @brief Data Rate command.
* @param DataRateValue: Data rate value.
* This parameter can be one of the following values:
* @arg LIS3DSH_DATARATE_3_125: 3.125 Hz output data rate
* @arg LIS3DSH_DATARATE_6_25: 6.25 Hz output data rate
* @arg LIS3DSH_DATARATE_12_5: 12.5 Hz output data rate
* @arg LIS3DSH_DATARATE_25: 25 Hz output data rate
* @arg LIS3DSH_DATARATE_50: 50 Hz output data rate
* @arg LIS3DSH_DATARATE_100: 100 Hz output data rate
* @arg LIS3DSH_DATARATE_400: 400 Hz output data rate
* @arg LIS3DSH_DATARATE_800: 800 Hz output data rate
* @arg LIS3DSH_DATARATE_1600: 1600 Hz output data rate
* @retval None
*/
void LIS3DSH_DataRateCmd(uint8_t DataRateValue)
{
uint8_t tmpreg;
/* Read CTRL_REG4 register */
ACCELERO_IO_Read(&tmpreg, LIS3DSH_CTRL_REG4_ADDR, 1);
/* Set new data rate configuration from 100 to 400Hz */
tmpreg &= (uint8_t)~LIS3DSH_DATARATE_400;
tmpreg |= DataRateValue;
/* Write value to MEMS CTRL_REG4 register */
ACCELERO_IO_Write(&tmpreg, LIS3DSH_CTRL_REG4_ADDR, 1);
}
/**
* @brief Change the Full Scale of LIS3DSH.
* @param FS_value: new full scale value.
* This parameter can be one of the following values:
* @arg LIS3DSH_FULLSCALE_2: +-2g
* @arg LIS3DSH_FULLSCALE_4: +-4g
* @arg LIS3DSH_FULLSCALE_6: +-6g
* @arg LIS3DSH_FULLSCALE_8: +-8g
* @arg LIS3DSH_FULLSCALE_16: +-16g
* @retval None
*/
void LIS3DSH_FullScaleCmd(uint8_t FS_value)
{
uint8_t tmpreg;
/* Read CTRL_REG5 register */
ACCELERO_IO_Read(&tmpreg, LIS3DSH_CTRL_REG5_ADDR, 1);
/* Set new full scale configuration */
tmpreg &= (uint8_t)~LIS3DSH_FULLSCALE_16;
tmpreg |= FS_value;
/* Write value to MEMS CTRL_REG5 register */
ACCELERO_IO_Write(&tmpreg, LIS3DSH_CTRL_REG5_ADDR, 1);
}
/**
* @brief Reboot memory content of LIS3DSH.
* @param None
* @retval None
*/
void LIS3DSH_RebootCmd(void)
{
uint8_t tmpreg;
/* Read CTRL_REG6 register */
ACCELERO_IO_Read(&tmpreg, LIS3DSH_CTRL_REG6_ADDR, 1);
/* Enable or Disable the reboot memory */
tmpreg |= LIS3DSH_BOOT_FORCED;
/* Write value to MEMS CTRL_REG6 register */
ACCELERO_IO_Write(&tmpreg, LIS3DSH_CTRL_REG6_ADDR, 1);
}
/**
* @brief Read LIS3DSH output register, and calculate the acceleration
* ACC[mg]=SENSITIVITY* (out_h*256+out_l)/16 (12 bit representation).
* @param pointer on floating buffer.
* @retval None
*/
void LIS3DSH_ReadACC(int16_t *pData)
{
int8_t buffer[6];
uint8_t crtl, i = 0x00;
float sensitivity = LIS3DSH_SENSITIVITY_0_06G;
float valueinfloat = 0;
ACCELERO_IO_Read(&crtl, LIS3DSH_CTRL_REG5_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[0], LIS3DSH_OUT_X_L_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[1], LIS3DSH_OUT_X_H_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[2], LIS3DSH_OUT_Y_L_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[3], LIS3DSH_OUT_Y_H_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[4], LIS3DSH_OUT_Z_L_ADDR, 1);
ACCELERO_IO_Read((uint8_t*)&buffer[5], LIS3DSH_OUT_Z_H_ADDR, 1);
switch(crtl & LIS3DSH__FULLSCALE_SELECTION)
{
/* FS bit = 000 ==> Sensitivity typical value = 0.06milligals/digit */
case LIS3DSH_FULLSCALE_2:
sensitivity = LIS3DSH_SENSITIVITY_0_06G;
break;
/* FS bit = 001 ==> Sensitivity typical value = 0.12milligals/digit */
case LIS3DSH_FULLSCALE_4:
sensitivity = LIS3DSH_SENSITIVITY_0_12G;
break;
/* FS bit = 010 ==> Sensitivity typical value = 0.18milligals/digit */
case LIS3DSH_FULLSCALE_6:
sensitivity = LIS3DSH_SENSITIVITY_0_18G;
break;
/* FS bit = 011 ==> Sensitivity typical value = 0.24milligals/digit */
case LIS3DSH_FULLSCALE_8:
sensitivity = LIS3DSH_SENSITIVITY_0_24G;
break;
/* FS bit = 100 ==> Sensitivity typical value = 0.73milligals/digit */
case LIS3DSH_FULLSCALE_16:
sensitivity = LIS3DSH_SENSITIVITY_0_73G;
break;
default:
break;
}
/* Obtain the mg value for the three axis */
for(i=0; i<3; i++)
{
valueinfloat = ((buffer[2*i+1] << 8) + buffer[2*i]) * sensitivity;
pData[i] = (int16_t)valueinfloat;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/