/** ****************************************************************************** * @file lsm6dsl.c * @author MCD Application Team * @version V1.0.0 * @date 14-February-2017 * @brief This file provides a set of functions needed to manage the LSM6DSL * accelero and gyro devices ****************************************************************************** * @attention * *

© COPYRIGHT(c) 2017 STMicroelectronics

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "lsm6dsl.h" /** @addtogroup BSP * @{ */ /** @addtogroup Component * @{ */ /** @defgroup LSM6DSL LSM6DSL * @{ */ /** @defgroup LSM6DSL_Private_Variables LSM6DSL Private Variables * @{ */ ACCELERO_DrvTypeDef Lsm6dslAccDrv = { LSM6DSL_AccInit, LSM6DSL_AccDeInit, LSM6DSL_AccReadID, 0, LSM6DSL_AccLowPower, 0, 0, 0, 0, 0, 0, 0, LSM6DSL_AccReadXYZ }; GYRO_DrvTypeDef Lsm6dslGyroDrv = { LSM6DSL_GyroInit, LSM6DSL_GyroDeInit, LSM6DSL_GyroReadID, 0, LSM6DSL_GyroLowPower, 0, 0, 0, 0, 0, 0, 0, LSM6DSL_GyroReadXYZAngRate }; /** * @} */ /** @defgroup LSM6DSL_ACC_Private_Functions LSM6DSL ACC Private Functions * @{ */ /** * @brief Set LSM6DSL Accelerometer Initialization. * @param InitStruct: Init parameters */ void LSM6DSL_AccInit(uint16_t InitStruct) { uint8_t ctrl = 0x00; uint8_t tmp; /* Read CTRL1_XL */ tmp = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL1_XL); /* Write value to ACC MEMS CTRL1_XL register: FS and Data Rate */ ctrl = (uint8_t) InitStruct; tmp &= ~(0xFC); tmp |= ctrl; SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL1_XL, tmp); /* Read CTRL3_C */ tmp = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL3_C); /* Write value to ACC MEMS CTRL3_C register: BDU and Auto-increment */ ctrl = ((uint8_t) (InitStruct >> 8)); tmp &= ~(0x44); tmp |= ctrl; SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL3_C, tmp); } /** * @brief LSM6DSL Accelerometer De-initialization. */ void LSM6DSL_AccDeInit(void) { uint8_t ctrl = 0x00; /* Read control register 1 value */ ctrl = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL1_XL); /* Clear ODR bits */ ctrl &= ~(LSM6DSL_ODR_BITPOSITION); /* Set Power down */ ctrl |= LSM6DSL_ODR_POWER_DOWN; /* write back control register */ SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL1_XL, ctrl); } /** * @brief Read LSM6DSL ID. * @retval ID */ uint8_t LSM6DSL_AccReadID(void) { /* IO interface initialization */ SENSOR_IO_Init(); /* Read value at Who am I register address */ return (SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_WHO_AM_I_REG)); } /** * @brief Set/Unset Accelerometer in low power mode. * @param status 0 means disable Low Power Mode, otherwise Low Power Mode is enabled */ void LSM6DSL_AccLowPower(uint16_t status) { uint8_t ctrl = 0x00; /* Read CTRL6_C value */ ctrl = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL6_C); /* Clear Low Power Mode bit */ ctrl &= ~(0x10); /* Set Low Power Mode */ if(status) { ctrl |= LSM6DSL_ACC_GYRO_LP_XL_ENABLED; }else { ctrl |= LSM6DSL_ACC_GYRO_LP_XL_DISABLED; } /* write back control register */ SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL6_C, ctrl); } /** * @brief Read X, Y & Z Acceleration values * @param pData: Data out pointer */ void LSM6DSL_AccReadXYZ(int16_t* pData) { int16_t pnRawData[3]; uint8_t ctrlx= 0; uint8_t buffer[6]; uint8_t i = 0; float sensitivity = 0; /* Read the acceleration control register content */ ctrlx = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL1_XL); /* Read output register X, Y & Z acceleration */ SENSOR_IO_ReadMultiple(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_OUTX_L_XL, buffer, 6); for(i=0; i<3; i++) { pnRawData[i]=((((uint16_t)buffer[2*i+1]) << 8) + (uint16_t)buffer[2*i]); } /* Normal mode */ /* Switch the sensitivity value set in the CRTL1_XL */ switch(ctrlx & 0x0C) { case LSM6DSL_ACC_FULLSCALE_2G: sensitivity = LSM6DSL_ACC_SENSITIVITY_2G; break; case LSM6DSL_ACC_FULLSCALE_4G: sensitivity = LSM6DSL_ACC_SENSITIVITY_4G; break; case LSM6DSL_ACC_FULLSCALE_8G: sensitivity = LSM6DSL_ACC_SENSITIVITY_8G; break; case LSM6DSL_ACC_FULLSCALE_16G: sensitivity = LSM6DSL_ACC_SENSITIVITY_16G; break; } /* Obtain the mg value for the three axis */ for(i=0; i<3; i++) { pData[i]=( int16_t )(pnRawData[i] * sensitivity); } } /** * @} */ /** @defgroup LSM6DSL_GYRO_Private_Functions LSM6DSL GYRO Private Functions * @{ */ /** * @brief Set LSM6DSL Gyroscope Initialization. * @param InitStruct: pointer to a LSM6DSL_InitTypeDef structure * that contains the configuration setting for the LSM6DSL. */ void LSM6DSL_GyroInit(uint16_t InitStruct) { uint8_t ctrl = 0x00; uint8_t tmp; /* Read CTRL2_G */ tmp = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL2_G); /* Write value to GYRO MEMS CTRL2_G register: FS and Data Rate */ ctrl = (uint8_t) InitStruct; tmp &= ~(0xFC); tmp |= ctrl; SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL2_G, tmp); /* Read CTRL3_C */ tmp = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL3_C); /* Write value to GYRO MEMS CTRL3_C register: BDU and Auto-increment */ ctrl = ((uint8_t) (InitStruct >> 8)); tmp &= ~(0x44); tmp |= ctrl; SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL3_C, tmp); } /** * @brief LSM6DSL Gyroscope De-initialization */ void LSM6DSL_GyroDeInit(void) { uint8_t ctrl = 0x00; /* Read control register 1 value */ ctrl = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL2_G); /* Clear ODR bits */ ctrl &= ~(LSM6DSL_ODR_BITPOSITION); /* Set Power down */ ctrl |= LSM6DSL_ODR_POWER_DOWN; /* write back control register */ SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL2_G, ctrl); } /** * @brief Read ID address of LSM6DSL * @retval ID */ uint8_t LSM6DSL_GyroReadID(void) { /* IO interface initialization */ SENSOR_IO_Init(); /* Read value at Who am I register address */ return SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_WHO_AM_I_REG); } /** * @brief Set/Unset LSM6DSL Gyroscope in low power mode * @param status 0 means disable Low Power Mode, otherwise Low Power Mode is enabled */ void LSM6DSL_GyroLowPower(uint16_t status) { uint8_t ctrl = 0x00; /* Read CTRL7_G value */ ctrl = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL7_G); /* Clear Low Power Mode bit */ ctrl &= ~(0x80); /* Set Low Power Mode */ if(status) { ctrl |= LSM6DSL_ACC_GYRO_LP_G_ENABLED; }else { ctrl |= LSM6DSL_ACC_GYRO_LP_G_DISABLED; } /* write back control register */ SENSOR_IO_Write(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL7_G, ctrl); } /** * @brief Calculate the LSM6DSL angular data. * @param pfData: Data out pointer */ void LSM6DSL_GyroReadXYZAngRate(float *pfData) { int16_t pnRawData[3]; uint8_t ctrlg= 0; uint8_t buffer[6]; uint8_t i = 0; float sensitivity = 0; /* Read the gyro control register content */ ctrlg = SENSOR_IO_Read(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_CTRL2_G); /* Read output register X, Y & Z acceleration */ SENSOR_IO_ReadMultiple(LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW, LSM6DSL_ACC_GYRO_OUTX_L_G, buffer, 6); for(i=0; i<3; i++) { pnRawData[i]=((((uint16_t)buffer[2*i+1]) << 8) + (uint16_t)buffer[2*i]); } /* Normal mode */ /* Switch the sensitivity value set in the CRTL2_G */ switch(ctrlg & 0x0C) { case LSM6DSL_GYRO_FS_245: sensitivity = LSM6DSL_GYRO_SENSITIVITY_245DPS; break; case LSM6DSL_GYRO_FS_500: sensitivity = LSM6DSL_GYRO_SENSITIVITY_500DPS; break; case LSM6DSL_GYRO_FS_1000: sensitivity = LSM6DSL_GYRO_SENSITIVITY_1000DPS; break; case LSM6DSL_GYRO_FS_2000: sensitivity = LSM6DSL_GYRO_SENSITIVITY_2000DPS; break; } /* Obtain the mg value for the three axis */ for(i=0; i<3; i++) { pfData[i]=( float )(pnRawData[i] * sensitivity); } } /** * @} */ /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/