From: Thomas Pietrzak Date: Fri, 18 Oct 2013 21:16:15 +0000 (+0000) Subject: Initial commit X-Git-Url: https://git.thomaspietrzak.com/?a=commitdiff_plain;h=cc358ca48eded5f004a6fa43346ab313a0e44298;p=multitouchglove.git Initial commit git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@113 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- diff --git a/lib/HAL_L3Gx.c b/lib/HAL_L3Gx.c new file mode 100644 index 0000000..117ab94 --- /dev/null +++ b/lib/HAL_L3Gx.c @@ -0,0 +1,45 @@ +#include "HAL_L3Gx.h" + +#include "stm32f10x.h" +#include + +void spi_get(uint8_t *buffer, uint8_t address, uint8_t nb) +{ + //set the read bit + address |= 0xC0; + + //reset multiple byte bit if necessary + if (nb <= 1) + address &= 0xBF; + + spi_start(2); + + //send the request + spi_write(2, &address, 1); + + //get the value + spi_read(2, buffer, nb); + + spi_stop(2); +} + +void spi_set(uint8_t *buffer, uint8_t address, uint8_t nb) +{ + //reset the read bit + address &= 0x3F; + + //set multiple byte bit if necessary + if (nb > 1) + address |= 0x40; + + spi_start(2); + + //send the request + spi_write(2, &address, 1); + + //send the value + spi_write(2, buffer, nb); + + spi_stop(2); +} + diff --git a/lib/HAL_L3Gx.h b/lib/HAL_L3Gx.h new file mode 100755 index 0000000..3031843 --- /dev/null +++ b/lib/HAL_L3Gx.h @@ -0,0 +1,13 @@ +#ifndef __HAL_L3GX__ +#define __HAL_L3GX__ + +#include "spi.h" + +#define L3gxCommInit() spi_init(2) +#define L3gxBufferRead(pVal,cAddress,nBytes) spi_get(pVal,cAddress,nBytes) +#define L3gxBufferWrite(pVal,cAddress,nBytes) spi_set(pVal,cAddress,nBytes) + +void spi_get(uint8_t *buffer, uint8_t address, uint8_t nb); +void spi_set(uint8_t *pcBuffer, uint8_t address, uint8_t nb); + +#endif diff --git a/lib/HAL_LPS331AP.h b/lib/HAL_LPS331AP.h new file mode 100755 index 0000000..a6e94c6 --- /dev/null +++ b/lib/HAL_LPS331AP.h @@ -0,0 +1,103 @@ +/** + * @file HAL_LPS331AP.h + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief Hardware Abstraction Layer for LPS331AP. + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion*/ +#ifndef __HAL_LPS331AP_H +#define __HAL_LPS331AP_H + +/* Includes */ +#include "stm32f10x.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup iNemo_Sensor_Drivers iNemo Sensor Drivers + * @{ + */ + +/** + * @addtogroup HAL_LPS331AP HAL LPS331AP + * @brief This is an adapter header to join the platform indipendent @ref Sensor_Libraries for the LPS331AP pressure sensor + * to the low level driver on the microcontroller side. + * @{ + */ + +/** + * @addtogroup HAL_LPS331AP_Exported_Constants HAL LPS331AP Exported Constants + * @{ + */ + +#define USE_I2C + + +#define LPS_I2C_Speed 400000 +#define LPS_I2C_ADDR0 0xBB +#define LPS_I2C_ADDR1 0xB8 + +/** + *@} + */ + + +/** + * @addtogroup HAL_LPS331AP_Exported_Macros HAL LPS331AP Exported Macros + * @{ + */ + +#ifdef USE_I2C +#include "i2c.h" + +#define Lps331apCommInit() //iNemoI2C1Init(LPS_I2C_Speed) + +#define Lps331apBufferRead(pVal,cAddress,nBytes) iNemoI2C1BufferRead(pVal,cAddress,nBytes) +#define Lps331apBufferWrite(pVal,cAddress,nBytes) iNemoI2C1BufferWrite(pVal,cAddress,nBytes) + +#else +#include "spi.h" + + // put here the macro definition for spi drivers + +#endif + +/** + *@} + */ + +/** + *@} + */ + +/** + *@} + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ diff --git a/lib/HAL_LSM303DLHC.h b/lib/HAL_LSM303DLHC.h new file mode 100755 index 0000000..530f543 --- /dev/null +++ b/lib/HAL_LSM303DLHC.h @@ -0,0 +1,110 @@ +/** + * @file HAL_LSM303DLHC.h + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief Hardware Abstraction Layer for LSM303DLHC. + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion*/ +#ifndef __HAL_LSM303DLHC_H +#define __HAL_LSM303DLHC_H + +/* Includes */ +#include "stm32f10x.h" +#include "i2c.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/** +* @addtogroup iNemo_Sensor_Drivers iNemo Sensor Drivers +* @{ +*/ + +/** + * @addtogroup HAL_LSM303DLHC HAL LSM303DLHC + * @brief This is an adapter header to join the platform indipendent @ref Sensor_Libraries for the LSM303DLHC 6 axis sensor + * to the low level driver on the microcontroller side. + * @{ + */ + +/** + * @addtogroup HAL_LSM303DLHC_Exported_Constants HAL LSM303DLHC Exported Constants + * @{ + */ + + +#define LSM_I2C I2C2 + +#define LSM_I2C_Speed 400000 + + + +/** + * @addtogroup HAL_LSM303DLHC_Interrupt_Pin_Define HAL LSM303DLHC Interrupt Pin Define + * @{ + */ + +#define LSM_A_INT1_Pin GPIO_Pin_2 +#define LSM_A_INT1_Port GPIOD +#define LSM_A_INT1_RCC_Port RCC_APB2Periph_GPIOD + +#define LSM_A_INT2_Pin GPIO_Pin_5 +#define LSM_A_INT2_Port GPIOB +#define LSM_A_INT2_RCC_Port RCC_APB2Periph_GPIOB + + +/** + *@} + */ + +/** + *@} + */ + +/** + * @addtogroup HAL_LSM303DLHC_Exported_Macros HAL LSM303DLHC Exported Macros + * @{ + */ + +#define Lsm303dlhcI2CInit() iNemoI2C2Init(LSM_I2C_Speed) +#define Lsm303dlhcI2CBufferRead(cDevAddress,pVal,cAddress,nBytes) iNemoI2C2BufferRead(cDevAddress,pVal,cAddress,nBytes) +#define Lsm303dlhcI2CBufferWrite(cDevAddress,pVal,cAddress,nBytes) iNemoI2C2BufferWrite(cDevAddress,pVal,cAddress,nBytes) + +/** + *@} + */ + +/** + *@} + */ + +/** + *@} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ diff --git a/lib/L3Gx/inc/L3Gx.h b/lib/L3Gx/inc/L3Gx.h new file mode 100755 index 0000000..6b68034 --- /dev/null +++ b/lib/L3Gx/inc/L3Gx.h @@ -0,0 +1,939 @@ +/******************************************************************************** + * @file L3GX.h + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief Header for L3Gx.c file + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __L3GX_H +#define __L3GX_H + +#include +#include "HAL_L3Gx.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + +/** + * @defgroup L3Gx + * @brief This module contains all the functions to configure the L3Gx (L3G4200D or L3GD20) + * gyroscopic sensor. + * @details + * Since this code is platform independent an implementation of the SPI or I2C driver must + * be provided by the user according to the used platform. + * Every function makes use of the L3gxBufferRead and/or L3gxBufferWrite + * as low level functions to write bytes through the used digital interface. + * In order to link and use this code the user should define and export these functions in a header + * file called "HAL_L3Gx.h" (included by this module). + * @{ + */ + + + + +/** + * @defgroup L3GX_Exported_Types L3Gx Exported Types + * @{ + */ + +/** + * @brief Gyroscope Functional state. Used to enable or disable a specific option. + */ +typedef enum +{ + L3G_DISABLE = 0, + L3G_ENABLE = !L3G_DISABLE +}L3GFunctionalState; + + +/** + * @brief Gyroscope Flag status. Used to set/reset the sensor flags. + */ +typedef enum +{ + L3G_RESET = 0, + L3G_SET = !L3G_RESET +}L3GFlagStatus; + + +/** + * @brief Gyroscope Output Data Rate and LPF bandwidth + */ +typedef enum +{ + + L3G_ODR_100_HZ_CUTOFF_12_5 = 0x00, /*!< Output Data Rate = 100 Hz - LPF Cut-Off = 12.5 Hz */ + L3G_ODR_100_HZ_CUTOFF_25 = 0x10, /*!< Output Data Rate = 100 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_200_HZ_CUTOFF_12_5 = 0x40, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 12.5 Hz */ + L3G_ODR_200_HZ_CUTOFF_25 = 0x50, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_200_HZ_CUTOFF_50 = 0x60, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_200_HZ_CUTOFF_70 = 0x70, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 70 Hz */ + L3G_ODR_400_HZ_CUTOFF_20 = 0x80, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 20 Hz */ + L3G_ODR_400_HZ_CUTOFF_25 = 0x90, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_400_HZ_CUTOFF_50 = 0xA0, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_400_HZ_CUTOFF_110 = 0xB0, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 110 Hz */ + L3G_ODR_800_HZ_CUTOFF_30 = 0xC0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 30 Hz */ + L3G_ODR_800_HZ_CUTOFF_35 = 0xD0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 35 Hz */ + L3G_ODR_800_HZ_CUTOFF_50 = 0xE0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_800_HZ_CUTOFF_110 = 0xF0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 110 Hz */ + + L3G_ODR_95_HZ_CUTOFF_12_5 = 0x00, /*!< Output Data Rate = 95 Hz - LPF Cut-Off = 12.5 Hz */ + L3G_ODR_95_HZ_CUTOFF_25 = 0x10, /*!< Output Data Rate = 95 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_190_HZ_CUTOFF_12_5 = 0x40, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 12.5 Hz */ + L3G_ODR_190_HZ_CUTOFF_25 = 0x50, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_190_HZ_CUTOFF_50 = 0x60, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_190_HZ_CUTOFF_70 = 0x70, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 70 Hz */ + L3G_ODR_380_HZ_CUTOFF_20 = 0x80, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 20 Hz */ + L3G_ODR_380_HZ_CUTOFF_25 = 0x90, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 25 Hz */ + L3G_ODR_380_HZ_CUTOFF_50 = 0xA0, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_380_HZ_CUTOFF_100 = 0xB0, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 100 Hz */ + L3G_ODR_760_HZ_CUTOFF_30 = 0xC0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 30 Hz */ + L3G_ODR_760_HZ_CUTOFF_35 = 0xD0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 35 Hz */ + L3G_ODR_760_HZ_CUTOFF_50 = 0xE0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 50 Hz */ + L3G_ODR_760_HZ_CUTOFF_100 = 0xF0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 100 Hz */ + + +}GyroOutputDataRate; + + + +/** + * @brief Gyroscope Power Mode + */ +typedef enum +{ + L3G_NORMAL_SLEEP_MODE = 0x08, /*!< Normal mode or Sleep mode enabled. To go in sleep mode all axes shall be disabled. */ + L3G_POWER_DOWN_MODE = 0x00 /*!< Power Down mode enabled */ +}GyroPowerMode; + + +/** + * @brief Gyroscope Axes + */ +typedef enum +{ + L3G_X_AXIS_DIS = 0x00, /*!< X Axis disabled */ + L3G_X_AXIS_EN = 0x01, /*!< X Axis enabled */ + L3G_Y_AXIS_DIS = 0x00, /*!< Y Axis disabled */ + L3G_Y_AXIS_EN = 0x02, /*!< Y Axis enabled */ + L3G_Z_AXIS_DIS = 0x00, /*!< Z Axis disabled */ + L3G_Z_AXIS_EN = 0x04, /*!< Z Axis enabled */ + L3G_ALL_AXES_DIS = 0x00, /*!< All axes disabled */ + L3G_ALL_AXES_EN = 0x07 /*!< All axes enabled */ +}GyroAxesEnabling; + + +/** + * @brief Gyroscope Full scale selection + */ +typedef enum +{ + L3G_FS_250_DPS = 0x00, /*!< ±250 dps */ + L3G_FS_500_DPS = 0x10, /*!< ±500 dps */ + L3G_FS_2000_DPS = 0x20 /*!< ±2000 dps */ +}GyroFullScale; + + +/** + * @brief Gyroscope Block Data Update selection + */ +typedef enum +{ + L3G_CONTINUOS_UPDATE = 0x00, /*!< Continuos Update */ + L3G_BLOCK_UPDATE = 0x80 /*!< Single Update: output registers not updated until MSB and LSB reading */ +}GyroBlockDataUpdate; + + +/** + * @brief Gyroscope Endianness selection + */ +typedef enum +{ + L3G_LITTLE_ENDIAN = 0x00, /*!< Little Endian: data LSB @ lower address */ + L3G_BIG_ENDIAN = 0x40 /*!< Big Endian: data MSB @ lower address */ +}GyroEndianness; + + +/** + * @brief Gyroscope High Pass Mode Filter Selection + */ +typedef enum +{ + L3G_HPFM_NORMAL = 0x00, /*!< Normal Mode */ + L3G_HPFM_REFERENCE = 0x10, /*!< Reference Signal for filtering */ + L3G_HPFM_AOI = 0x30 /*!< Autoreset On Interrupt event */ +}GyroHPFMode; + + +/** + * @brief Gyroscope Irq on line 2 list + */ +typedef enum +{ + L3G_I2_EMPTY = 0x01, /*!< FIFO empty flag */ + L3G_I2_OVERRUN = 0x02, /*!< Data over-run flag */ + L3G_I2_WTM = 0x04, /*!< Watermark flag */ + L3G_I2_DRDY = 0x08 /*!< Data ready flag */ +}L3GIrq2List; + + +/** + * @brief Gyroscope Init structure definition + */ +typedef struct +{ + GyroPowerMode xPowerMode; /*!< Low power mode selection (see table 19 datasheet) */ + GyroOutputDataRate xOutputDataRate; /*!< Output Data Rate */ + GyroAxesEnabling xEnabledAxes; /*!< Axes Enable */ + GyroFullScale xFullScale; /*!< Full Scale */ + GyroBlockDataUpdate xDataUpdate; /*!< Data Update mode : Continuos update or data don`t change until MSB and LSB nex reading */ + GyroEndianness xEndianness; /*!< Endianess */ +}L3GInit; + + +/** + * @brief Gyroscope Filter Init structure definition + */ +typedef struct +{ + L3GFunctionalState xHPF; /*!< HPF enabling/disabling */ + uint8_t cHPFCutOff; /*!< This value shall be between 0 and 10. The HPF cut-off frequency will be ODR[Hz]/(12.5(1+cHPFCutOff))*/ + GyroHPFMode xHPF_Mode; /*!< HPF MODE: Normal mode or Reference signal for filtering*/ + uint8_t cHPFReference; /*!< Reference value for filtering*/ +}L3GFilterInit; + + +/** + * @brief Gyroscope Data status. It notifies if data on axis are available or overrided. + */ +typedef struct +{ + L3GFlagStatus X_Da:1; + L3GFlagStatus Y_Da:1; + L3GFlagStatus Z_Da:1; + L3GFlagStatus ZYX_Da:1; + L3GFlagStatus X_Or:1; + L3GFlagStatus Y_Or:1; + L3GFlagStatus Z_Or:1; + L3GFlagStatus ZYX_Or:1; +}L3GDataStatus; + + +/** + * @brief Gyroscope Events on axis bitfield structure + * @note Workaround for X-Y axis inverded. + */ +typedef struct +{ + L3GFlagStatus Y_LOW:1; /*!< X axis low event */ + L3GFlagStatus Y_HIGH:1; /*!< X axis high event */ + L3GFlagStatus X_LOW:1; /*!< Y axis low event */ + L3GFlagStatus X_HIGH:1; /*!< Y axis high event */ + L3GFlagStatus Z_LOW:1; /*!< Z axis low event */ + L3GFlagStatus Z_HIGH:1; /*!< Z axis high event */ + uint8_t :2; /*!< 2 bits padding */ +}L3GAxisEvents; + + +/** + * @brief Gyroscope FIFO Working Mode + */ +typedef enum +{ + L3G_BYPASS_MODE = 0x00, /*!< Bypass mode: don't use the FIFO */ + L3G_FIFO_MODE = 0x20, /*!< FIFO mode */ + L3G_STREAM_MODE = 0x40, /*!< Stream mode */ + L3G_STREAM_TO_FIFO = 0x60, /*!< Stream to FIFO mode */ + L3G_BYPASS_TO_STREAM= 0x80 /*!< Bypass to Stream mode */ +}L3GFifoMode; + + + +/** + * @brief Gyroscope FIFO Init structure definition + */ +typedef struct +{ + L3GFifoMode xFifoMode; /*!< FIFO operating mode */ + uint8_t cWtm; /*!< WaterMark level for FIFO in range [0, 31] */ +}L3GFifoInit; + + +/** + * @brief Gyroscope FIFO Status bitfield structure + */ +typedef struct +{ + uint8_t FIFO_FSS:5; /*!< FIFO unread samples */ + L3GFlagStatus FIFO_EMPTY_FLAG:1; /*!< FIFO Empty flag */ + L3GFlagStatus FIFO_OVRN_FLAG:1; /*!< FIFO Overrun flag */ + L3GFlagStatus FIFO_WTM_FLAG:1; /*!< FIFO Watermark flag */ + +}L3GFifoStatus; + + +/** + * @brief Gyroscope External events on axis combination + */ +typedef enum +{ + L3G_OR_COMBINATION = 0x00, /*!< OR combination of enabled IRQs */ + L3G_AND_COMBINATION = 0x80, /*!< AND combination of enabled IRQs */ + +}L3GIrqOnaxisCombination; + +/** + * @} + */ + + +/** + * @defgroup L3GX_Exported_Constants L3Gx Exported Constants + *@{ + */ + +/** + * @defgroup L3GX_Sensitivity_Defines L3Gx Sensitivity Defines + * @{ + */ + +#define L3G_Sensitivity_250dps (float) 114.285f /*!< gyroscope sensitivity with 250 dps full scale [LSB/dps] */ +#define L3G_Sensitivity_500dps (float) 57.1429f /*!< gyroscope sensitivity with 500 dps full scale [LSB/dps] */ +#define L3G_Sensitivity_2000dps (float) 14.285f /*!< gyroscope sensitivity with 2000 dps full scale [LSB/dps] */ + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup L3GX_Register_Mapping L3Gx Register Mapping + * @{ + */ + +/** + * \brief Gyroscope WHO_AM_I Register: Device identification register. + * \code + * Read + * Default value: 0xD3 + * + * \endcode + */ +#define L3G_WHO_AM_I 0x0F + + +/** + * \brief Gyroscope Control Register 1 + * \code + * Read Write + * Default value: 0x07 + * + * 7:6 DR1-DR0: Output Data Rate selection + * 5:4 BW1-BW0: Bandwidth selection + * + * DR1-DR0 | BW1-BW0 | Gyro ODR [Hz] | LPF cut-off freq[Hz] + * --------------------------------------------------------------- + * 00 | 00 | 100 | 12.5 + * 00 | 01 | 100 | 25 + * 00 | 10 | 100 | 25 + * 00 | 11 | 100 | 25 + * --------------------------------------------------------------- + * 01 | 00 | 200 | 12.5 + * 01 | 01 | 200 | 25 + * 01 | 10 | 200 | 50 + * 01 | 11 | 200 | 70 + * --------------------------------------------------------------- + * 10 | 00 | 400 | 20 + * 10 | 01 | 400 | 25 + * 10 | 10 | 400 | 50 + * 10 | 11 | 400 | 110 + * --------------------------------------------------------------- + * 11 | 00 | 800 | 30 + * 11 | 01 | 800 | 35 + * 11 | 10 | 800 | 50 + * 11 | 11 | 800 | 110 + * --------------------------------------------------------------- + * + * 3 PD: Power down mode enable. Default value: 0 (0: power down mode, sleep, 1: normal mode or sleep mode) + * 2 Zen: Z axis enable. (0 - Z axis disabled; 1- Z axis enabled) + * 1 Yen: Y axis enable. (0 - Y axis disabled; 1- Y axis enabled) + * 0 Xen: X axis enable. (0 - X axis disabled; 1- X axis enabled) + * \endcode + */ +#define L3G_CTRL_REG1 0x20 + + +/** + * \brief Gyroscope Control Register 2 + * \code + * Read Write + * Default value: 0x00 + * + * 7:6 0-0: Value loaded at boot. This value must not be changed + * 5:4 HPM1-HPM0: High Pass filter Mode Selection + * + * HPM1 | HPM0 | High Pass filter Mode + * ------------------------------------------------------------------- + * 0 | 0 | Normal mode (reset reading HP_RESET_FILTER) + * 0 | 1 | Reference signal for filtering + * 1 | 0 | Normal mode + * 1 | 1 | Autoreset on interrupt event + * ------------------------------------------------------------------- + * + * + * + * 3-0 HPCF3-HPCF0: High Pass filter Cut Off frequency selection + * + * HPCF3-HPCF0 | ODR= 100Hz | ODR= 200Hz | ODR= 400Hz | ODR= 800Hz + * ----------------------------------------------------------------------- + * 0000 | 8 | 15 | 30 | 56 + * 0001 | 4 | 8 | 15 | 30 + * 0010 | 2 | 4 | 8 | 15 + * 0011 | 1 | 2 | 4 | 8 + * 0100 | 0.5 | 1 | 2 | 4 + * 0101 | 0.2 | 0.5 | 1 | 2 + * 0110 | 0.1 | 0.2 | 0.5 | 1 + * 0111 | 0.05 | 0.1 | 0.2 | 0.5 + * 1000 | 0.02 | 0.05 | 0.1 | 0.2 + * 1001 | 0.01 | 0.02 | 0.05 | 0.1 + * ----------------------------------------------------------------------- + * \endcode + */ +#define L3G_CTRL_REG2 0x21 + + +/** + * \brief Gyroscope Control Register 3 + * \code + * Read Write + * Default value: 0x00 + * + * 7 I1_Int1: Interrupt enable on INT1 pin. Default value 0. (0: Disable; 1: Enable) + * 6 I1_Boot: Boot status available on INT1. Default value 0. (0: Disable; 1: Enable) + * 5 H_Lactive: Interrupt active configuration on INT1. Default value 0. (0: High; 1:Low) + * 4 PP_OD: Push- Pull / Open drain. Default value: 0. (0: Push- Pull; 1: Open drain) + * 3 I2_DRDY: Date Ready on DRDY/INT2. Default value 0. (0: Disable; 1: Enable) + * 2 I2_WTM: FIFO Watermark interrupt on DRDY/INT2. Default value: 0. (0: Disable; 1: Enable) + * 1 I2_ORun: FIFO Overrun interrupt on DRDY/INT2 Default value: 0. (0: Disable; 1: Enable) + * 0 I2_Empty: FIFO Empty interrupt on DRDY/INT2. Default value: 0. (0: Disable; 1: Enable) + * + * \endcode + */ +#define L3G_CTRL_REG3 0x22 + + +/** + * \brief Gyroscope Control Register 4 + * \code + * Read Write + * Default value: 0x00 + * + * 7 BDU: Block Data Update. Default value: 0 (0: continous update; 1: output registers not updated until MSB and LSB reading) + * 6 BLE: Big/Little Endian Data Selection. Default value 0. (0: Data LSB @ lower address; 1: Data MSB @ lower address) + * 5-4 FS1-FS0: Full Scale selection. Default value: 00 (00: 250 dps; 01: 500 dps; 10: 2000 dps; 11: 2000 dps) + * 3 - + * 2-1 ST1-ST0: Self Test Enable. Default value: 00 (00: Self Test Disabled) + * + * ST1 | ST0 | Self test mode + * ------------------------------------ + * 0 | 0 | Normal mode + * 0 | 1 | Self test 0 + * 1 | 0 | -- + * 1 | 1 | Self test 1 + * ------------------------------------ + * + * 0 SIM: SPI Serial Interface Mode selection. Default value: 0 (0: 4-wire interface; 1: 3-wire interface). + * + * \endcode + */ +#define L3G_CTRL_REG4 0x23 + + +/** + * \brief Gyroscope Control Register 5 + * \code + * Read Write + * Default value: 0x00 + * + * 7 BOOT: Reboot memory content. Default value: 0 (0: normal mode; 1: reboot memory content) + * 6 FIFO_EN: FIFO enable. Default value: 0 (0: FIFO disable; 1: FIFO Enable) + * 5 - + * 4 HPen: High Pass filter Enable. Default value: 0 (0: HPF disabled; 1: HPF enabled. See Figure 20) + * 3-2 INT1_Sel1-INT1_Sel0: INT1 selection configuration. Default value: 0 (See Figure 20) + * + * Hpen | INT_SEL1 | INT_SEL2 | Description + * ---------------------------------------------------------------------------------------------------------------- + * x | 0 | 0 | Non-high-pass-filtered data are used for interrupt generation + * x | 0 | 1 | High-pass-filtered data are used for interrupt generation + * 0 | 1 | x | Low-pass-filtered data are used for interrupt generation + * 1 | 1 | x | High-pass and low-pass-filtered data are used for interrupt generation + * ---------------------------------------------------------------------------------------------------------------- + * + * 1-0 Out_Sel1-Out_Sel0: Out selection configuration. Default value: 0 + * + * Hpen | OUT_SEL1 | OUT_SEL0 | Description + * ------------------------------------------------------------------------------------------------------------- + * x | 0 | 0 | Data in DataReg and FIFO are non-highpass-filtered + * x | 0 | 1 | Data in DataReg and FIFO are high-passfiltered + * 0 | 1 | x | Data in DataReg and FIFO are low-passfiltered by LPF2 + * 1 | 1 | x | Data in DataReg and FIFO are high-pass and low-pass-filtered by LPF2 + * ------------------------------------------------------------------------------------------------------------- + * + * \endcode + */ +#define L3G_CTRL_REG5 0x24 + + +/** + * \brief Gyroscope REFERENCE/DATACAPTURE Register + * \code + * Read Write + * Default value: 0x00 + * + * 7-0 Ref7-Ref0: Reference value for Interrupt generation. Default value: 0 + * + * \endcode + */ +#define L3G_REFERENCE 0x25 + + +/** + * \brief Gyroscope OUT_TEMP Register + * \code + * Read + * Default value: (The value is expressed as 16bit two’s complement) + * + * 7-0 Temp7-Temp0: Temperature data. + * + * \endcode + */ +#define L3G_OUT_TEMP 0x26 + + +/** + * \brief Gyroscope STATUS Register + * \code + * Read + * Default value: (The value is expressed as 16bit two’s complement) + * + * 7 ZYXOR: X, Y, Z -axis data overrun. Default value: 0 (0: no overrun has occurred; 1: new data has overwritten the previous one before it was read) + * 6 ZOR: Z axis data overrun. Default value: 0 (0: no overrun has occurred; 1: a new data for the Z-axis has overwritten the previous one) + * 5 YOR: Y axis data overrun. Default value: 0 (0: no overrun has occurred; 1: a new data for the Y-axis has overwritten the previous one) + * 4 XOR: X axis data overrun. Default value: 0 (0: no overrun has occurred; 1: a new data for the X-axis has overwritten the previous one) + * 3 ZYXDA: X, Y, Z -axis new data available. Default value: 0 (0: a new set of data is not yet available; 1: a new set of data is available) + * 2 ZDA: Z axis new data available. Default value: 0 (0: a new data for the Z-axis is not yet available; 1: a new data for the Z-axis is available) + * 1 YDA: Y axis new data available. Default value: 0 (0: a new data for the Y-axis is not yet available;1: a new data for the Y-axis is available) + * 0 XDA: X axis new data available. Default value: 0 (0: a new data for the X-axis is not yet available; 1: a new data for the X-axis is available) + * + * \endcode +*/ +#define L3G_STATUS_REG 0x27 + + +/** + * \brief Gyroscope X-axis angular rate data. LSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 XOUT7-XOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define L3G_OUT_X_L 0x28 + + +/** + * \brief Gyroscope X-axis angular rate data. MSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 XOUT15-XOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define L3G_OUT_X_H 0x29 + + +/** + * \brief Gyroscope Y-axis angular rate data. LSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 YOUT7-YOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define L3G_OUT_Y_L 0x2A + + +/** + * \brief Gyroscope Y-axis angular rate data. MSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 YOUT15-YOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define L3G_OUT_Y_H 0x2B + + +/** + * \brief Gyroscope Z-axis angular rate data. LSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 ZOUT7-ZOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define L3G_OUT_Z_L 0x2C + + +/** + * \brief Gyroscope Z-axis angular rate data. MSB Register. + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:0 ZOUT15-ZOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define L3G_OUT_Z_H 0x2D + + +/** + * \brief Gyroscope FIFO Control Register. + * \code + * Read Write + * Default value: ( The value is expressed as 16bit two’s complement) + * 7:5 FM2-FM0: FIFO mode selection. Default value: 00 + * + * FM2 | FM1 | FM0 | FIFO mode + * ---------------------------------------------------- + * 0 | 0 | 0 | Bypass mode + * 0 | 0 | 1 | FIFO mode + * 0 | 1 | 0 | Stream mode + * 0 | 1 | 1 | Stream-to-FIFO mode + * 1 | 0 | 0 | Bypass-to-Stream mode + * ---------------------------------------------------- + * + * 4-0 WTM4-WTM0: FIFO threshold. Watermark level setting + * + * \endcode + */ +#define L3G_FIFO_CTRL_REG 0x2E + + +/** + * \brief Gyroscope FIFO Source Register. + * \code + * Read + * Default value: output + * 7 WTM: Watermark status. (0: FIFO filling is lower than WTM level; 1: FIFO filling is equal or higher than WTM level) + * 6 OVRN: Overrun bit status. (0: FIFO is not completely filled; 1:FIFO is completely filled) + * 5 EMPTY: FIFO empty bit. (0: FIFO not empty; 1: FIFO empty) + * 4-1 FSS4-FSS1: FIFO stored data level + * + * \endcode + */ +#define L3G_FIFO_SRC_REG 0x2F + + +/** + * \brief Gyroscope Configuration Register for Interrupt 1 source. + * \code + * Read + * Default value: 0x00 + * 7 AND/OR: AND/OR combination of Interrupt events.Default value: 0 (0: OR combination of interrupt events 1: AND combination of interrupt events + * 6 LIR: Latch Interrupt Request. Default value: 0 (0: interrupt request not latched; 1: interrupt request latched) Cleared by reading INT1_SRC reg. + * 5 ZHIE: Enable interrupt generation on Z high event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value higher than preset threshold) + * 4 ZLIE: Enable interrupt generation on Z low event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value lower than preset threshold) + * 3 YHIE: Enable interrupt generation on Y high event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value higher than preset threshold) + * 2 YLIE: Enable interrupt generation on Y low event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value lower than preset threshold) + * 1 XHIE: Enable interrupt generation on X high event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value higher than preset threshold) + * 0 XLIE: Enable interrupt generation on X low event. (0: disable interrupt request; 1: enable interrupt request on measured angular rate value lower than preset threshold) + * + * \endcode + */ +#define L3G_INT1_CFG_REG 0x30 + + +/** + * \brief Gyroscope Interrupt 1 source register. + * \code + * Read + * Default value: output + * 7 0 + * 6 IA : Interrupt active. Default value: 0 (0: no interrupt has been generated; 1: one or more interrupts have been generated) + * 5 ZH: Z high. Default value: 0 (0: no interrupt, 1: Z High event has occurred) + * 4 ZL: Z low. Default value: 0 (0: no interrupt; 1: Z Low event has occurred) + * 3 YH: Y high. Default value: 0 (0: no interrupt, 1: Y High event has occurred) + * 2 YL: Y low. Default value: 0 (0: no interrupt; 1: Y Low event has occurred) + * 1 XH: X high. Default value: 0 (0: no interrupt, 1: X High event has occurred) + * 0 XL: X low. Default value: 0 (0: no interrupt; 1: X Low event has occurred) + * + * \endcode + */ +#define L3G_INT1_SCR_REG 0x31 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on X-axis. MSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7 - + * 6 THSX14-THSX08: Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_THS_XH_REG 0x32 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on X-axis. LSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7-0 THSX7-THSX0 Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_TSH_XL_REG 0x33 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on Y-axis. MSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7 - + * 6 THSY14-THSY08: Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_TSH_YH_REG 0x34 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on Y-axis. LSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7-0 THSY7-THSY0 Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_TSH_YL_REG 0x35 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on Z-axis. MSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7 - + * 6 THSZ14-THSZ08: Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_TSH_ZH_REG 0x36 + + +/** + * \brief Gyroscope Interrupt 1 Threshold on Z-axis. LSB Register. + * \code + * Read Write + * Default value: 0x00 + * 7-0 THSZ7-THSZ0 Interrupt 1 threshold. + * + * \endcode + */ +#define L3G_INT1_TSH_ZL_REG 0x37 + + +/** + * \brief Gyroscope Interrupt 1 Duration Register. + * \code + * Read Write + * Default value: 0x00 + * 7 WAIT: WAIT enable. Default value: 0 (0: disable; 1: enable). Wait =’0’: the interrupt falls immediately if signal crosses the selected threshold; Wait =’1’: if signal crosses the selected threshold, the interrupt falls only after the duration has counted number of samples at the selected data rate, written into the duration counter register. + * 6-0 D6-D0: Duration value (these bits set the minimum duration of the Interrupt event to be recognized. Duration steps and maximum values depend on the ODR chosen.Default value: 000 0000). + * + * \endcode + */ +#define L3G_INT1_DURATION_REG 0x38 + + +/** + * @} + */ + + +/** @defgroup L3GX_Exported_Functions L3Gx Exported Functions + * @{ + */ + +void L3gxConfig(L3GInit *pxL3GInitStruct); +void L3gxGetInfo(L3GInit *pxL3GInitStruct); +void L3gxFilterConfig(L3GFilterInit *pxL3GFilterInitStruct); +void L3gxFilterGetInfo(L3GFilterInit* pxL3GFilterInitStruct); +void L3gxLowpower(GyroPowerMode xPowerMode); +void L3gxSetDataRate(GyroOutputDataRate xDataRate); +GyroOutputDataRate L3gxGetEnumDataRate(void); +void L3gxSetFullScale(GyroFullScale xFullScale); +GyroFullScale L3gxGetEnumFullScale(void); +void L3gxGetSensitivity(float* pfSensitivityXYZ); +void L3gxReboot(void); +void L3gxReadRawData(int16_t* pnRawData); +void L3gxReadAngRate(float* pfData); +void L3gxReadFifo(float* pfData, uint8_t cDataToRead); +L3GDataStatus L3gxGetDataStatus(void); +void L3gxIrq1Config(L3GFunctionalState xNewState); +void L3gxIrq2Config(L3GIrq2List xIrq2Config, L3GFunctionalState xNewState); +void L3gxFifoInit(L3GFifoInit* pxFifoInit); +L3GFifoStatus L3gxFifoGetStatus(void); +void L3gxFifo(L3GFunctionalState xNewState); +void L3gxSetAxisIrqs(L3GIrqOnaxisCombination xIrqCombinations, L3GAxisEvents* pxAxisEvents, L3GFunctionalState xLatched); +L3GFunctionalState L3gxGetAxisIrqs(L3GAxisEvents* pxAxisEvents); +void L3gxSetThreshold(float *pfData); +float L3gxReadTemp(void); + + +/** + * @} + */ + +/** + * @defgroup L3GX_Exported_Macros L3Gx Exported Macros + * @{ + */ + +/** @defgroup L3GX_I2C_Communication L3Gx I2C Communication + * @{ + */ + +#define L3gxByteRead(pVal,cAddress) L3gxBufferRead(pVal,cAddress,1) +#define L3gxByteWrite(pVal,cAddress) L3gxBufferWrite(pVal,cAddress,1) + + +/** + * @} + */ + +/** @defgroup L3GX_L3G4200D L3Gx L3G4200D + * @{ + */ + + +#define L3g4200dConfig L3gxConfig +#define L3g4200dGetInfo L3gxGetInfo +#define L3g4200dFilterConfig L3gxFilterConfig +#define L3g4200dFilterGetInfo L3gxFilterGetInfo +#define L3g4200dLowpower L3gxLowpower +#define L3g4200dSetDataRate L3gxSetDataRate +#define L3g4200dGetEnumDataRate L3gxGetEnumDataRate +#define L3g4200dSetFullScale L3gxSetFullScale +#define L3g4200dGetEnumFullScale L3gxGetEnumFullScale +#define L3g4200dGetSensitivity L3gxGetSensitivity +#define L3g4200dReboot L3gxReboot +#define L3g4200dReadRawData L3gxReadRawData +#define L3g4200dReadAngRate L3gxReadAngRate +#define L3g4200dReadFifo L3gxReadFifo +#define L3g4200dGetDataStatus L3gxGetDataStatus +#define L3g4200dIrq1Config L3gxIrq1Config +#define L3g4200dIrq2Config L3gxIrq2Config +#define L3g4200dFifoInit L3gxFifoInit +#define L3g4200dFifoGetStatus L3gxFifoGetStatus +#define L3g4200dFifo L3gxFifo +#define L3g4200dSetAxisIrqs L3gxSetAxisIrqs +#define L3g4200dGetAxisIrqs L3gxGetAxisIrqs +#define L3g4200dSetThreshold L3gxSetThreshold +#define L3g4200dReadTemp L3gxReadTemp + + +/** + *@} + */ + +/** @defgroup L3GX_L3GD20 L3Gx L3GD20 + * @{ + */ + + +#define L3gd20Config L3gxConfig +#define L3gd20GetInfo L3gxGetInfo +#define L3gd20FilterConfig L3gxFilterConfig +#define L3gd20FilterGetInfo L3gxFilterGetInfo +#define L3gd20Lowpower L3gxLowpower +#define L3gd20SetDataRate L3gxSetDataRate +#define L3gd20GetEnumDataRate L3gxGetEnumDataRate +#define L3gd20SetFullScale L3gxSetFullScale +#define L3gd20GetEnumFullScale L3gxGetEnumFullScale +#define L3gd20GetSensitivity L3gxGetSensitivity +#define L3gd20Reboot L3gxReboot +#define L3gd20ReadRawData L3gxReadRawData +#define L3gd20ReadAngRate L3gxReadAngRate +#define L3gd20ReadFifo L3gxReadFifo +#define L3gd20GetDataStatus L3gxGetDataStatus +#define L3gd20Irq1Config L3gxIrq1Config +#define L3gd20Irq2Config L3gxIrq2Config +#define L3gd20FifoInit L3gxFifoInit +#define L3gd20FifoGetStatus L3gxFifoGetStatus +#define L3gd20Fifo L3gxFifo +#define L3gd20SetAxisIrqs L3gxSetAxisIrqs +#define L3gd20GetAxisIrqs L3gxGetAxisIrqs +#define L3gd20SetThreshold L3gxSetThreshold +#define L3gd20ReadTemp L3gxReadTemp + + +/** + *@} + */ + +/** + *@} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/lib/L3Gx/src/L3Gx.c b/lib/L3Gx/src/L3Gx.c new file mode 100755 index 0000000..ff15367 --- /dev/null +++ b/lib/L3Gx/src/L3Gx.c @@ -0,0 +1,794 @@ +/** + * @file L3GX.c + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief This file provides a set of functions needed to manage the L3Gx slave. + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +#include "L3Gx.h" + +#include + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + + +/** +* @defgroup L3Gx +* @{ +*/ + + +/** + * @defgroup L3GX_Private_TypesDefinitions L3Gx Private TypesDefinitions + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup L3GX_Private_Defines L3Gx Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup L3GX_Private_Macros L3Gx Private Macros + * @{ + */ + +#define L3G_ABS(a) (a>0?(a):-(a)) + +/** + *@} + */ + + +/** + * @defgroup L3GX_Private_FunctionPrototypes L3Gx Private FunctionPrototypes + * @{ + */ + +/** + *@} + */ + + +/** +* @defgroup L3GX_Private_Functions L3Gx Private Functions +* @{ +*/ + + +/** +* @brief Set configuration of angular rate of L3GX pointer to a L3GInit structure that contains +* the configuration setting for the L3GX. +* @param pxL3GInitStruct : pointer to a L3GInit structure that contains the configuration setting. +* This parameter is a pointer to @ref L3GInit . +* @retval None. +* @details +* Example: +* @code +* L3GInit L3GInitStructure; +* +* L3GInitStructure.xPowerMode = L3G_NORMAL_SLEEP_MODE; +* L3GInitStructure.xOutputDataRate = L3G_ODR_100_HZ_CUTOFF_12_5; +* L3GInitStructure.xEnabledAxes = L3G_ALL_AXES_EN; +* L3GInitStructure.xFullScale = L3G_FS_500_DPS; +* L3GInitStructure.xDataUpdate = L3G_CONTINUOS_UPDATE; +* L3GInitStructure.xEndianness = L3G_LITTLE_ENDIAN; +* +* L3gxConfig(&L3GInitStructure); +* @endcode +*/ +void L3gxConfig(L3GInit *pxL3GInitStruct) +{ + uint8_t CTRL1 = 0x00, CTRL4 = 0x00; + + CTRL1 |= ((uint8_t)pxL3GInitStruct->xPowerMode | (uint8_t)pxL3GInitStruct->xOutputDataRate | (uint8_t)pxL3GInitStruct->xEnabledAxes); + CTRL4 |= ((uint8_t)pxL3GInitStruct->xFullScale | (uint8_t)pxL3GInitStruct->xDataUpdate | (uint8_t)pxL3GInitStruct->xEndianness); + + L3gxByteWrite(&CTRL1,L3G_CTRL_REG1); + L3gxByteWrite(&CTRL4,L3G_CTRL_REG4); + +} + + +/** +* @brief Gets the general configuration of L3GX for the magnetometer. +* @param pxL3GInitStruct : pointer to a L3GInit structure that will +* contain the configuration setting read from the L3GX registers. +* @retval None +*/ +void L3gxGetInfo(L3GInit *pxL3GInitStruct) +{ + uint8_t CTRL1, CTRL4; + + /* Read the registers content */ + L3gxByteRead(&CTRL4, L3G_CTRL_REG4); + L3gxByteRead(&CTRL1, L3G_CTRL_REG1); + + /* Fill the structure fields from CTRL1 reg info */ + pxL3GInitStruct->xPowerMode = (GyroPowerMode)(CTRL1 & 0x08); + pxL3GInitStruct->xOutputDataRate = (GyroOutputDataRate)(CTRL1 & 0xF0); + pxL3GInitStruct->xEnabledAxes = (GyroAxesEnabling)(CTRL1 & 0x07); + + /* Fill the structure fields from CTRL4 reg info */ + pxL3GInitStruct->xFullScale = (GyroFullScale)(CTRL4 & 0x30); + pxL3GInitStruct->xDataUpdate = (GyroBlockDataUpdate)(CTRL4 & 0x80); + pxL3GInitStruct->xEndianness = (GyroEndianness)(CTRL4 & 0x40); + +} + + +/** +* @brief Set configuration of angular rate of L3GX pointer to a L3GFilterInit structure +* that contains the filter configuration setting for the L3GX. +* @param pxL3GFilterInitStruct: pointer to a L3GInit structure that contains the filter configuration setting. +* This parameter is a pointer to @ref L3GFilterInit . +* @retval None. +* @details +* Example: +* @code +* L3GFilterInit FilterInitStr; +* +* FilterInitStr.xHPF = L3G_NORMAL_SLEEP_MODE; +* FilterInitStr.cHPFCutOff = 5; +* FilterInitStr.xHPF_Mode = L3G_HPFM_NORMAL; +* FilterInitStr.cHPFReference = 0; +* +* L3gxFilterConfig(&FilterInitStr); +* @endcode +*/ +void L3gxFilterConfig(L3GFilterInit *pxL3GFilterInitStruct) +{ + uint8_t CTRL2 = 0x00, CTRL5 = 0x00; + + L3gxByteRead(&CTRL5,L3G_CTRL_REG5); + if(pxL3GFilterInitStruct->xHPF == L3G_ENABLE) + { + CTRL5 |= 0x10; + } + else + { + CTRL5 &= 0xCF; + } + + CTRL2 |= (uint8_t)(pxL3GFilterInitStruct->xHPF_Mode | pxL3GFilterInitStruct->cHPFCutOff); + + L3gxByteWrite(&CTRL5,L3G_CTRL_REG5); + L3gxByteWrite(&CTRL2,L3G_CTRL_REG2); + L3gxByteWrite(&pxL3GFilterInitStruct->cHPFReference,L3G_REFERENCE); +} + +/** +* @brief Get configuration of Internal High Pass Filter of L3GX for the linear acceleration +* @param L3GFilterInit : pointer to a L3GFilterInit structure that will +* contain the configuration setting read from the L3GX registers. +* @retval None +*/ +void L3gxFilterGetInfo(L3GFilterInit* pxL3GFilterInitStruct) +{ + uint8_t CTRL2 = 0x00, CTRL5 = 0x00; + + /* Read the sensor registers */ + L3gxByteRead(&CTRL5,L3G_CTRL_REG5); + L3gxByteRead(&CTRL2,L3G_CTRL_REG2); + + /* check if enabled */ + if(CTRL5 & 0x10) + pxL3GFilterInitStruct->xHPF=L3G_ENABLE; + else + pxL3GFilterInitStruct->xHPF=L3G_DISABLE; + + /* Get mode and cutoff */ + pxL3GFilterInitStruct->xHPF_Mode = (GyroHPFMode)(CTRL2 & 0x30); + pxL3GFilterInitStruct->cHPFCutOff = (CTRL2 & 0x0F); + + /* Get reference */ + L3gxByteRead(&pxL3GFilterInitStruct->cHPFReference,L3G_REFERENCE); +} + + +/** +* @brief Set the L3GX Power Mode. +* @param xPowerMode: Power Mode selection. +* This parameter is a value of @ref GyroPowerMode . +* @retval None. +*/ +void L3gxLowpower(GyroPowerMode xPowerMode) +{ + uint8_t tmpreg; + L3gxByteRead(&tmpreg,L3G_CTRL_REG1); + tmpreg &= 0xF7; + + tmpreg |= (uint8_t) xPowerMode; + L3gxByteWrite(&tmpreg,L3G_CTRL_REG1); +} + + +/** +* @brief Set the L3GX Data Rate. +* @param xDataRate: Datarate value. +* This parameter can be any value of @ref GyroOutputDataRate . +* @retval None. +*/ +void L3gxSetDataRate(GyroOutputDataRate xDataRate) +{ + uint8_t tmpreg; + + /* Read the register value */ + L3gxByteRead(&tmpreg,L3G_CTRL_REG1); + + /* mask and set it */ + tmpreg &= 0x0F; + tmpreg |= (uint8_t)xDataRate; + + /* write value on the register */ + L3gxByteWrite(&tmpreg,L3G_CTRL_REG1); + +} + + +/** +* @brief Returns the output data rate as a GyroOutputDataRate enumerative value. +* @param None. +* @retval GyroOutputDataRate: GyroOutputDataRate enumerative value. +*/ +GyroOutputDataRate L3gxGetEnumDataRate(void) +{ + uint8_t tmpReg; + + /* Read the register value */ + L3gxByteRead(&tmpReg,L3G_CTRL_REG1); + + /* return the masked value */ + return ((GyroOutputDataRate)(tmpReg & 0xF0)); + +} + + +/** +* @brief Set the L3GX Full Scale register +* @param xFullScale: new full scale value. +* This parameter can be any value of @ref GyroFullScale . +* @retval None. +*/ +void L3gxSetFullScale(GyroFullScale xFullScale) +{ + uint8_t tmpreg; + + /* Read the register value */ + L3gxByteRead(&tmpreg,L3G_CTRL_REG4); + + /* mask and set it */ + tmpreg &= 0xCF; + tmpreg |= (uint8_t)xFullScale; + + /* write value on the register */ + L3gxByteWrite(&tmpreg,L3G_CTRL_REG4); +} + + + +/** +* @brief Returns the full scale as a GyroFullScale enumerative value. +* @param None. +* @retval GyroFullScale: GyroFullScale enumerative value. +*/ +GyroFullScale L3gxGetEnumFullScale(void) +{ + uint8_t tmpReg; + + /* Read the register value */ + L3gxByteRead(&tmpReg,L3G_CTRL_REG4); + + /* return the masked value */ + return ((GyroFullScale)(tmpReg & 0x30)); +} + + + +/** +* @brief Returns the Full Scale of Gyro expressed in LSB/dps. +* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored. +* This parameter is a pointer to a float array. +* @retval None. +*/ +void L3gxGetSensitivity(float *pfSensitivityXYZ) +{ + uint8_t tmpReg; + + /* Read the register content */ + L3gxByteRead(&tmpReg,L3G_CTRL_REG4); + tmpReg &= 0x30; + + /* return the correspondent value */ + switch(tmpReg) + { + case L3G_FS_250_DPS: + pfSensitivityXYZ[0]=L3G_Sensitivity_250dps; + pfSensitivityXYZ[1]=L3G_Sensitivity_250dps; + pfSensitivityXYZ[2]=L3G_Sensitivity_250dps; + + break; + case L3G_FS_500_DPS: + pfSensitivityXYZ[0]=L3G_Sensitivity_500dps; + pfSensitivityXYZ[1]=L3G_Sensitivity_500dps; + pfSensitivityXYZ[2]=L3G_Sensitivity_500dps; + + break; + case L3G_FS_2000_DPS: + pfSensitivityXYZ[0]=L3G_Sensitivity_2000dps; + pfSensitivityXYZ[1]=L3G_Sensitivity_2000dps; + pfSensitivityXYZ[2]=L3G_Sensitivity_2000dps; + + break; + } + + +} + +/** +* @brief Reboots the L3GX. +* @param None. +* @retval None. +*/ +void L3gxReboot(void) +{ + uint8_t tmpreg, value; + L3gxByteRead(&tmpreg,L3G_CTRL_REG5); + + /* Take memory of the register content */ + tmpreg &= 0x7F; + + /* Put the BOOT field to 1 and make the reboot */ + value = 0x80; + L3gxByteWrite(&value,L3G_CTRL_REG5); + /* Rewrite the old content of the register */ + L3gxByteWrite(&tmpreg,L3G_CTRL_REG5); +} + + + +/** +* @brief Read L3GX output register, and calculate the raw angular +* rate [LSB] AngRate= (out_h*256+out_l)/16 (12 bit rappresentation) +* @param pnRawData: pointer to the uint16_t array where the read data must be stored. +* @retval None. +*/ +void L3gxReadRawData(int16_t* pnRawData) +{ + int i; + uint8_t buffer[6]; + uint8_t reg; + L3gxByteRead(®,L3G_CTRL_REG4); + L3gxBufferRead(buffer,L3G_OUT_X_L, 6); + + /* check in the control register 4 the data alignment (Big Endian or Little Endian)*/ + if(!(reg & 0x40)) + { + for(i=0; i<3; i++) + pnRawData[i]=(int16_t)(((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]); + } + else + { + for(i=0; i<3; i++) + pnRawData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]); + } +} + + +/** +* @brief Read L3GX output register, and calculate the angular rate expressed in dps. +* @param pfData: pointer to the uint16_t array where the read data must be stored. +* @retval None. +*/ +void L3gxReadAngRate(float* pfData) +{ + int16_t buffer[3]; + uint8_t reg; + float fSensitivity = 0.0f; + //BoardConsolePrintf("Sensitivity : %2.4f\n", fSensitivity); + + /* read the register values */ + L3gxReadRawData(buffer); + L3gxByteRead(®,L3G_CTRL_REG4); + + /* switch the sensitivity value set in the CRTL4 */ + switch(reg & 0x30) + { + case 0x00: + fSensitivity=L3G_Sensitivity_250dps; + break; + + case 0x10: + fSensitivity=L3G_Sensitivity_500dps; + break; + + case 0x30: + fSensitivity=L3G_Sensitivity_2000dps; + break; + } + + //BoardConsolePrintf("So...\n"); + + //BoardConsolePrintf("Sensitivity : %2.4f\n", fSensitivity); + + /* divide by sensitivity */ + uint8_t i; + for(i=0; i<3; i++) + { + //BoardConsolePrintf("value=%02x\n", buffer[i]); + pfData[i]=(float)buffer[i]; + //BoardConsolePrintf("data=%2.4f\n", pfData[i]); + pfData[i]/=fSensitivity; + //BoardConsolePrintf("newdata=%2.4f\n", pfData[i]); + } + +} + + +/** +* @brief Read L3GX output register when FIFO mode is active. +* @param pfData: pointer to float buffer where to store data. +* This parameter is a float array pointer. +* @param cDataToRead: number of samples to read. Each sample is made up of the three axis readings. +* This parameter is an uint8_t . +* @retval None +*/ +void L3gxReadFifo(float* pfData, uint8_t cDataToRead) +{ + uint8_t *pcBuffer=(uint8_t*)pfData; + uint8_t j=0,reg; + float fSensitivity = 0.0; + uint16_t aux; + + L3gxByteRead(®,L3G_CTRL_REG4); + + /* switch the sensitivity value set in the CRTL4 */ + switch(reg & 0x30) + { + case 0x00: + fSensitivity=L3G_Sensitivity_250dps; + break; + + case 0x10: + fSensitivity=L3G_Sensitivity_500dps; + break; + + case 0x30: + fSensitivity=L3G_Sensitivity_2000dps; + break; + } + + /* Read the register content */ + L3gxBufferRead(pcBuffer, L3G_OUT_X_L, cDataToRead*6); + + /* convert all data to float */ + uint16_t i; + for(i=0 ; iExample: +* @code +* ... +* ExtiConfiguration(); // set the micro exti before init +* L3gxIrq2Config(L3G_I2_DRDY,L3G_ENABLE); // for example enable the data_ready IRQ +* ... +* @endcode +*/ +void L3gxIrq2Config(L3GIrq2List xIrq2Config, L3GFunctionalState xNewState) +{ + uint8_t tempReg; + + /* Read the register content */ + L3gxByteRead(&tempReg, L3G_CTRL_REG3); + + /* Unmask the selected IRQ */ + if(xNewState) + tempReg |= (uint8_t)xIrq2Config; + else + tempReg &= ~(uint8_t)xIrq2Config; + + /* Write byte on register */ + L3gxByteWrite(&tempReg, L3G_CTRL_REG3); + +} + + +/** +* @brief Configures the sensor FIFO. +* @param L3GFifoInit: pointer to the Fifo initialization structure. +* This parameter is a pointer to a @ref L3GFifoInit. +* @note This function won't enable the FIFO. Please call the @ref Lsm303dlhcAccFifo in order to enable this mode. +* @retval None +*/ +void L3gxFifoInit(L3GFifoInit* pxFifoInit) +{ + /* Built the byte to be written */ + uint8_t tempReg = (pxFifoInit->xFifoMode | (pxFifoInit->cWtm & 0x1F)); + + /* Write the built value on the FIFO_CTRL register */ + L3gxByteWrite(&tempReg, L3G_FIFO_CTRL_REG); + +} + + +/** +* @brief Configures the sensor FIFO. +* @param xNewState: New state for the FIFO use. +* This parameter is a pointer to a @ref L3gxFifo +* @retval None +*/ +void L3gxFifo(L3GFunctionalState xNewState) +{ + /* Built the byte to be written */ + uint8_t tempReg; + + /* Read the value on the CTRL5 register */ + L3gxByteRead(&tempReg, L3G_CTRL_REG5); + + /* Build the value to write */ + if(xNewState == L3G_ENABLE) + tempReg |= 0x40; + else + tempReg &= (~0x40); + + /* Write the built value on the CTRL5 register */ + L3gxByteWrite(&tempReg, L3G_CTRL_REG5); + +} + + +/** +* @brief Gets the FIFO status flags and unread data. +* @param None. +* @retval L3GFifoStatus Fifo status descriptor. +*/ +L3GFifoStatus L3gxFifoGetStatus(void) +{ + L3GFifoStatus xL3GFifoStatus; + + /* Read the register content */ + L3gxByteRead((uint8_t*)&xL3GFifoStatus, L3G_FIFO_SRC_REG); + + /* Return its value */ + return xL3GFifoStatus; + +} + + +/** +* @brief Sets the IRQs on Axis. +* @param xIrqCombinations: Combination of events on axis. +* This parameter is a @ref L3GIrqOnaxisCombination . +* @param pxAxisEvents: Events on axis structure. +* This parameter is a pointer to a @ref L3GAxisEvents . +* @param xLatched: Latched interrupt. +* This parameter can be L3G_ENABLE or L3G_DISABLE . +* @retval None +* @details +* Example: +* @code +* L3GAxisEvents xAxisEvents; +* +* xAxisEvents.X_LOW=0; +* xAxisEvents.X_HIGH=0; +* xAxisEvents.Y_LOW=1; +* xAxisEvents.Y_HIGH=0; +* xAxisEvents.Z_LOW=0; +* xAxisEvents.Z_HIGH=1; +* +* L3gxSetAxisIrqs(L3G_OR_COMBINATION,&xAxisEvents,L3G_DISABLE); +* @endcode +*/ +void L3gxSetAxisIrqs(L3GIrqOnaxisCombination xIrqCombinations, L3GAxisEvents* pxAxisEvents, L3GFunctionalState xLatched) +{ + /* Build the value to build on register */ + uint8_t tempReg = ((uint8_t)xIrqCombinations) | (*(uint8_t*)pxAxisEvents); + + /* if required, set the IRQ latched bit */ + if(xLatched) + tempReg |= 0x40; + + /* Write the built value on the irq1 configuration register */ + L3gxByteWrite(&tempReg, L3G_INT1_CFG_REG); + +} + + +/** +* @brief Gets the IRQs on Axis status. +* @param pxAxisEvents: Events on axis structure. +* This parameter is a pointer to a @ref L3GAxisEvents . +* @retval None +*/ +L3GFunctionalState L3gxGetAxisIrqs(L3GAxisEvents* pxAxisEvents) +{ + uint8_t tempReg; + + /* Read register */ + L3gxByteRead(&tempReg, L3G_INT1_SCR_REG); + + uint8_t tempRet = tempReg & 0x3F; + + /* Take the MSb to return */ + (*pxAxisEvents)=*(L3GAxisEvents*)(&tempRet); + + return (L3GFunctionalState)((tempReg & 0x40)>>6); + +} + + +/** +* @brief Sets threshold for the angular rate. +* @param pfData: Angular rate threshold ordered by axis (XYZ) and expressed in dps. +* This parameter is a float array. +* @retval None +*/ +void L3gxSetThreshold(float *pfData) +{ + uint8_t reg, j=0, pcData[6]; + float fSensitivity = 0.0, aux; + int16_t pnData[3]; + + /* X and Y thresholds and flags are inverted.. here a workaround */ + aux=pfData[1]; + pfData[1]=pfData[0]; + pfData[0]=aux; + + /* Read the CTRL4 register */ + L3gxByteRead(®,L3G_CTRL_REG4); + + /* switch the sensitivity value set in the CRTL4 + (00: 250 dps; 01: 500 dps; 10: 2000 dps; 11: 2000 dps) + */ + switch(reg & 0x30) + { + case 0x00: + fSensitivity=L3G_Sensitivity_250dps; + break; + + case 0x10: + fSensitivity=L3G_Sensitivity_500dps; + break; + + case 0x20: case 0x30: + fSensitivity=L3G_Sensitivity_2000dps; + break; + } + + /* Convert the dps values in register values */ + uint8_t i; + for(i=0;i<3;i++) + { + pnData[i] = (int16_t)(pfData[i]*fSensitivity); + + pcData[j++] = (uint8_t)(pnData[i]>>8); + pcData[j++] = (uint8_t)pnData[i]; + } + + /* Write the values on registers */ + L3gxBufferWrite(pcData,L3G_INT1_THS_XH_REG,6); + + +} + + +/** +* @brief Read L3G4300D temperature output register. +* @param None. +* @retval float: Temperature (C/LSB). +*/ +float L3gxReadTemp(void) +{ + int8_t buffer; + + /* Read register */ + L3gxByteRead((uint8_t*)&buffer, L3G_OUT_TEMP); + + /* convert to float */ + return (float)buffer; + +} + + +/** +*@} +*/ + + +/** + * @} + */ + + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/lib/L3Gx/src/L3Gx.dep b/lib/L3Gx/src/L3Gx.dep new file mode 100644 index 0000000..a05f898 --- /dev/null +++ b/lib/L3Gx/src/L3Gx.dep @@ -0,0 +1,12 @@ +L3Gx/src/L3Gx.o: L3Gx/src/L3Gx.c \ + /Users/tom/Documents/src/multitouchglove/lib/L3Gx/inc/L3Gx.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdint.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdint-gcc.h \ + /Users/tom/Documents/src/multitouchglove/lib/HAL_L3Gx.h \ + /Users/tom/Documents/src/multitouchglove/lib/spi.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Core/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/src/CM3/CoreSupport/core_cm3.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Core/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/config/arm/stm32f10/stm32f10x_conf.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/inemo/BoardConsole.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdarg.h diff --git a/lib/LPS331AP/inc/LPS331AP.h b/lib/LPS331AP/inc/LPS331AP.h new file mode 100755 index 0000000..2add89f --- /dev/null +++ b/lib/LPS331AP/inc/LPS331AP.h @@ -0,0 +1,639 @@ +/** + * @file LSM303DLHC.h + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief Header for LPS331AP.c file + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __LPS331AP_H +#define __LPS331AP_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "HAL_LPS331AP.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + +/** + * @defgroup LPS331AP + * @brief This module contains all the functions to configure the LPS331AP pressure sensor. + * @details + * Since this code is platform independent an implementation of the SPI or I2C driver must + * be provided by the user according to the used platform. + * Every function makes use of the Lps331apBufferRead and/or Lps331apBufferWrite + * as low level functions to write bytes through the used digital interface. + * In order to link and use this code the user should define and export these functions in a header + * file called "HAL_LPS331AP.h" (included by this module). + * + * @{ + */ + +/** + * @defgroup LPS331AP_Exported_Types LPS331AP Exported Types + * @{ + */ + +/** + * @brief LPS331AP Functional state. Used to enable or disable a specific option. + */ +typedef enum +{ + LPS_DISABLE = 0, + LPS_ENABLE = !LPS_DISABLE +}LPSFunctionalState; + + +/** + * @brief Pressure Flag status. Used to set/reset the sensor flags. + */ +typedef enum +{ + LPS_RESET = 0, + LPS_SET = !LPS_RESET +}LPSFlagStatus; + + +/** + * @brief LPS331AP Output Data Rate + */ +typedef enum +{ + ODR_P_T_ONE_SHOT = 0x00, /*!< Output Data Rate: P - one shot, T - one shot */ + ODR_P_1HZ_T_1HZ = 0x10, /*!< Output Data Rate: P - 1Hz, T - 1Hz */ + ODR_P_7HZ_T_1HZ = 0x20, /*!< Output Data Rate: P - 7Hz, T - 1Hz */ + ODR_P_12_5HZ_T_1HZ = 0x30, /*!< Output Data Rate: P - 12.5Hz, T - 1Hz */ + ODR_P_25HZ_T_1HZ = 0x40, /*!< Output Data Rate: P - 25Hz, T - 1Hz */ + ODR_P_7HZ_T_7HZ = 0x50, /*!< Output Data Rate: P - 7Hz, T - 7Hz */ + ODR_P_12_5HZ_T_12_5HZ = 0x60, /*!< Output Data Rate: P - 12.5Hz, T - 12.5Hz */ + ODR_P_25HZ_T_25HZ = 0x70, /*!< Output Data Rate: P - 25Hz, T - 25Hz */ +}LPSOutputDataRate; + + +/** + * @brief LPS331AP Pressure resolution + */ +typedef enum +{ + LPS_PRESS_AVG_1 = 0x00, /*!< Internal average on 1 sample */ + LPS_PRESS_AVG_2 = 0x01, /*!< Internal average on 2 sample */ + LPS_PRESS_AVG_4 = 0x02, /*!< Internal average on 4 sample */ + LPS_PRESS_AVG_8 = 0x03, /*!< Internal average on 8 sample */ + LPS_PRESS_AVG_16 = 0x04, /*!< Internal average on 16 sample */ + LPS_PRESS_AVG_32 = 0x05, /*!< Internal average on 32 sample */ + LPS_PRESS_AVG_64 = 0x06, /*!< Internal average on 64 sample */ + LPS_PRESS_AVG_128 = 0x07, /*!< Internal average on 128 sample */ + LPS_PRESS_AVG_256 = 0x08, /*!< Internal average on 256 sample */ + LPS_PRESS_AVG_384 = 0x09, /*!< Internal average on 384 sample */ + LPS_PRESS_AVG_512 = 0x0A, /*!< Internal average on 512 sample */ +}LPSPressureResolution; + + +/** + * @brief LPS331AP Temperature resolution + */ +typedef enum +{ + LPS_TEMP_AVG_1 = 0x00, /*!< Internal average on 1 sample */ + LPS_TEMP_AVG_2 = 0x10, /*!< Internal average on 2 sample */ + LPS_TEMP_AVG_4 = 0x20, /*!< Internal average on 4 sample */ + LPS_TEMP_AVG_8 = 0x30, /*!< Internal average on 8 sample */ + LPS_TEMP_AVG_16 = 0x40, /*!< Internal average on 16 sample */ + LPS_TEMP_AVG_32 = 0x50, /*!< Internal average on 32 sample */ + LPS_TEMP_AVG_64 = 0x60, /*!< Internal average on 64 sample */ + LPS_TEMP_AVG_128 = 0x70, /*!< Internal average on 128 sample */ +}LPSTemperatureResolution; + + + +/** + * @brief LPS331AP Irq list + */ +typedef enum +{ + LPS_GND = 0x00, + LPS_P_HIGH = 0x01, + LPS_P_LOW = 0x02, + LPS_P_LOW_HIGH = 0x03, + LPS_DATA_READY = 0x04, + LPS_TRISTATE = 0x07, +}LPSIrqList; + + +/** + * @brief LPS331AP Irq pin output configuration + */ +typedef enum +{ + LPS_PP = 0x00, + LPS_OD = 0x40 +}LPSOutputType; + + +/** + * @brief Pressure sensor Irq initialization structure + */ +typedef struct +{ + LPSFunctionalState xIrqActiveLow; + LPSOutputType xOutType; + LPSIrqList xInt1List; + LPSIrqList xInt2List; + float fPressThr; + LPSFunctionalState xIrqPressLow; + LPSFunctionalState xIrqPressHigh; +}LPSIrqInit; + + +/** + * @brief Pressure sensor Init structure definition + */ +typedef struct +{ + LPSOutputDataRate xOutputDataRate; /*!< Output Data Rate */ + LPSPressureResolution xPresRes; /*!< Pressure sensor resolution */ + LPSTemperatureResolution xTempRes; /*!< Temperature sensor resolution */ + LPSFunctionalState xPressureAutoZero; /*!< Auto zero feature enabled */ + float fPressureRef; /*!< Pressure sensor reference value */ + LPSFunctionalState xBDU; /*!< Auto zero feature enabled */ +}LPS331Init; + + +/** + * @brief Pressure sensor data status structure structure + */ +typedef struct +{ + LPSFlagStatus cTempDataAvailable:1; /*!< Temperature data available bit */ + LPSFlagStatus cPressDataAvailable:1; /*!< Pressure data available bit */ + uint8_t :2; /*!< 2 bits padding */ + LPSFlagStatus cTempDataOverrun:1; /*!< Temperature data over-run bit */ + LPSFlagStatus cPressDataOverrun:1; /*!< Pressure data over-run bit */ + uint8_t :2; /*!< 2 bits padding */ +}LPS331DataStatus; + + +/** + * @} + */ + +/** + * @defgroup LPS331AP_Exported_Constants LPS331AP Exported Constants + * @{ + */ + + +/** + * @} + */ + +/** + * @defgroup LPS331AP_Exported_Macros LPS331AP Exported Macros + * @{ + */ + +/** +* @brief Read LPS331AP output register, and calculate the pressure in mbar. +* @param None. +* @retval float: pressure expressed in mbar. +*/ +#define Lps331apReadPressure() ((float)Lps331apReadRawPressure()/4096) + + +/** +* @brief Read LPS331AP output register, and calculate the temperature in C deg. +* @param None. +* @retval float: temperature expressed in C deg. +*/ +#define Lps331apReadTemperature() ((float)Lps331apReadRawTemperature()/480.0+42.5) + + +/** @defgroup LPS331AP_Communication LPS331AP Communication + * @{ + */ + +#define Lps331apByteRead(pVal,cAddress) Lps331apBufferRead(pVal,cAddress,1) +#define Lps331apByteWrite(pVal,cAddress) Lps331apBufferWrite(pVal,cAddress,1) + + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup LPS331AP_Register_Mapping LPS331AP Register Mapping + * @{ + */ + +/** + * @brief Reference pressure (LSB data) + * \code + * Read/write + * Default value: 0x00 + * 7:0 REF7-ODR0: Lower part of the reference pressure that + * is sum to the sensor output pressure. + * \endcode + */ +#define LPS_REF_P_XL_ADDR 0x08 + + +/** + * @brief Reference pressure (middle part) + * \code + * Read/write + * Default value: 0x00 + * 7:0 REF15-ODR8: Middle part of the reference pressure that + * is sum to the sensor output pressure. + * \endcode + */ +#define LPS_REF_P_L_ADDR 0x09 + + +/** + * @brief Reference pressure (MSB part) + * \code + * Read/write + * Default value: 0x00 + * 7:0 REF15-ODR8: Higher part of the reference pressure that + * is sum to the sensor output pressure. + * \endcode + */ +#define LPS_REF_P_H_ADDR 0x0A + + +/** + * @brief Device identifier register. + * \code + * Read + * Default value: 0xBB + * 7:0 This read-only register contains the device identifier that, for LPS331AP, is set to BBh. + * \endcode + */ +#define LPS_WHO_AM_I_ADDR 0x0F + + +/** + * @brief Pressure resolution Register + * \code + * Read/write + * Default value: 0x7A + * 7 RFU + * 6:4 AVGT2-AVGT0: temperature internal average. + * AVGT2 | AVGT1 | AVGT0 | Nr. Internal Average + * ------------------------------------------------------ + * 0 | 0 | 0 | 1 + * 0 | 0 | 1 | 2 + * 0 | 1 | 0 | 4 + * 0 | 1 | 1 | 8 + * 1 | 0 | 0 | 16 + * 1 | 0 | 1 | 32 + * 1 | 1 | 0 | 64 + * 1 | 1 | 1 | 128 + * + * 3:0 AVGP3-AVGP0: pressure internal average. + * AVGP3 | AVGP2 | AVGP1 | AVGP0 | Nr. Internal Average + * ------------------------------------------------------ + * 0 | 0 | 0 | 0 | 1 + * 0 | 0 | 0 | 1 | 2 + * 0 | 0 | 1 | 0 | 4 + * 0 | 0 | 1 | 1 | 8 + * 0 | 1 | 0 | 0 | 16 + * 0 | 1 | 0 | 1 | 32 + * 0 | 1 | 1 | 0 | 64 + * 0 | 1 | 1 | 1 | 128 + * 1 | 0 | 0 | 0 | 256 + * 1 | 0 | 0 | 1 | 384 + * 1 | 0 | 1 | 0 | 512 + * + * \endcode + */ +#define LPS_RES_CONF_ADDR 0x10 + + + + +/** + * @brief Pressure sensor control register 1 + * \code + * Read/write + * Default value: 0x00 + * 7 PD: power down control. 0 - disable; 1 - enable + * 6:4 ODR2, ODR1, ODR0: output data rate selection. + * ODR2 | ODR1 | ODR0 | Pressure output data-rate(Hz) | Temperature output data-rate(Hz) + * ---------------------------------------------------------------------------------- + * 0 | 0 | 0 | one shot | one shot + * 0 | 0 | 1 | 1 | 1 + * 0 | 1 | 0 | 7 | 1 + * 0 | 1 | 1 | 12.5 | 1 + * 1 | 0 | 0 | 25 | 1 + * 1 | 0 | 1 | 7 | 7 + * 1 | 1 | 0 | 12.5 | 12.5 + * 1 | 1 | 1 | 25 | 25 + * + * 3 DIFF_EN: Interrupt circuit. 0 - disable; 1 - enable + * 2 BDU: block data update. 0 - disable; 1 - enable + * 1 DELTA_EN: delta pressure. 0 - disable; 1 - enable + * 0 SIM: SPI Serial Interface Mode selection. 0 - disable; 1 - enable + * \endcode + */ +#define LPS_CTRL_REG1_ADDR 0x20 + + +/** + * @brief Pressure sensor control register 2 + * \code + * Read/write + * Default value: 0x00 + * 7 BOOT: Reboot memory content. 0: normal mode; 1: reboot memory content + * 6:3 Reserved. + * 2 SWRESET: Software reset. 0: normal mode; 1: SW reset. + * 1 AUTO_ZERO: Autozero enable. 0: normal mode; 1: autozero enable. + * 0 ONE_SHOT: One shot enable. 0: waiting for start of conversion; 1: start for a new dataset + * \endcode + */ +#define LPS_CTRL_REG2_ADDR 0x21 + + +/** + * @brief Pressure sensor control register 3 + * \code + * Read/write + * Default value: 0x00 + * 7 INT_H_L: Interrupt active high, low. + * 6 PP_OD: Push-pull/open drain selection on interrupt pads. + * 5:3 INT2_S3, INT2_S2, INT2_S1: data signal on INT2 pad control bits. + * 2:0 INT1_S3, INT1_S2, INT1_S1: data signal on INT1 pad control bits. + * INT1(2)_S3 | INT1(2)_S2 | INT1(2)_S1 | INT1(2) pin + * ------------------------------------------------------ + * 0 | 0 | 0 | GND + * 0 | 0 | 1 | Pressure high (P_high) + * 0 | 1 | 0 | Pressure low (P_low) + * 0 | 1 | 1 | P_low OR P_high + * 1 | 0 | 0 | Data ready + * 1 | 0 | 1 | Reserved + * 1 | 1 | 0 | Reserved + * 1 | 1 | 1 | Tri-state + + * \endcode + */ +#define LPS_CTRL_REG3_ADDR 0x22 + + +/** + * @brief Interrupt configuration Register + * \code + * Read/write + * Default value: 0x00. + * 7:3 Reserved. + * 2 LIR: Latch Interrupt request into INT_SOURCE register. 0 - disable; 1 - enable + * 1 PL_E: Enable interrupt generation on differential pressure low event. 0 - disable; 1 - enable + * 0 PH_E: Enable interrupt generation on differential pressure high event. 0 - disable; 1 - enable + * \endcode + */ +#define LPS_INT_CFG_REG_ADDR 0x23 + + +/** + * @brief Interrupt source Register + * \code + * Read + * Default value: 0x00. + * 7:3 0. + * 2 IA: Interrupt Active.0: no interrupt has been generated; 1: one or more interrupt events have been generated. + * 1 PL: Differential pressure Low. 0: no interrupt has been generated; 1: Low differential pressure event has occurred. + * 0 PH: Differential pressure High. 0: no interrupt has been generated; 1: High differential pressure event has occurred. + * \endcode + */ +#define LPS_INT_SOURCE_REG_ADDR 0x24 + + +/** + * @brief Threshold pressure (LSB) + * \code + * Read + * Default value: 0x00. + * 7:0 THS7-THS0: Low part of threshold value for pressure interrupt + * generation. The complete threshold value is given by THS_P_H & THS_P_L and is + * expressed as unsigned number. P_ths(mbar)=(THS_P_H & THS_P_L)[dec]/16. + * \endcode + */ +#define LPS_THS_P_LOW_REG_ADDR 0x25 + + +/** + * @brief Threshold pressure (MSB) + * \code + * Read + * Default value: 0x00. + * 7:0 THS15-THS8: High part of threshold value for pressure interrupt + * generation. The complete threshold value is given by THS_P_H & THS_P_L and is + * expressed as unsigned number. P_ths(mbar)=(THS_P_H & THS_P_L)[dec]/16. + * \endcode + */ +#define LPS_THS_P_HIGH_REG_ADDR 0x26 + + +/** + * @brief Status Register + * \code + * Read + * Default value: 0x00 + * 7:6 0 + * 5 P_OR: Pressure data overrun. 0: no overrun has occurred; 1: new data for pressure has overwritten the previous one. + * 4 T_OR: Temperature data overrun. 0: no overrun has occurred; 1: a new data for temperature has overwritten the previous one. + * 3:2 0 + * 1 P_DA: Pressure data available. 0: new data for pressure is not yet available; 1: new data for pressure is available. + * 0 T_DA: Temperature data available. 0: new data for temperature is not yet available; 1: new data for temperature is available. + * \endcode + */ +#define LPS_STATUS_REG_ADDR 0x27 + + +/** + * @brief Pressure data (LSB). + * \code + * Read + * Default value: 0x00. + * POUT7 - POUT0: Pressure data LSB (2's complement). + * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L & + * PRESS_OUT_XL)[dec]/4096. + * \endcode + */ +#define LPS_PRESS_POUT_XL_ADDR 0x28 + + +/** + * @brief Pressure data (Middle part). + * \code + * Read + * Default value: 0x80. + * POUT15 - POUT8: Pressure data middle part (2's complement). + * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L & + * PRESS_OUT_XL)[dec]/4096. + * \endcode + */ +#define LPS_PRESS_OUT_L_ADDR 0x29 + + +/** + * @brief Pressure data (MSB). + * \code + * Read + * Default value: 0x2F. + * POUT23 - POUT16: Pressure data MSB (2's complement). + * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L & + * PRESS_OUT_XL)[dec]/4096. + * \endcode + */ +#define LPS_PRESS_OUT_H_ADDR 0x2A + + +/** + * @brief Temperature data (LSB). + * \code + * Read + * Default value: 0x00. + * TOUT7 - TOUT0: temperature data LSB. + * T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec]/480. + * \endcode + */ +#define LPS_TEMP_OUT_L_ADDR 0x2B + + +/** + * @brief Temperature data (MSB). + * \code + * Read + * Default value: 0x00. + * TOUT15 - TOUT8: temperature data MSB. + * T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec]/480. + * \endcode + */ +#define LPS_TEMP_OUT_H_ADDR 0x2C + + +/** + * @brief Analog front end control + * \code + * Read/write + * Default value: 0x00 + * 7:1 Reserved. + * 0 SELMAIN: Current of operational amplifier selector. + * -‘1’ always high current + * -‘0’ high current during pressure acquisition and low current during temperature acquisition + * \endcode + */ +#define LPS_AMP_CTRL_ADDR 0x30 + + + +/** + * @brief Pressure offset (LSB). + * \code + * Read + * Default value: 0x00. + * DELTA0 - DELTA7: Delta pressure register for One Point calibration. + * \endcode + */ +#define LPS_DELTA_PRESS_XL_ADDR 0x3C + + +/** + * @brief Pressure offset (Middle part). + * \code + * Read + * Default value: 0x80. + * DELTA15-DELTA8: Delta pressure register for One Point calibration. + * \endcode + */ +#define LPS_DELTA_PRESS_L_ADDR 0x3D + + +/** + * @brief Pressure offset (MSB). + * \code + * Read + * Default value: 0x2F. + * DELTA23-DELTA16: Delta pressure register for One Point calibration. + * \endcode + */ +#define LPS_DELTA_PRESS_H_ADDR 0x3E + + +/** + * @} + */ + + + +/** @defgroup LPS331AP_Exported_Functions LPS331AP Exported Functions + * @{ + */ + +void Lps331apConfig(LPS331Init* pxLPS331InitStruct); +void Lps331apGetInfo(LPS331Init* pxLPS331InitStruct); +void Lps331apLowPowerMode(LPSFunctionalState xFunctionalState); +void Lps331apSetPressureResolution(LPSPressureResolution xPressureResolution); +void Lps331apSetTemperatureResolution(LPSTemperatureResolution xTemperatureResolution); +void Lps331apSetDataRate(LPSOutputDataRate xDataRate); +LPSOutputDataRate Lps331apGetDataRate(void); +void Lps331apRebootCmd(void); +void Lps331apEnterShutdownCmd(void); +void Lps331apExitShutdownCmd(void); +int32_t Lps331apReadRawPressure(void); +int16_t Lps331apReadRawTemperature(void); +void Lps331apIrqInit(LPSIrqInit* pxLPSIrqInit); +void Lps331apOneShot(void); +LPS331DataStatus Lps331apGetDataStatus(void); +void Lps331apSetThreshold(float fThreshold); +float Lps331apGetThreshold(void); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ + diff --git a/lib/LPS331AP/src/LPS331AP.c b/lib/LPS331AP/src/LPS331AP.c new file mode 100755 index 0000000..709024b --- /dev/null +++ b/lib/LPS331AP/src/LPS331AP.c @@ -0,0 +1,606 @@ +/** + * @file LSM303DLH.c + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief This file provides a set of functions needed to manage the LPS331AP slave. + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +#include "LPS331AP.h" + + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + + +/** +* @addtogroup LPS331AP +* @{ +*/ + + +/** + * @defgroup LPS331AP_Private_TypesDefinitions LPS331AP Private TypesDefinitions + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup LPS331AP_Private_Defines LPS331AP Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup LPS331AP_Private_Macros LPS331AP Private Macros + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup LPS331AP_Private_Variables LPS331AP Private Variables + * @{ + */ + +/** + *@} + */ + + + +/** + * @defgroup LPS331AP_Private_FunctionPrototypes LPS331AP Private FunctionPrototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup LPS331AP_Private_Functions LPS331AP Private Functions + * @{ + */ + +/** +* @brief Set configuration of pressure sensor LPS331AP +* @param pxLPS331InitStruct : pointer to a LPS331Init structure that contains the configuration setting for the LPS331AP. +* @retval None. +* @details +* Example: +* @code +* LPS331Init xLps331apInit; +* +* xLps331apInit.xOutputDataRate=ODR_P_7HZ_T_1HZ; +* xLps331apInit.xPresRes=LPS_PRESS_AVG_1; +* xLps331apInit.xTempRes=LPS_TEMP_AVG_1; +* xLps331apInit.xPressureAutoZero=LPS_DISABLE; +* xLps331apInit.fPressureRef=0; +* xLps331apInit.xBDU=LPS_DISABLE; +* +* Lps331apInit(&xLps331apInit); +* @endcode +*/ +void Lps331apConfig(LPS331Init* pxLPS331InitStruct) +{ + uint8_t tempReg[3]; + uint8_t i; + + for(i=0 ; i<3 ; i++) + tempReg[i]=(uint8_t)(((uint32_t)(4096.0*pxLPS331InitStruct->fPressureRef))>>(8*i)); + + /* Write the reference value on register */ + Lps331apBufferWrite(tempReg, LPS_REF_P_XL_ADDR,3); + + /* Resolution register setting */ + tempReg[0] = (uint8_t)pxLPS331InitStruct->xPresRes | (uint8_t)pxLPS331InitStruct->xTempRes; + + /* Write the value on register */ + Lps331apByteWrite(&tempReg[0], LPS_RES_CONF_ADDR); + + /* Read the CTRL1 and 2 register content */ + Lps331apBufferRead(tempReg, LPS_CTRL_REG1_ADDR,2); + + /* Enter the SDN mode */ + tempReg[0] &= 0x7F; + Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR); + + /* CTRL1 register */ + tempReg[0] &= 0x8B; + tempReg[0] |= pxLPS331InitStruct->xOutputDataRate; + + if(pxLPS331InitStruct->xBDU) + tempReg[0] |= 0x04; + else + tempReg[0] &= 0xFB; + + /* CTRL2 register */ + if(pxLPS331InitStruct->xPressureAutoZero) + tempReg[1] |= 0x02; + else + tempReg[1] &= 0xFD; + + /* Write the reference value on register */ + Lps331apBufferWrite(tempReg, LPS_CTRL_REG1_ADDR,2); + + /* Exit the SDN mode */ + tempReg[0] |= 0x80; + Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR); + +} + + +/** +* @brief Gets the general configuration of LPS331AP. +* @param pxLPS331InitStruct : pointer to a LPS331Init structure that will +* contain the configuration setting read from the LPS331AP registers. +* @retval None +*/ +void Lps331apGetInfo(LPS331Init* pxLPS331InitStruct) +{ + uint8_t tempReg[4]; + + Lps331apBufferRead(tempReg, LPS_REF_P_XL_ADDR,3); + tempReg[3]=0; + + /* Get the reference value */ + pxLPS331InitStruct->fPressureRef = (float)(*((uint32_t*)tempReg))/4096.0; + + /* Read register */ + Lps331apByteRead(&tempReg[0], LPS_RES_CONF_ADDR); + + pxLPS331InitStruct->xPresRes=(LPSPressureResolution)(tempReg[0] & 0x0F); + pxLPS331InitStruct->xTempRes=(LPSTemperatureResolution)(tempReg[0] & 0x70); + + /* Read the CTRL1 and 2 register content */ + Lps331apBufferRead(tempReg, LPS_CTRL_REG1_ADDR,2); + + /* get info */ + if(tempReg[0] & 0x04) + pxLPS331InitStruct->xBDU = LPS_ENABLE; + else + pxLPS331InitStruct->xBDU = LPS_DISABLE; + + + if(tempReg[1] & 0x02) + pxLPS331InitStruct->xPressureAutoZero = LPS_ENABLE; + else + pxLPS331InitStruct->xPressureAutoZero = LPS_DISABLE; + + /* Get the ODR info */ + Lps331apByteRead(tempReg, LPS_CTRL_REG1_ADDR); + + pxLPS331InitStruct->xOutputDataRate = (LPSOutputDataRate)(tempReg[0] & 0x70); + +} + + +/** +* @brief Enable or disable the lowpower mode for pressure sensor LPS331AP. +* @param xFunctionalState : new state for the lowpower mode. +* This parameter can be: LPS_ENABLE or LPS_DISABLE +* @retval None +*/ +void Lps331apLowPowerMode(LPSFunctionalState xFunctionalState) +{ + uint8_t tmpreg; + + /* Read the register content */ + Lps331apByteRead(&tmpreg, LPS_AMP_CTRL_ADDR); + + /* modify the specified bit */ + if(xFunctionalState == LPS_ENABLE) + { + tmpreg |= 0x01; + } + else + { + tmpreg &= 0xFE; + } + + /* Write the computed values on register */ + Lps331apByteWrite(&tmpreg, LPS_AMP_CTRL_ADDR); +} + + +/** +* @brief Change pressure resolution for Pressure sensor LPS331AP. +* @param xPressureResolution : new pressure resolution value. +* This parameter can be one of the @ref LPSPressureResolution value. +* @retval None +*/ +void Lps331apSetPressureResolution(LPSPressureResolution xPressureResolution) +{ + uint8_t tempReg; + + /* Read the register content */ + Lps331apByteRead(&tempReg, LPS_RES_CONF_ADDR); + + /* CTRL1 register */ + tempReg &= 0xF0; + tempReg |= xPressureResolution; + + /* Write computed byte onto register */ + Lps331apByteWrite(&tempReg, LPS_RES_CONF_ADDR); +} + + +/** +* @brief Change temperature resolution for Pressure sensor LPS331AP. +* @param xTemperatureResolution : new pressure resolution value. +* This parameter can be one of the @ref LPSTemperatureResolution value. +* @retval None +*/ +void Lps331apSetTemperatureResolution(LPSTemperatureResolution xTemperatureResolution) +{ + uint8_t tempReg; + + /* Read the register content */ + Lps331apByteRead(&tempReg, LPS_RES_CONF_ADDR); + + /* CTRL1 register */ + tempReg &= 0x8F; + tempReg |= xTemperatureResolution; + + /* Write computed byte onto register */ + Lps331apByteWrite(&tempReg, LPS_RES_CONF_ADDR); +} + + +/** +* @brief Change the ODR(Output data rate) for pressure sensor LPS331AP. +* @param xDataRate : new ODR value. +* This parameter can be one of the @ref LPSOutputDataRate value. +* @retval None +*/ +void Lps331apSetDataRate(LPSOutputDataRate xDataRate) +{ + uint8_t tempReg; + + /* Read the register content */ + Lps331apByteRead(&tempReg, LPS_CTRL_REG1_ADDR); + + /* CTRL1 register */ + tempReg &= 0x8F; + tempReg |= xDataRate; + + /*Enter Power Down mode*/ + Lps331apEnterShutdownCmd(); + + /* Write computed byte onto register */ + Lps331apByteWrite(&tempReg, LPS_CTRL_REG1_ADDR); + + /*Exit from Power down mode*/ + Lps331apExitShutdownCmd(); +} + + +/** +* @brief Returns the output data rate. +* @param None. +* @retval Datarate in Hz. +* This parameter is a @ref LPSOutputDataRate. +*/ +LPSOutputDataRate Lps331apGetDataRate(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR); + + /* ..mask it */ + tmpReg &= 0x70; + + /* return the correspondent value */ + return ((LPSOutputDataRate)tmpReg); +} + + + +/** +* @brief Reboot memory content of LPS331AP. +* @param None +* @retval None +*/ +void Lps331apRebootCmd(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lps331apByteRead(&tmpReg, LPS_CTRL_REG2_ADDR); + + /* Set the BOOT bit */ + tmpReg |= 0x80; + + /* Write register */ + Lps331apByteWrite(&tmpReg, LPS_CTRL_REG2_ADDR); + +} + + + +/** +* @brief Enter the shutdown mode for LPS331AP. +* @param None +* @retval None +*/ +void Lps331apEnterShutdownCmd(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR); + + /* Reset the power down bit */ + tmpReg &= 0x7F; + + /* Write register */ + Lps331apByteWrite(&tmpReg, LPS_CTRL_REG1_ADDR); + +} + + +/** +* @brief Exit the shutdown mode for LPS331AP. +* @param None +* @retval None +*/ +void Lps331apExitShutdownCmd(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR); + + /* Set the power down bit */ + tmpReg |= 0x80; + + /* Write register */ + Lps331apByteWrite(&tmpReg, LPS_CTRL_REG1_ADDR); + +} + +/** +* @brief Read LPS331AP output register, and calculate the raw pressure. +* @param None. +* @retval int32_t: pressure raw value. +*/ +int32_t Lps331apReadRawPressure(void) +{ + uint8_t buffer[3]; + uint32_t tempVal=0; + + /* Read the register content */ + Lps331apBufferRead(buffer, LPS_PRESS_POUT_XL_ADDR, 3); + + /* Build the raw data */ + uint8_t i; + for(i=0; i<3; i++) + tempVal |= (((uint32_t)buffer[i]) << (8*i)); + + /* convert the 2's complement 24 bit to 2's complement 32 bit */ + if(tempVal & 0x00800000) + tempVal |= 0xFF000000; + + /* return the built value */ + return ((int32_t)tempVal); + +} + + +/** +* @brief Read LPS331AP output register, and calculate the raw temperature. +* @param None. +* @retval int16_t: temperature raw value. +*/ +int16_t Lps331apReadRawTemperature(void) +{ + uint8_t buffer[2]; + uint16_t tempVal=0; + + /* Read the register content */ + Lps331apBufferRead(buffer, LPS_TEMP_OUT_L_ADDR, 2); + + /* Build the raw value */ + tempVal = (((uint16_t)buffer[1]) << 8)+(uint16_t)buffer[0]; + + /* Return it */ + return ((int16_t)tempVal); + +} + + +/** +* @brief Configures the LPS331AP IRQ outout pins. +* @param pxLPSIrqInit: pointer to the LPSIrqInit structure that defines the IRQ parameters. +* @retval None. +* @details +* Example: +* @code +* LPSIrqInit xLps331apIrqInit; +* +* xLps331apIrqInit.xIrqActiveLow = LPS_DISABLE; +* xLps331apIrqInit.xOutType = LPS_PP; +* xLps331apIrqInit.xInt1List = LPS_DATA_READY; +* xLps331apIrqInit.xInt2List = LPS_P_LOW_HIGH; +* xLps331apIrqInit.fPressThr = 1006.2; +* xLps331apIrqInit.xIrqPressLow=LPS_ENABLE; +* xLps331apIrqInit.xIrqPressHigh=LPS_ENABLE; +* +* ExtiConfiguration(); // set the micro exti before init +* Lps331apIrqInit(&xLps331apIrqInit); +* @endcode +*/ +void Lps331apIrqInit(LPSIrqInit* pxLPSIrqInit) +{ + uint8_t tempReg[2]; + + /* From the structure build the value to write on CTRL3 reg */ + tempReg[0] = (((uint8_t)(pxLPSIrqInit->xIrqActiveLow))<<7) | ((uint8_t)(pxLPSIrqInit->xOutType)) | ((uint8_t)(pxLPSIrqInit->xInt2List)<<3) | ((uint8_t)(pxLPSIrqInit->xInt1List)); + + /* Read the register content */ + Lps331apByteWrite(tempReg, LPS_CTRL_REG3_ADDR); + + /* Build the threshold register values */ + tempReg[0]=(uint8_t)(16.0*pxLPSIrqInit->fPressThr); + tempReg[1]=(uint8_t)(((uint16_t)(16.0*pxLPSIrqInit->fPressThr))>>8); + + /* Read the registers content */ + Lps331apBufferWrite(tempReg, LPS_THS_P_LOW_REG_ADDR, 2); + + Lps331apByteRead(tempReg, LPS_INT_CFG_REG_ADDR); + + /* Enable or disable the high pressure interrupt */ + if(pxLPSIrqInit->xIrqPressHigh) + tempReg[0] |= 0x01; + else + tempReg[0] &= 0xFE; + + /* Enable or disable the low pressure interrupt */ + if(pxLPSIrqInit->xIrqPressLow) + tempReg[0] |= 0x02; + else + tempReg[0] &= 0xFD; + + tempReg[0]|=0x04; + + /* Write the register or disable the high pressure interrupt */ + Lps331apByteWrite(tempReg, LPS_INT_CFG_REG_ADDR); + + /* if one has been requested then enable the differential circuit */ + Lps331apByteRead(tempReg, LPS_CTRL_REG1_ADDR); + if(pxLPSIrqInit->xIrqPressHigh || pxLPSIrqInit->xIrqPressLow) + { + tempReg[0] |= 0x08; + } + else + /* else disable it */ + { + tempReg[0] &= 0xF7; + } + Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR); + +} + + + +/** +* @brief Sets the one-shot bit in order to start acquisition when the ONE SHOT mode has been selected by the ODR configuration. +* @param None. +* @retval None. +*/ +void Lps331apOneShot(void) +{ + uint8_t tempReg; + + /* Read the CTRL2 register */ + Lps331apByteRead(&tempReg, LPS_CTRL_REG2_ADDR); + + /* Set the one shot bit */ + tempReg |= 0x01; + + /* Write the CTRL2 register */ + Lps331apByteWrite(&tempReg, LPS_CTRL_REG2_ADDR); + +} + + +/** +* @brief Gets status for LPS331AP data. +* @param None. +* @retval LPS331DataStatus: Data status in a LPS331DataStatus bitfields structure. +*/ +LPS331DataStatus Lps331apGetDataStatus(void) +{ + uint8_t tempReg; + + /* Read the status register */ + Lps331apByteRead(&tempReg, LPS_STATUS_REG_ADDR); + + /* cast and return it */ + return(*(LPS331DataStatus*)&tempReg); + +} + + +/** +* @brief Sets the pressure threshold. +* @param fThreshold: Threshold expressed in mbar. +* This parameter is a float value. +* @retval None. +*/ +void Lps331apSetThreshold(float fThreshold) +{ + uint8_t tempReg[2]; + + /* Build the threshold register values */ + tempReg[0]=(uint8_t)(16.0*fThreshold); + tempReg[1]=(uint8_t)(((uint16_t)(16.0*fThreshold))>>8); + + /* write the register content */ + Lps331apBufferWrite(tempReg, LPS_THS_P_LOW_REG_ADDR, 2); + +} + + +/** +* @brief Gets the pressure threshold. +* @param None. +* @retval float: threshold value expressed in mbar. +*/ +float Lps331apGetThreshold(void) +{ + uint8_t tempReg[2]; + + /* read the register content */ + Lps331apBufferRead(tempReg, LPS_THS_P_LOW_REG_ADDR, 2); + + /* return the float value */ + return ((float)((((uint16_t)tempReg[1])<<8) + tempReg[0])/16); + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ diff --git a/lib/LSM303DLHC/inc/LSM303DLHC.h b/lib/LSM303DLHC/inc/LSM303DLHC.h new file mode 100755 index 0000000..acda42a --- /dev/null +++ b/lib/LSM303DLHC/inc/LSM303DLHC.h @@ -0,0 +1,1359 @@ +/** + * @file LSM303DLHC.h + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief Header for LSM303DLHC.c file + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __LSM303DLHC_H +#define __LSM303DLHC_H + +/* Includes ------------------------------------------------------------------*/ +#include +#include "HAL_LSM303DLHC.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + +/** + * @addtogroup LSM303DLHC + * @brief This module contains all the functions to configure the LSM303DLHC accelerometer+magnetometer. + * @details + * Since this code is platform independent an implementation of the I2C driver must + * be provided by the user according to the used platform. + * Every function makes use of the Lsm303dlhcAccI2CBufferRead and/or Lsm303dlhcAccI2CBufferWrite + * for the accelerometer and Lsm303dlhcMagI2CBufferRead and/or Lsm303dlhcMagI2CBufferWrite for + * magnetometer as low level functions to write bytes through the used digital interface. + * In order to link and use this code the user should define and export these functions in a header + * file called "HAL_LSM303DLHC.h" (included by this module). + * @{ + */ + +/** + * @addtogroup Accelerometer + * @{ + */ + +/** + * @defgroup Accelerometer_Exported_Types Accelerometer Exported Types + * @{ + */ + +/** + * @brief Accelerometer/Magnetometer Functional state. Used to enable or disable a specific option. + */ +typedef enum +{ + LSM_DISABLE = 0, + LSM_ENABLE = !LSM_DISABLE +}LSMFunctionalState; + + +/** + * @brief Accelerometer/Magnetometer Flag status. Used to set/reset the sensor flags. + */ +typedef enum +{ + LSM_RESET = 0, + LSM_SET = !LSM_RESET +}LSMFlagStatus; + + +/** + * @brief Accelerometer Output Data Rate + */ +typedef enum +{ + LSM_ODR_1_HZ = 0x10, /*!< Output Data Rate = 1 Hz */ + LSM_ODR_10_HZ = 0x20, /*!< Output Data Rate = 10 Hz */ + LSM_ODR_25_HZ = 0x30, /*!< Output Data Rate = 25 Hz */ + LSM_ODR_50_HZ = 0x40, /*!< Output Data Rate = 50 Hz */ + LSM_ODR_100_HZ = 0x50, /*!< Output Data Rate = 100 Hz */ + LSM_ODR_200_HZ = 0x60, /*!< Output Data Rate = 200 Hz */ + LSM_ODR_400_HZ = 0x70, /*!< Output Data Rate = 400 Hz */ + LSM_ODR_1620_HZ = 0x80, /*!< Output Data Rate = 1620 Hz only in Low Power Mode */ + LSM_ODR_1344_HZ = 0x90 /*!< Output Data Rate = 1344 Hz in Normal mode and 5376 Hz in Low Power Mode */ +}AccOutputDataRate; + + +/** + * @brief Accelerometer Power Mode + */ +typedef enum +{ + LSM_NORMAL_MODE = 0x00, /*!< Normal mode enabled */ + LSM_LOW_POWER_MODE = 0x08 /*!< Low Power mode enabled */ +}AccPowerMode; + + +/** + * @brief Accelerometer Axes + */ +typedef enum +{ + LSM_X_AXIS_DIS = 0x00, /*!< X Axis disabled */ + LSM_X_AXIS_EN = 0x01, /*!< X Axis enabled */ + LSM_Y_AXIS_DIS = 0x00, /*!< Y Axis disabled */ + LSM_Y_AXIS_EN = 0x02, /*!< Y Axis enabled */ + LSM_Z_AXIS_DIS = 0x00, /*!< Z Axis disabled */ + LSM_Z_AXIS_EN = 0x04, /*!< Z Axis enabled */ + LSM_ALL_AXES_DIS = 0x00, /*!< All axes disabled */ + LSM_ALL_AXES_EN = 0x07 /*!< All axes enabled */ +}AccAxesEnabling; + + +/** + * @brief Accelerometer Full scale selection + */ +typedef enum +{ + LSM_FS_2G = 0x00, /*!< ±2 g */ + LSM_FS_4G = 0x10, /*!< ±4 g */ + LSM_FS_8G = 0x20, /*!< ±8 g */ + LSM_FS_16G = 0x30 /*!< ±16 g */ +}AccFullScale; + + +/** + * @brief Accelerometer Block Data Update selection + */ +typedef enum +{ + LSM_CONTINUOS_UPDATE = 0x00, /*!< Continuos Update */ + LSM_BLOCK_UPDATE = 0x80 /*!< Single Update: output registers not updated until MSB and LSB reading */ +}AccBlockDataUpdate; + + +/** + * @brief Accelerometer Endianness selection + */ +typedef enum +{ + LSM_LITTLE_ENDIAN = 0x00, /*!< Little Endian: data LSB @ lower address */ + LSM_BIG_ENDIAN = 0x40 /*!< Big Endian: data MSB @ lower address */ +}AccEndianness; + + +/** + * @brief Accelerometer High Pass Mode Filter Selection + */ +typedef enum +{ + LSM_HPFM_NORMAL = 0x00, /*!< Normal Mode */ + LSM_HPFM_REFERENCE = 0x40, /*!< Reference Signal for filtering */ + LSM_HPFM_AOI = 0xC0 /*!< Autoreset On Interrupt event */ +}AccHPFMode; + + +/** + * @brief Accelerometer High Pass Filter Cut-Off + */ +typedef enum +{ + LSM_HPCF_8 = 0x00, /*!< ft= ODR[hz]/(6*8). For more details see Accelerometer Control Register 2 description */ + LSM_HPCF_16 = 0x10, /*!< ft= ODR[hz]/(6*16). For more details see Accelerometer Control Register 2 description */ + LSM_HPCF_32 = 0x20, /*!< ft= ODR[hz]/(6*32). For more details see Accelerometer Control Register 2 description */ + LSM_HPCF_64 = 0x30 /*!< ft= ODR[hz]/(6*64). For more details see Accelerometer Control Register 2 description */ +}AccHPFCutOff; + + + +/** + * @brief Accelerometer Irq on line 1 list + */ +typedef enum +{ + LSM_I1_OVERRUN = 0x02, + LSM_I1_WTM = 0x04, + LSM_I1_DRDY2 = 0x08, + LSM_I1_DRDY1 = 0x10, + LSM_I1_AOI2 = 0x20, + LSM_I1_AOI1 = 0x40, + LSM_I1_CLICK = 0x80 +}LSMAIrq1List; + + +/** + * @brief Accelerometer Irq on line 2 list + */ +typedef enum +{ + LSM_I2_CLICK = 0x80, + LSM_I2_INT1 = 0x40, + LSM_I2_INT2 = 0x20, + LSM_I2_BOOT = 0x10, + LSM_I2_P2ACT = 0x08, + LSM_I2_H_LACTIVE = 0x02, +}LSMAIrq2List; + + +/** + * @brief Accelerometer data status. It notifies if data on axis are available or overrided + */ +typedef struct +{ + LSMFlagStatus X_Da:1; + LSMFlagStatus Y_Da:1; + LSMFlagStatus Z_Da:1; + LSMFlagStatus ZYX_Da:1; + LSMFlagStatus X_Or:1; + LSMFlagStatus Y_Or:1; + LSMFlagStatus Z_Or:1; + LSMFlagStatus ZYX_Or:1; +}LSMADataStatus; + + +/** + * @brief Accelerometer Init structure definition + */ +typedef struct +{ + AccPowerMode xPowerMode; /*!< Power mode selection */ + AccOutputDataRate xOutputDataRate; /*!< Output Data Rate */ + AccAxesEnabling xEnabledAxes; /*!< Axes to be enabled */ + AccFullScale xFullScale; /*!< Full Scale */ + AccBlockDataUpdate xDataUpdate; /*!< Data Update mode : Continuos update or data don`t change until MSB and LSB nex reading */ + AccEndianness xEndianness; /*!< Endianness */ + LSMFunctionalState xHighResolution; /*!< High Resolution enabling/disabling */ +}LSMAccInit; + + +/** + * @brief Accelerometer Filter Init structure definition + */ +typedef struct +{ + LSMFunctionalState xHPF; /*!< HPF enabling/disabling */ + AccHPFMode xHPF_Mode; /*!< HPF MODE: Normal mode, Reference signal or Auntoreset on interrupt event for filtering */ + uint8_t cHPFReference; /*!< Reference value for filtering. Used only in case the mode is "Reference Signal" */ + AccHPFCutOff xHPFCutOff; /*!< HPF_frequency ft=ODR/6*HPc HPc=8,16,32,64 */ + LSMFunctionalState xHPFClick; /*!< HPF_enabling/disabling on CLICK function */ + LSMFunctionalState xHPFAOI2; /*!< HPF_enabling/disabling for AOI function on interrupt 2 */ + LSMFunctionalState xHPFAOI1; /*!< HPF_enabling/disabling for AOI function on interrupt 1 */ +}LSMAccFilterInit; + + +/** + * @brief Accelerometer FIFO Working Mode + */ +typedef enum +{ + LSM_BYPASS_MODE = 0x00, /*!< Bypass mode: don't use the FIFO */ + LSM_FIFO_MODE = 0x40, /*!< FIFO mode */ + LSM_STREAM_MODE = 0x80, /*!< Stream mode */ + LSM_TRIGGER_MODE = 0xC0 /*!< Trigger mode */ +}LSMAFifoMode; + + +/** + * @brief Accelerometer Sensor IRQ line + */ +typedef enum +{ + LSM_INT1_LINE=0x01, /*!< Sensor IRQ line 1 */ + LSM_INT2_LINE /*!< Sensor IRQ line 2 */ +}LSMAIrqLine; + + +/** + * @brief Accelerometer FIFO Init structure definition + */ +typedef struct +{ + LSMAFifoMode xFifoMode; /*!< FIFO operating mode */ + LSMAIrqLine xTriggerSel; /*!< External interrupt line linked to the FIFO trigger event */ + uint8_t cWtm; /*!< WaterMark level for FIFO in range [0, 31] */ +}LSMAccFifoInit; + + +/** + * @brief Accelerometer FIFO Status bitfield structure + */ +typedef struct +{ + uint8_t FIFO_FSS:5; /*!< FIFO unread samples */ + LSMFlagStatus FIFO_EMPTY_FLAG:1; /*!< FIFO Empty flag */ + LSMFlagStatus FIFO_OVRN_FLAG:1; /*!< FIFO Overrun flag */ + LSMFlagStatus FIFO_WTM_FLAG:1; /*!< FIFO Watermark flag */ + +}LSMAccFifoStatus; + +/** + * @brief Accelerometer Events on axis bitfield structure + */ +typedef struct +{ + LSMFlagStatus X_LOW:1; /*!< X axis low event */ + LSMFlagStatus X_HIGH:1; /*!< X axis high event */ + LSMFlagStatus Y_LOW:1; /*!< Y axis low event */ + LSMFlagStatus Y_HIGH:1; /*!< Y axis high event */ + LSMFlagStatus Z_LOW:1; /*!< Z axis low event */ + LSMFlagStatus Z_HIGH:1; /*!< Z axis high event */ + uint8_t :2; /*!< 2 bits padding */ +}LSMAccAxisEvents; + + +/** + * @brief Accelerometer External events on axis combination + */ +typedef enum +{ + LSM_OR_COMBINATION = 0x00, /*!< OR combination of enabled IRQs */ + LSM_AND_COMBINATION = 0x80, /*!< AND combination of enabled IRQs */ + LSM_SIXD_MOV_RECOGNITION = 0x40, /*!< 6D movement recognition */ + LSM_SIXD_POS_RECOGNITION = 0xC0 /*!< 6D position recognition */ + +}LSMAccIrqOnaxisCombination; + + +/** + * @brief Accelerometer Click initialization structure + */ +typedef struct +{ + uint16_t nClickThreshold; /*!< Click acceleration threshold expressed in mg */ + LSMFunctionalState xNegativeDetection; /*!< Click negative detection */ + uint8_t cClickTimeLimit; /*!< Click time limit expressed in ms */ + uint8_t cDClickTimeLatency; /*!< Click time latency expressed in ms (only for double click) */ + uint8_t cDClickTimeWindow; /*!< Click time window expressed in ms (only for double click) */ +}LSMAccClickInit; + + +/** + * @} + */ + +/** + * @defgroup Accelerometer_Exported_Constants Accelerometer Exported Constants + * @{ + */ + + +/** + * @defgroup Accelerometer_Sensitivity_Defines Accelerometer Sensitivity Defines + * @{ + */ + +#define LSM_Acc_Sensitivity_2g 1.0 /*!< accelerometer sensitivity with 2 g full scale [LSB/mg] */ +#define LSM_Acc_Sensitivity_4g 0.5 /*!< accelerometer sensitivity with 4 g full scale [LSB/mg] */ +#define LSM_Acc_Sensitivity_8g 0.25 /*!< accelerometer sensitivity with 8 g full scale [LSB/mg] */ +#define LSM_Acc_Sensitivity_16g 0.0834 /*!< accelerometer sensitivity with 12 g full scale [LSB/mg] */ + +/** + * @} + */ /* end of group Accelerometer_Sensitivity_Defines */ + +/** + * @} + */ + +/** + * @defgroup Accelerometer_Exported_Macros Accelerometer Exported Macros + * @{ + */ + +/** @defgroup Accelerometer_I2C_Communication Accelerometer I2C Communication + * @{ + */ + +#define Lsm303dlhcAccI2CBufferRead(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferRead(LSM_A_I2C_ADDRESS,pVal,cAddress,nBytes) +#define Lsm303dlhcAccI2CBufferWrite(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferWrite(LSM_A_I2C_ADDRESS,pVal,cAddress,nBytes) + +#define Lsm303dlhcAccI2CByteRead(pVal,cAddress) Lsm303dlhcAccI2CBufferRead(pVal,cAddress,1) +#define Lsm303dlhcAccI2CByteWrite(pVal,cAddress) Lsm303dlhcAccI2CBufferWrite(pVal,cAddress,1) + +/** + * @} + */ + +/** + *@} + */ + +/** @defgroup Accelerometer_Register_Mapping Accelerometer Register Mapping + * @{ + */ + +/** + * @brief Accelerometer I2C Slave Address + */ +#define LSM_A_I2C_ADDRESS 0x33 + +/** + * @brief Accelerometer Control Register 1 + * \code + * Read/write + * Default value: 0x07 + * 7:4 ODR3-ODR0: Data Rate selection + * ODR3 | ODR2 | ODR1 | ODR0 | Power Mode Sel & Out Data Rate[Hz] + * -------------------------------------------------------------- + * 0 | 0 | 0 | 0 | Power Down + * 0 | 0 | 0 | 1 | Normal / Low Power (1 Hz) + * 0 | 0 | 1 | 0 | Normal / Low Power (10 Hz) + * 0 | 0 | 1 | 1 | Normal / Low Power (25 Hz) + * 0 | 1 | 0 | 0 | Normal / Low Power (50 Hz) + * 0 | 1 | 0 | 1 | Normal / Low Power (100 Hz) + * 0 | 1 | 1 | 0 | Normal / Low Power (200 Hz) + * 0 | 1 | 1 | 1 | Normal / Low Power (400 Hz) + * 1 | 0 | 0 | 0 | Low Power (1620 Hz) + * 1 | 0 | 0 | 1 | Normal (1344 Hz) / Low Power (5376 Hz) + * 3 LPen: Low Power Mode Enable. 0 - Normal Mode 1 - Low Power Mode + * 2 Zen: Z axis enable. 0 - Z axis disabled 1- Z axis enabled + * 1 Yen: Y axis enable. 0 - Y axis disabled 1- Y axis enabled + * 0 Xen: X axis enable. 0 - X axis disabled 1- X axis enabled + * \endcode + */ +#define LSM_A_CTRL1_REG_ADDR 0x20 + + +/** + * @brief Accelerometer Control Register 2 + * \code + * Read/write + * Default value: 0x00 + * 7:6 HPM1-HPM0: High pass filter mode selection: + * HPM1 | HPM0 | High pass filter mode + * ----------------------------------------- + * 0 | 0 | Normal mode (reset reading HP_RESET_FILTER) + * 0 | 1 | Reference signal for filtering + * 1 | 0 | Normal mode (reset reading HP_RESET_FILTER) + * 1 | 1 | Autoreset on interrupt event + * 5:4 HPCF1-HPCF0: High pass filter cut-off frequency (ft) configuration + * ft= ODR[hz]/6*HPc + * HPCF1 | HPCF0 | HPc | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] + * | | | ODR 1 Hz | ODR 10 Hz | ODR 25 Hz | ODR 50 Hz | ODR 100 Hz | ODR 200 HZ | ODR 400 Hz | ODR 1344 HZ + * ------------------------------------------------------------------------------------------------------------------------------------ + * 0 | 0 | 8 | 0.02 | 0.2 | 0.52 | 1.04 | 2.08 | 4.16 | 8.33 | 28 + * 0 | 1 | 16 | 0.01 | 0.1 | 0.26 | 0.52 | 1.04 | 2.08 | 4.16 | 14 + * 1 | 0 | 32 | 0.005 | 0.05 | 0.13 | 0.26 | 0.52 | 1.04 | 2.08 | 7 + * 1 | 1 | 64 | 0.0026 | 0.026 | 0.065 | 0.13 | 0.26 | 0.52 | 1.04 | 3.5 + * 3 FDS: Filtered data selection. 0 - internal filter bypassed; 1 - data from internal filter sent to output register and FIFO + * 2 HPCLICK: High pass filter enabled for CLICK function. 0 - filter bypassed; 1 - filter enabled + * 1 HPIS2: High pass filter enabled for interrupt 2 source. 0 - filter bypassed; 1 - filter enabled + * 0 HPIS1: High pass filter enabled for interrupt 1 source. 0 - filter bypassed; 1 - filter enabled + * \endcode + */ +#define LSM_A_CTRL2_REG_ADDR 0x21 + + +/** + * @brief Accelerometer Control Register 3 Interrupt Control Register + * \code + * Read/write + * Default value: 0x00 + * 7 I1_CLICK: Click interrupt on INT1. 0 - disable; 1 - enable + * 6 I1_AOI1: AOI1 interrupt on INT1. 0 - disable; 1 - enable + * 5 I1_AOI2: AOI2 interrupt on INT1. 0 - disable; 1 - enable + * 4 I1_DRDY1: DRDY1 interrupt on INT1. 0 - disable; 1 - enable + * 3 I1_DRDY2: DRDY2 interrupt on INT1. 0 - disable; 1 - enable + * 2 I1_WTM: FIFO watermark interrupt on INT1. 0 - disable; 1 - enable + * 1 I1_OVERRUN: FIFO overrun interrup on INT1. 0 - disable; 1 - enable + * 0 -: Not used. It shall be zero + * \endcode + */ +#define LSM_A_CTRL3_REG_ADDR 0x22 + + +/** + * @brief Accelerometer Control Register 4 + * \code + * Read/write + * Default value: 0x00 + * 7 BDU: Block data update. 0 -continuos update; 1- output registers not updated between MSB and LSB reading + * 6 BLE: Big/little endian data selection. 0 - data LSB @ lower address; 1 - data MSB @ lower address + * 5:4 FS1 - FS0: Full-scale selection + * FS1 | FS0 | Full Scale + * ----------------------------------------- + * 0 | 0 | ±2 g + * 0 | 1 | ±4 g + * 1 | 0 | ±8 g + * 1 | 1 | ±16 g + * 3 HR: High resolution output mode. 0 - disable; 1- enable + * 2:1 -: Not used. They shall be zero + * 0 SIM: SPI serial interface mode selection. 0 - 4 wire interface; 1 - 3 wire interface + * \endcode + */ +#define LSM_A_CTRL4_REG_ADDR 0x23 + + +/** + * @brief Accelometer Control Register 5 + * \code + * Read/write + * Default value: 0x00 + * 7 BOOT: Reboot memory content. 0 - Normal mode; 1 - Reboot memory content + * 6 FIFO_EN: FIFO enable. 0 - FIFO disabled; 1 - FIFO enabled + * 5:4 -: Not used. They shall be zero + * 3 LIR_INT1: Latch interrupt request on INT1_SRC register. 0 - Interrupt request not latched; 1 - Interrupt request latched + * 2 D4D_INT1: 4D detection enabling (enabled on INT1 when 6D bit on INT1_CFG is set to 1). 0 - 4D detection disabled; 1 - 4D detection enabled + * 1 LIR_INT2: Latch interrupt request on INT2_SRC register. 0 - Interrupt request not latched; 1 - Interrupt request latched + * 0 D4D_INT1: 4D detection enabling (enabled on INT2 when 6D bit on INT2_CFG is set to 1). 0 - 4D detection disabled; 1 - 4D detection enabled + * \endcode + */ +#define LSM_A_CTRL5_REG_ADDR 0x24 + + +/** + * @brief Accelometer Control Register 6 + * \code + * Read/write + * Default value: 0x00 + * 7 I2_CLICKen: CLICK interrupt on PAD2. 0 - disable; 1 - enable + * 6 I2_INT1: Interrupt 1 on PAD2. 0 - disable; 1 - enable + * 5 I2_INT2: Interrupt 2 on PAD2. 0 - disable; 1 - enable + * 4 BOOT_I1: Reboot memory content on PAD2. 0 - disable; 1 - enable + * 3 P2_ACT: Active function status on PAD2. 0 - disable; 1 - enable + * 2 -: Not used. It shall be zero + * 1 H_LACTIVE: Interrupt active high, low. 0 - active high; 1 - active low + * 0 -: Not used. It shall be zero. + * \endcode + */ +#define LSM_A_CTRL6_REG_ADDR 0x25 + + +/** + * @brief Accelrometer HP Reference register + * \code + * Read/write + * Default value: 0x00 + * 7:0 Ref7 - Ref0: Reference value for high-pass filter. + * This register sets the acceleration value taken as a reference for the high-pass filter output + * When filter is turned on (at least one of FDS, HPen2, or HPen1 bit is equal to ‘1’) and HPM + * bits are set to “01”, filter out is generated taking this value as a reference. + * \endcode + */ +#define LSM_A_REFERENCE_REG_ADDR 0x26 + + +/** + * @brief Accelerometer Status Register + * \code + * Read + * Default value: 0x00 + * 7 ZYXOR: X, Y and Z axis data overrun. 0 - No overrun has occurred; 1 - A new set of data has overwritten the previous ones + * 6 ZOR: Z axis data overrun. 0 - No overrun has occurred; 1 - A new data for the Z-axis has overwritten the previous one + * 5 YOR: Y axis data overrun. 0 - No overrun has occurred; 1 - A new data for the Y-axis has overwritten the previous one + * 4 XOR: X axis data overrun. 0 - No overrun has occurred; 1 - A new data for the X-axis has overwritten the previous one + * 3 ZYXDA: X, Y and Z axis new data available. 0 - A new set of data is not yet available; 1 - A new set of data available + * 2 ZDA: Z axis new data available. 0 - A new data for Z-axis is not yet available; 1 - A new data for Z-axis is available + * 1 YDA: Y axis new data available. 0 - A new data for Y-axis is not yet available; 1 - A new data for Y-axis is available + * 0 XDA: X axis new data available. 0 - A new data for X-axis is not yet available; 1 - A new data for X-axis is available + * \endcode + */ +#define LSM_A_STATUS_REG_ADDR 0x27 + + +/** + * @brief Accelerometer X axis Output Data Low Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 XOUT7-XOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define LSM_A_OUT_X_L_REG_ADDR 0x28 + + +/** + * @brief Acceleration X-axis Output Data High Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 XOUT15-XOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define LSM_A_OUT_X_H_REG_ADDR 0x29 + + +/** + * @brief Acceleration Y-axis Output Data Low Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 YOUT7-YOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define LSM_A_OUT_Y_L_REG_ADDR 0x2A + + +/** + * @brief Acceleration Y-axis Output Data High Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 YOUT15-YOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define LSM_A_OUT_Y_H_REG_ADDR 0x2B + + +/** + * @brief Acceleration Z-axis Output Data Low Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 ZOUT7-ZOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0) + * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1) + * \endcode + */ +#define LSM_A_OUT_Z_L_REG_ADDR 0x2C + + +/** + * @brief Acceleration Z-axis Output Data High Register + * \code + * Read + * Default value: ( The value is expressed as 16bit two’s complement). Because the resolution is 12 bit, + * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16. + * 7:0 ZOUT15-ZOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0) + * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1) + * \endcode + */ +#define LSM_A_OUT_Z_H_REG_ADDR 0x2D + + +/** + * @brief FIFO Control Register + * \code + * Read/write + * Default value: 0x00 + * 7:6 FM1 - FM0: FIFO Mode selection + * FM1 | FM0 | FIFO Mode Configuration + * ------------------------------------- + * 0 | 0 | Bypass Mode + * 0 | 1 | FIFO Mode + * 1 | 0 | Stream Mode + * 1 | 1 | Trigger Mode + * 5 TR: Trigger selection. 0 - trigger event linked to trigger signal on INT1; 1 - trigger event linked to trigger signal on INT2 + * 4:0 FTH4 - FTH0: ????? + * \endcode + */ +#define LSM_A_FIFO_CTRL_REG_ADDR 0x2E + + +/** + * @brief FIFO Status Register + * \code + * Read + * Default value: 0x00 + * 7 WTM: + * 6 OVRN_FIFO: + * 5 EMPTY: + * 4:0 FSS4 - FSSO: + * \endcode + */ +#define LSM_A_FIFO_STATUS_REG_ADDR 0x2F + + +/** + * @brief Accelerometer Configuration Register for Interrupt 1 source. + * \code + * Read/write + * Default value: 0x00 + * 7 AOI: AND/OR combination of Interrupt events. See table below + * 6 6D: 6 direction detection function enable. See table below + * 5 ZHIE/ZUPE: Enable interrupt generation on Z high event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value higher than preset threshold + * 4 ZLIE/ZDOWNNE: Enable interrupt generation on Z low event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value lower than preset threshold + * 3 YHIE/YUPE: Enable interrupt generation on Y high event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value higher than preset threshold + * 2 YLIE/YDOWNE: Enable interrupt generation on Y low event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value lower than preset threshold + * 1 XHIE/XUPE: Enable interrupt generation on X high event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value higher than preset threshold + * 0 XLIE/XDOWNE: Enable interrupt generation on X low event or on direction recognition. 0: disable interrupt request; 1: enable interrupt request on measured acceleration for value lower than preset threshold + * AOI | 6D | Interrupt mode + * -------------------------------------------------------- + * 0 | 0 | OR combination of interrupt events + * 0 | 1 | 6 direction movement recognition + * 1 | 0 | AND combination of interrupt events + * 1 | 1 | 6 direction position recognition + * \endcode + */ +#define LSM_A_INT1_CFG_REG_ADDR 0x30 + + +/** + * @brief Accelerometer Interrupt 1 source register. + * Reading at this address clears INT1_SRC IA bit (and the interrupt signal on INT 1 pin) and + * allows the refreshment of data in the INT1_SRC register if the latched option was chosen. + * \code + * Read + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 IA : Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated + * 5 ZH: Z high. 0: no interrupt, 1: Z High event has occurred + * 4 ZL: Z low. 0: no interrupt; 1: Z Low event has occurred + * 3 YH: Y high. 0: no interrupt, 1: Y High event has occurred + * 2 YL: Y low. 0: no interrupt; 1: Y Low event has occurred + * 1 XH: X high. 0: no interrupt, 1: X High event has occurred + * 0 XL: X low. 0: no interrupt; 1: X Low event has occurred + * \endcode + */ +#define LSM_A_INT1_SRC_REG_ADDR 0x31 + + +/** + * @brief Accelerometer Interrupt 1 Threshold Register + * \code + * Read/write + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 THS6-THS0: Interrupt 1 threshold. + * \endcode + */ +#define LSM_A_INT1_THS_REG_ADDR 0x32 + + +/** + * @brief Acceleroemter INT1_DURATION Register + * \code + * Read/write + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 D6-D0: Duration value. (Duration steps and maximum values depend on the ODR chosen) + * \endcode + */ +#define LSM_A_INT1_DURATION_REG_ADDR 0x33 + + +/** + * @brief INT2_CFG Register Configuration register for Interrupt 2 source. + * \code + * Read/write + * Default value: 0x00 + * 7 AOI: AND/OR combination of Interrupt events. See table below + * 6 6D: 6 direction detection function enable. See table below + * 5 ZHIE: Enable interrupt generation on Z high event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 4 ZLIE: Enable interrupt generation on Z low event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value lower than preset threshold + * 3 YHIE: Enable interrupt generation on Y high event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 2 YLIE: Enable interrupt generation on Y low event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value lower than preset threshold + * 1 XHIE: Enable interrupt generation on X high event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 0 XLIE: Enable interrupt generation on X low event. 0: disable interrupt request; 1: enable interrupt request on measured accel. value lower than preset threshold + * AOI | 6D | Interrupt mode + * -------------------------------------------------------- + * 0 | 0 | OR combination of interrupt events + * 0 | 1 | 6 direction movement recognition + * 1 | 0 | AND combination of interrupt events + * 1 | 1 | 6 direction position recognition + * \endcode + */ +#define LSM_A_INT2_CFG_REG_ADDR 0x34 + + +/** + * @brief INT2_SCR Register Interrupt 2 source register. + * Reading at this address clears INT2_SRC IA bit (and the interrupt signal on INT 2 pin) and + * allows the refreshment of data in the INT2_SRC register if the latched option was chosen. + * \code + * Read + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 IA : Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated + * 5 ZH: Z high. 0: no interrupt, 1: Z High event has occurred + * 4 ZL: Z low. 0: no interrupt; 1: Z Low event has occurred + * 3 YH: Y high. 0: no interrupt, 1: Y High event has occurred + * 2 YL: Y low. 0: no interrupt; 1: Y Low event has occurred + * 1 YH: X high. 0: no interrupt, 1: X High event has occurred + * 0 YL: X low. 0: no interrupt; 1: X Low event has occurred + * \endcode + */ +#define LSM_A_INT2_SRC_REG_ADDR 0x35 + + +/** + * @brief Accelerometer Interrupt 2 Threshold Register + * \code + * Read/write + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 THS6-THS0: Interrupt 2 threshold. + * \endcode + */ +#define LSM_A_INT2_THS_REG_ADDR 0x36 + + +/** + * @brief Acceromter INT2_DURATION Register + * \code + * Read/write + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 D6-D0: Duration value. (Duration steps and maximum values depend on the ODR chosen) + * \endcode + */ +#define LSM_A_INT2_DURATION_REG_ADDR 0x37 + + +/** + * @brief CLICK Configuration register. + * \code + * Read/write + * Default value: 0x00 + * 7:6 -: It shall be zero for correct working of the device + * 5 ZD: Enable interrupt double click on Z axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 4 ZS: Enable interrupt single click on Z axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 3 YD: Enable interrupt double click on Y axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 2 YS: Enable interrupt single click on Y axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 1 XD: Enable interrupt double click on X axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * 0 XS: Enable interrupt single click on X axis. 0: disable interrupt request; 1: enable interrupt request on measured accel. value higher than preset threshold + * \endcode +*/ +#define LSM_A_CLICK_CONF_REG_ADDR 0x38 + + +/** + * @brief CLICK source register. + * \code + * Read + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 IA: Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated + * 5 DCLICK: Double CLICK-CLICK enable. 0: Double CLICK-CLICK detection disable; 1: Double CLICK-CLICK detection enable + * 4 SCLICK: Single CLICK-CLICK enable. 0: Single CLICK-CLICK detection disable; 1: Single CLICK-CLICK detection enable + * 3 Sign: CLICK-CLICK Sign. 0: positive detection; 1: negative detection + * 2 Z: Z CLICK-CLICK detection. 0: no interrupt; 1: Z high event has occurred + * 1 Y: Y CLICK-CLICK detection. 0: no interrupt; 1: Y high event has occurred + * 0 X: X CLICK-CLICK detection. 0: no interrupt; 1: X high event has occurred + * \endcode +*/ +#define LSM_A_CLICK_SRC_REG_ADDR 0x39 + + +/** + * @brief CLICK Threshold Register. 1LSB = full-scale/128. THS6 through THS0 define the threshold which is used by the system to + * start the click detection procedure. The threshold value is expressed over 7 bits as an unsigned number. + * \code + * Read/write + * Default value: 0x00 + * 7 0: It shall be zero for correct working of the device + * 6 THS6-THS0: CLICK-CLICK threshold. + * \endcode + */ +#define LSM_A_CLICK_THS_REG_ADDR 0x3A + + +/** + * @brief CLICK Time Limit Register. 1LSB = 1/ODR. TLI7 through TLI0 define the maximum time interval that can elapse + * between the start of the click detection procedure (the accelration on the selected channel exceeds the programmed + * threshold) and when the acceleration goes back below the threshold + * \code + * Read/write + * Default value: 0x00 + * 7:0 TLI7-TLI0: CLICK-CLICK time limit. + * \endcode + */ +#define LSM_A_CLICK_TIME_LIMIT_REG_ADDR 0x3B + + +/** + * @brief CLICK Time Latency Register. 1LSB = 1/ODR. TLA7 through TLA0 define the time interval that starts after the first + * click detection where the click detection procedure is disabled, in cases where the device is configured for double click + * detection. + * \code + * Read/write + * Default value: 0x00 + * 7:0 TLA7-TLA0: CLICK-CLICK time latency. + * \endcode + */ +#define LSM_A_CLICK_TIME_LATENCY_REG_ADDR 0x3C + + +/** + * @brief CLICK Time Window Register. 1LSB = 1/ODR. TW7 through TW0 define the maximum interval of time + * that can elapse after the end of latency interval in which the click detection procedure can start, + * in cases where the device is configured for double click detection. + * \code + * Read/write + * Default value: 0x00 + * 7:0 TW7-TW0: CLICK-CLICK time window. + * \endcode + */ +#define LSM_A_CLICK_TIME_WINDOW_REG_ADDR 0x3D + + +/** + * @} + */ + + + +/** @defgroup Accelerometer_Exported_Functions Accelerometer Exported Functions + * @{ + */ +void Lsm303dlhcAccConfig(LSMAccInit* pxLSMAccInitStruct); +void Lsm303dlhcAccGetInfo(LSMAccInit* pxLSMAccInitStruct); +void Lsm303dlhcAccFilterConfig(LSMAccFilterInit* pxLSMAccFilterInitStruct); +void Lsm303dlhcAccFilterGetInfo(LSMAccFilterInit* pxLSMAccFilterInitStruct); +void Lsm303dlhcAccLowPowerMode(LSMFunctionalState xFunctionalState); +void Lsm303dlhcAccSetFullScale(AccFullScale xFullScale); +AccFullScale Lsm303dlhcAccGetEnumFullScale(void); +uint8_t Lsm303dlhcAccGetFullScale(void); +void Lsm303dlhcAccGetSensitivity(float *pfSensitivityXYZ); +void Lsm303dlhcAccSetDataRate(AccOutputDataRate xDataRate); +AccOutputDataRate Lsm303dlhcAccGetEnumDataRate(void); +uint16_t Lsm303dlhcAccGetDataRate(void); +void Lsm303dlhcAccRebootCmd(void); +void Lsm303dlhcAccReadOutReg(uint8_t* pcReg); +void Lsm303dlhcAccReadRawData(int16_t* pnRawData); +void Lsm303dlhcAccReadAcc(float* pfData); +void Lsm303dlhcAccReadAccFifo(int16_t* pnData, uint8_t cDataToRead); +LSMADataStatus Lsm303dlhcAccGetDataStatus(void); +void Lsm303dlhcAccIrq1Config(LSMAIrq1List xLSMAIrq1Config, LSMFunctionalState xNewState); +void Lsm303dlhcAccIrq2Config(LSMAIrq2List xLSMAIrq2Config, LSMFunctionalState xNewState); +void Lsm303dlhcAccFifo(LSMFunctionalState xNewState); +void Lsm303dlhcAccFifoInit(LSMAccFifoInit* pxLSMAccFifoInit); +LSMAccFifoStatus Lsm303dlhcAccFifoGetStatus(void); +void Lsm303dlhcAccSetAxisIrqs(LSMAccIrqOnaxisCombination xIrqCombinations, LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine, LSMFunctionalState xLatched); +LSMFunctionalState Lsm303dlhcAccGetAxisIrqs(LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine); +void Lsm303dlhcAccSetThreshold(int16_t nData, LSMAIrqLine xIRQLine); +void Lsm303dlhcAccSetIrqDuration(uint8_t cDuration, LSMAIrqLine xIRQLine); +void Lsm303dlhcAccClickInit(LSMAccClickInit* pxClickInit); + +/** + * @} + */ + +/** + * @} + */ + + +/** + * @addtogroup Magnetometer + * @{ + */ + +/** + * @defgroup Magnetometer_Exported_Types Magnetometer Exported Types + * @{ + */ + +/** + * @brief Magnetometer Output Data Rate + */ +typedef enum +{ + LSM_ODR_0_75_HZ = 0x00, /*!< Output Data Rate = 0.75 Hz */ + LSM_ODR_1_5_HZ = 0x04, /*!< Output Data Rate = 1.5 Hz */ + LSM_ODR_3_0_HZ = 0x08, /*!< Output Data Rate = 3 Hz */ + LSM_ODR_7_5_HZ = 0x0C, /*!< Output Data Rate = 7.5 Hz */ + LSM_ODR_15_HZ = 0x10, /*!< Output Data Rate = 15 Hz */ + LSM_ODR_30_HZ = 0x14, /*!< Output Data Rate = 30 Hz */ + LSM_ODR_75_HZ = 0x18, /*!< Output Data Rate = 75 Hz */ + LSM_ODR_220_HZ = 0x1C /*!< Output Data Rate = 220 Hz */ +}MagOutputDataRate; + + +/** + * @brief Magnetometer Full Scale + */ +typedef enum +{ + LSM_FS_1_3_GA = 0x20, /*!< Full scale = ±1.3 Gauss */ + LSM_FS_1_9_GA = 0x40, /*!< Full scale = ±1.9 Gauss */ + LSM_FS_2_5_GA = 0x60, /*!< Full scale = ±2.5 Gauss */ + LSM_FS_4_0_GA = 0x80, /*!< Full scale = ±4.0 Gauss */ + LSM_FS_4_7_GA = 0xA0, /*!< Full scale = ±4.7 Gauss */ + LSM_FS_5_6_GA = 0xC0, /*!< Full scale = ±5.6 Gauss */ + LSM_FS_8_1_GA = 0xE0 /*!< Full scale = ±8.1 Gauss */ +}MagFullScale; + + +/** + * @brief Magnetometer Working Mode + */ +typedef enum +{ + LSM_CONTINUOS_CONVERSION = 0x00, /*!< Continuous-Conversion Mode */ + LSM_SINGLE_CONVERSION = 0x01, /*!< Single-Conversion Mode */ + LSM_SLEEP = 0x02 /*!< Sleep Mode */ +}MagWorkingMode; + + + +/** + * @brief Magnetometer Init structure definition + */ +typedef struct +{ + MagOutputDataRate xOutputDataRate; /*!< Magnetometer Output data Rate */ + MagFullScale xFullScale; /*!< Full Scale Configuration */ + MagWorkingMode xWorkingMode; /*!< Mode Configuration: Continuos, Single or Sleep Mode */ + LSMFunctionalState xTemperatureSensor; /*!< Temperature sensor enabling/disabling */ +}LSMMagInit; + + +/** + * @brief Magnetometer data status. It notifies if data on axis are available or overrun. + */ +typedef struct +{ + uint8_t xDataReady:1; /*!< DataReady bit flag */ + uint8_t xDataLock:1; /*!< DataLock bit flag */ + uint8_t :6; /*!< RFU */ +}LSMMDataStatus; + +/** + * @} + */ + +/** + * @defgroup Magnetometer_Exported_Constants Magnetometer Exported Constants + * @{ + */ + +/** + * @defgroup Magnetometer_Sensitivity Magnetometer Sensitivity + * @{ + */ + +#define LSM_Magn_Sensitivity_XY_1_3Ga 1100 /*!< magnetometer X Y axes sensitivity for 1.3 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_1_9Ga 855 /*!< magnetometer X Y axes sensitivity for 1.9 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_2_5Ga 670 /*!< magnetometer X Y axes sensitivity for 2.5 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_4Ga 450 /*!< magnetometer X Y axes sensitivity for 4 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_4_7Ga 400 /*!< magnetometer X Y axes sensitivity for 4.7 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_5_6Ga 330 /*!< magnetometer X Y axes sensitivity for 5.6 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_XY_8_1Ga 230 /*!< magnetometer X Y axes sensitivity for 8.1 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_1_3Ga 980 /*!< magnetometer Z axis sensitivity for 1.3 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_1_9Ga 760 /*!< magnetometer Z axis sensitivity for 1.9 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_2_5Ga 600 /*!< magnetometer Z axis sensitivity for 2.5 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_4Ga 400 /*!< magnetometer Z axis sensitivity for 4 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_4_7Ga 355 /*!< magnetometer Z axis sensitivity for 4.7 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_5_6Ga 295 /*!< magnetometer Z axis sensitivity for 5.6 Ga full scale [LSB/Ga] */ +#define LSM_Magn_Sensitivity_Z_8_1Ga 205 /*!< magnetometer Z axis sensitivity for 8.1 Ga full scale [LSB/Ga] */ + +/** + * @} + */ + + +/** + * @defgroup Temperature_Sensitivity Temperature Sensitivity + * @{ + */ +#define LSM_Temp_Sensitivity 8 /*!< temperature sensitivity [LSB/deg] */ + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @defgroup Magnetometer_Exported_Macros Magnetometer Exported Macros + * @{ + */ + +/** @defgroup Magnetometer_I2C_Communication Magnetometer I2C Communication + * @{ + */ +#define Lsm303dlhcMagI2CBufferRead(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferRead(LSM_M_I2C_ADDRESS,pVal,cAddress,nBytes) +#define Lsm303dlhcMagI2CBufferWrite(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferWrite(LSM_M_I2C_ADDRESS,pVal,cAddress,nBytes) + +#define Lsm303dlhcMagI2CByteRead(pVal,cAddress) Lsm303dlhcMagI2CBufferRead(pVal,cAddress,1) +#define Lsm303dlhcMagI2CByteWrite(pVal,cAddress) Lsm303dlhcMagI2CBufferWrite(pVal,cAddress,1) + +/** + * @} + */ + +/** + *@} + */ + +/** + * @defgroup Magnetometer_Register_Mapping Magnetometer Register Mapping + * @{ + */ + +/** + * @brief Magnetometer I2C Slave Address + */ +#define LSM_M_I2C_ADDRESS 0x3D + + +/** + * @brief Magnetometer Control Register A + * \code + * Read Write + * Default value: 0x10 + * 7 TEMP_EN: Temperature sensor enabling. 0: temperature sensor disabled; 1: temperature sensor enabled + * 6:5 0: They shall be zero for correct working of the device + * 4:2 DO2-DO0: Data Output Rate Bits + * DO2 | DO1 | DO0 | Minimum Data Output Rate (Hz) + * ------------------------------------------------------ + * 0 | 0 | 0 | 0.75 + * 0 | 0 | 1 | 1.5 + * 0 | 1 | 0 | 3.0 + * 0 | 1 | 1 | 7.5 + * 1 | 0 | 0 | 15(default) + * 1 | 0 | 1 | 30 + * 1 | 1 | 0 | 75 + * 1 | 1 | 1 | 220 + * 1:0 0: They shall be zero for correct working of the device + * \endcode + */ +#define LSM_M_CRA_REG_ADDR 0x00 + + +/** + * @brief Magnetometer Control Register B + * \code + * Read/Write + * Default value: 0x20 + * 7:5 GN2-GN0: Gain Configuration Bits + * GN2 | GN1 | GN0 | Mag Input | Gain X, Y | Gain Z | Output Range + * | | | Range[Ga] | [LSB/Gauss] | [LSB/Gauss] | + * ------------------------------------------------------------------------------------------- + * 0 | 0 | 0 | NA | NA | NA | 0xF800–0x07FF (-2048:2047) + * 0 | 0 | 1 | ±1.3 | 1100 | 980 | "" + * 0 | 1 | 0 | ±1.9 | 855 | 760 | "" + * 0 | 1 | 1 | ±2.5 | 670 | 600 | "" + * 1 | 0 | 0 | ±4.0 | 450 | 400 | "" + * 1 | 0 | 1 | ±4.7 | 400 | 355 | "" + * 1 | 1 | 0 | ±5.6 | 330 | 295 | "" + * 1 | 1 | 1 | ±8.1 | 230 | 205 | "" + * 4:0 0: They shall be zero for correct working of the device + * \endcode + */ +#define LSM_M_CRB_REG_ADDR (uint8_t) 0x01 + + +/** + * @brief Magnetometer Mode Register + * \code + * Read/Write + * Default value: 0x02 + * 7:2 0: They shall be zero for correct working of the device + * 1:0 MD1-MD0: Mode Select Bits + * MD1 | MD0 | MODE + * ------------------------------ + * 0 | 0 | Continuous-Conversion Mode. + * 0 | 1 | Single-Conversion Mode + * 1 | 0 | Sleep Mode. Device is placed in sleep mode. + * 1 | 1 | Sleep Mode. Device is placed in sleep mode. + * \endcode + */ +#define LSM_M_MR_REG_ADDR (uint8_t) 0x02 + + +/** + * @brief Magnetometer X-axis Magnetic Field Data MSB register. + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * endcode + */ +#define LSM_M_OUT_X_H_ADDR 0x03 + + +/** + * @brief Magnetometer X-axis Magnetic Field Data LSB register + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * \endcode + */ +#define LSM_M_OUT_X_L_ADDR 0x04 + + +/** + * @brief Magnetometer Z-axis Magnetic Field Data MSB register + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * \endcode + */ +#define LSM_M_OUT_Z_H_ADDR 0x05 + + +/** + * @brief Magnetometer Z-axis Magnetic Field Data LSB register + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * \endcode + */ +#define LSM_M_OUT_Z_L_ADDR 0x06 + + +/** + * @brief Magnetometer Y-axis Magnetic Field Data MSB register + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * \endcode + */ +#define LSM_M_OUT_Y_H_ADDR 0x07 + + +/** + * @brief Magnetometer Y-axis Magnetic Field Data LSB register + * The value (MSB+LSB) is expressed as 16bit two’s complement + * \code + * Read + * Default value: + * \endcode + */ +#define LSM_M_OUT_Y_L_ADDR 0x08 + + +/** + * @brief Magnetometer Status Register + * \code + * Read Only + * Default value: 0x00 + * 7:2 0: They shall be zero for correct working of the device + * 1 LOCK: Data output register lock.Once a new set of measurements is available, this bit is set when the first magnetic file data register has been read. + * 0 RDY: Data ready bit. This bit is set when a new set of measurements are available + * \endcode + */ +#define LSM_M_SR_REG_ADDR 0x09 + + +/** + * \brief Magnetometer Identification Register A + * \code + * Read + * Default value: 0x48 + * \endcode + */ +#define LSM_M_IRA_REG_ADDR 0x0A + + +/** + * @brief Magnetometer Identification Register B + * \code + * Read + * Default value: 0x34 + * \endcode + */ +#define LSM_M_IRB_REG_ADDR 0x0B + + +/** + * @brief Magnetometer Identification Register C + * \code + * Read + * Default value: 0x33 + * \endcode + */ +#define LSM_M_IRC_REG_ADDR 0x0C + + +/** + * @brief Temperature Data MSB register + * The value (MSB+LSB) is expressed as 12bit two’s complement with a sensitivity of 8LSB/deg + * \code + * Read + * Default value: + * 7:0 TEMP11-TEMP4: MSB byte of temperature data. + * \endcode + */ +#define LSM_M_TEMP_H_REG_ADDR 0x31 + + +/** + * @brief Temperature Data LSB register + * The value (MSB+LSB) is expressed as 12bit two’s complement with a sensitivity of 8LSB/deg + * \code + * Read + * Default value: + * 7:4 TEMP3-TEMP0: LSB byte of temperature data. + * 3-0 -: Do not consider. + * \endcode + */ +#define LSM_M_TEMP_L_REG_ADDR 0x32 + + +/** + * @} + */ + + +/** @defgroup Magnetometer_Exported_Functions Magnetometer Exported Functions + * @{ + */ + + +void Lsm303dlhcMagConfig(LSMMagInit* pxLSMMagInitStruct); +void Lsm303dlhcMagGetInfo(LSMMagInit* pxLSMMagInitStruct); +void Lsm303dlhcMagSetFullScale(MagFullScale xFullScale); +MagFullScale Lsm303dlhcMagGetEnumFullScale(void); +void Lsm303dlhcMagGetSensitivity(float *pfSensitivityXYZ); +float Lsm303dlhcMagGetFullScale(void); +void Lsm303dlhcMagSetDataRate(MagOutputDataRate xDataRate); +MagOutputDataRate Lsm303dlhcMagGetEnumDataRate(void); +float Lsm303dlhcMagGetDataRate(void); +void Lsm303dlhcMagReadMag(float* pfData); +void Lsm303dlhcMagReadRawData(int16_t* pnRawData); +int16_t Lsm303dlhcMagReadRawDataTemp(void); +float Lsm303dlhcMagReadTemp(void); +LSMMDataStatus Lsm303dlhcMagGetDataStatus(void); +void Lsm303dlhcMagDataReadyIrqConfig(LSMFunctionalState xFunctionalState); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LSM303DLHC_H */ + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ + diff --git a/lib/LSM303DLHC/src/LSM303DLHC.c b/lib/LSM303DLHC/src/LSM303DLHC.c new file mode 100755 index 0000000..d937956 --- /dev/null +++ b/lib/LSM303DLHC/src/LSM303DLHC.c @@ -0,0 +1,1531 @@ +/** + * @file LSM303DLH.c + * @author ART Team IMS-Systems Lab + * @version V2.3.0 + * @date 12 April 2012 + * @brief This file provides a set of functions needed to manage the LSM303DLH slave. + * @details + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * THIS SOURCE CODE IS PROTECTED BY A LICENSE. + * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED + * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE. + * + *

© COPYRIGHT 2012 STMicroelectronics

+ */ + + +/* Includes */ +#include "LSM303DLHC.h" + + + +/** + * @addtogroup Sensor_Libraries Sensor Libraries + * @{ + */ + +/** +* @defgroup LSM303DLHC +* @{ +*/ + +/** + * @addtogroup Accelerometer + * @{ + */ + +/** + * @defgroup Accelerometer_Private_TypesDefinitions Accelerometer Private TypesDefinitions + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Accelerometer_Private_Defines Accelerometer Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Accelerometer_Private_Macros Accelerometer Private Macros + * @{ + */ + +#define LSM_ABS(a) (a>0?(a):-(a)) +/** + *@} + */ + + +/** + * @defgroup Accelerometer_Private_Variables Accelerometer Private Variables + * @{ + */ + + + +/** + *@} + */ + + + +/** + * @defgroup Accelerometer_Private_FunctionPrototypes Accelerometer Private FunctionPrototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Accelerometer_Private_Functions Accelerometer Private Functions + * @{ + */ + +/** +* @brief Set configuration of Linear Acceleration measurement of LSM303DLHC +* @param pxLSMAccInitStruct : pointer to a LSMAccInit structure that contains the configuration setting for the Accelerometer LSM303DLH. +* @retval None. +* @details +* Example: +* @code +* LSMAccInit LSMAccInitStructure; +* +* LSMAccInitStructure.xPowerMode = LSM_NORMAL_MODE; +* LSMAccInitStructure.xOutputDataRate = LSM_ODR_400_HZ; +* LSMAccInitStructure.xEnabledAxes= LSM_ALL_AXES_EN; +* LSMAccInitStructure.xFullScale = LSM_FS_2G; +* LSMAccInitStructure.xDataUpdate = LSM_CONTINUOS_UPDATE; +* LSMAccInitStructure.xEndianness = LSM_BIG_ENDIAN; +* LSMAccInitStructure.xHighResolution = LSM_ENABLE; +* +* Lsm303dlhcAccConfig(&LSMAccInitStructure); +* @endcode +*/ +void Lsm303dlhcAccConfig(LSMAccInit* pxLSMAccInitStruct) +{ + uint8_t CTRL1 = 0x00, CTRL4 = 0x00; + + /* Read the CTRL4 register content */ + Lsm303dlhcAccI2CByteRead(&CTRL4, LSM_A_CTRL4_REG_ADDR); + + /* Compute the register values */ + CTRL1 |= (uint8_t) ((uint8_t)pxLSMAccInitStruct->xPowerMode | (uint8_t)pxLSMAccInitStruct->xOutputDataRate | (uint8_t)pxLSMAccInitStruct->xEnabledAxes); + CTRL4 |= (uint8_t) ((uint8_t)pxLSMAccInitStruct->xFullScale | (uint8_t)pxLSMAccInitStruct->xDataUpdate | (uint8_t)pxLSMAccInitStruct->xEndianness); + if(pxLSMAccInitStruct->xHighResolution == LSM_ENABLE) + { + CTRL4 |= 0x08; + } + else + { + CTRL4 &= 0xF0; + } + + /* Write the computed values on registers */ + Lsm303dlhcAccI2CByteWrite(&CTRL1, LSM_A_CTRL1_REG_ADDR); + Lsm303dlhcAccI2CByteWrite(&CTRL4, LSM_A_CTRL4_REG_ADDR); + +} + + +/** +* @brief Gets the general configuration of LSM303DLHC for the linear acceleration. +* @param pxLSMAccInitStruct : pointer to a LSMAccInit structure that will +* contain the configuration setting read from the LSM303DLHC registers. +* @retval None +*/ +void Lsm303dlhcAccGetInfo(LSMAccInit* pxLSMAccInitStruct) +{ + uint8_t CTRL1, CTRL4; + + /* Read the registers content */ + Lsm303dlhcAccI2CByteRead(&CTRL4, LSM_A_CTRL4_REG_ADDR); + Lsm303dlhcAccI2CByteRead(&CTRL1, LSM_A_CTRL1_REG_ADDR); + + /* Fill the structure fields from CTRL1 reg info */ + pxLSMAccInitStruct->xPowerMode = (AccPowerMode)(CTRL1 & 0x08); + pxLSMAccInitStruct->xOutputDataRate = (AccOutputDataRate)(CTRL1 & 0xF0); + pxLSMAccInitStruct->xEnabledAxes = (AccAxesEnabling)(CTRL1 & 0x07); + + /* Fill the structure fields from CTRL4 reg info */ + pxLSMAccInitStruct->xFullScale = (AccFullScale)(CTRL4 & 0x30); + pxLSMAccInitStruct->xDataUpdate = (AccBlockDataUpdate)(CTRL4 & 0x80); + pxLSMAccInitStruct->xEndianness = (AccEndianness)(CTRL4 & 0x40); + + if(CTRL4 & 0x08) + pxLSMAccInitStruct->xHighResolution = LSM_ENABLE; + else + pxLSMAccInitStruct->xHighResolution = LSM_DISABLE; + +} + + +/** +* @brief Set configuration of Internal High Pass Filter of LSM303DLHC for the linear acceleration +* @param pxLSMAccFilterInitStruct : pointer to a LSMAccFilterInit structure that +* contains the configuration setting for the LSM303DLHC. +* @retval None +* @details +* Example: +* @code +* LSMAccFilterInit LSMAccFilterInitStructure; +* +* LSMAccFilterInitStructure.xHPF=LSM_DISABLE; +* LSMAccFilterInitStructure.xHPF_Mode=LSM_HPFM_NORMAL; +* LSMAccFilterInitStructure.cHPFReference=0x00; +* LSMAccFilterInitStructure.xHPFCutOff=LSM_HPCF_16; +* LSMAccFilterInitStructure.xHPFClick=LSM_DISABLE; +* LSMAccFilterInitStructure.xHPFAOI2=LSM_DISABLE; +* LSMAccFilterInitStructure.xHPFAOI1=LSM_DISABLE; +* +* Lsm303dlhcAccFilterConfig(&LSMAccFilterInitStructure); +* @endcode +*/ +void Lsm303dlhcAccFilterConfig(LSMAccFilterInit* pxLSMAccFilterInitStruct) +{ + uint8_t CTRL2 = 0x00; + uint8_t REF = 0x00; + + /* Compute the register values */ + CTRL2 |= (uint8_t) ((uint8_t)pxLSMAccFilterInitStruct->xHPF_Mode| (uint8_t)pxLSMAccFilterInitStruct->xHPFCutOff); + if(pxLSMAccFilterInitStruct->xHPF == LSM_ENABLE) + { + CTRL2 |= 0x08; + } + else + { + CTRL2 &= 0xF7; + } + if(pxLSMAccFilterInitStruct->xHPFClick == LSM_ENABLE) + { + CTRL2 |= 0x04; + } + else + { + CTRL2 &= 0xFB; + } + if(pxLSMAccFilterInitStruct->xHPFAOI2 == LSM_ENABLE) + { + CTRL2 |= 0x02; + } + else + { + CTRL2 &= 0xFD; + } + if(pxLSMAccFilterInitStruct->xHPFAOI1 == LSM_ENABLE) + { + CTRL2 |= 0x01; + } + else + { + CTRL2 &= 0xFE; + } + + REF |= (uint8_t) (pxLSMAccFilterInitStruct->cHPFReference); + + /* Write the computed values on registers */ + Lsm303dlhcAccI2CByteWrite(&CTRL2, LSM_A_CTRL2_REG_ADDR); + Lsm303dlhcAccI2CByteWrite(&REF, LSM_A_REFERENCE_REG_ADDR); +} + + +/** +* @brief Get configuration of Internal High Pass Filter of LSM303DLHC for the linear acceleration +* @param pxLSMAccFilterInitStruct : pointer to a LSMAccFilterInit structure that will +* contain the configuration setting read from the LSM303DLHC registers. +* @retval None +*/ +void Lsm303dlhcAccFilterGetInfo(LSMAccFilterInit* pxLSMAccFilterInitStruct) +{ + uint8_t ctrl2, ref; + + Lsm303dlhcAccI2CByteRead(&ctrl2, LSM_A_CTRL2_REG_ADDR); + Lsm303dlhcAccI2CByteRead(&ref, LSM_A_REFERENCE_REG_ADDR); + + /* Get the filter mode and the cut-off frequency */ + pxLSMAccFilterInitStruct->xHPF_Mode = (AccHPFMode)(ctrl2 & 0xC0); + pxLSMAccFilterInitStruct->xHPFCutOff = (AccHPFCutOff)(ctrl2 & 0x30); + + /* Get the enable/disable filter bit */ + if(ctrl2 & 0x08) + pxLSMAccFilterInitStruct->xHPF = LSM_ENABLE; + else + pxLSMAccFilterInitStruct->xHPF = LSM_DISABLE; + + /* Get the enable/disable filter for click bit */ + if(ctrl2 & 0x04) + pxLSMAccFilterInitStruct->xHPFClick = LSM_ENABLE; + else + pxLSMAccFilterInitStruct->xHPFClick = LSM_DISABLE; + + /* Get the enable/disable int2 bit */ + if(ctrl2 & 0x02) + pxLSMAccFilterInitStruct->xHPFAOI2 = LSM_ENABLE; + else + pxLSMAccFilterInitStruct->xHPFAOI2 = LSM_DISABLE; + + /* Get the enable/disable int1 bit */ + if(ctrl2 & 0x01) + pxLSMAccFilterInitStruct->xHPFAOI1 = LSM_ENABLE; + else + pxLSMAccFilterInitStruct->xHPFAOI1 = LSM_DISABLE; + + /* Get the reference value */ + pxLSMAccFilterInitStruct->cHPFReference=ref; + +} + + +/** +* @brief Enable or disable the lowpower mode for Accelerometer of LSM303DLHC +* @param xFunctionalState : new state for the lowpower mode. This parameter can be: LSM_ENABLE or LSM_DISABLE +* @retval None +*/ +void Lsm303dlhcAccLowPowerMode(LSMFunctionalState xFunctionalState) +{ + uint8_t tmpreg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL1_REG_ADDR); + + /* modify the specified bit */ + if(xFunctionalState == LSM_ENABLE) + { + tmpreg |= 0x08; + } + else + { + tmpreg &= 0xF7; + } + + /* Write the computed values on registers */ + Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL1_REG_ADDR); +} + + +/** +* @brief Change the ODR(Output data rate) for Acceleromter of LSM303DLH +* @param xDataRate : new ODR value. This parameter can be one of the AccOutputDataRate value +* @retval None +*/ +void Lsm303dlhcAccSetDataRate(AccOutputDataRate xDataRate) +{ + uint8_t tmpreg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL1_REG_ADDR); + tmpreg &= 0x0F; + tmpreg |= (uint8_t) xDataRate; + + /* Write computed byte onto register */ + Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL1_REG_ADDR); +} + + +/** +* @brief Returns the output data rate as a AccOutputDataRate enumerative value. +* @param None. +* @retval AccOutputDataRate: AccOutputDataRate enumerative value. +*/ +AccOutputDataRate Lsm303dlhcAccGetEnumDataRate(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL1_REG_ADDR); + + /* mask and return it */ + return((AccOutputDataRate)(tmpReg & 0xF0)); + +} + + +/** +* @brief Returns the output data rate. +* @param None. +* @retval Datarate in Hz. +* This parameter is an uint16_t. +*/ +uint16_t Lsm303dlhcAccGetDataRate(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL1_REG_ADDR); + + /* ..mask it */ + tmpReg &= 0xF0; + + /* return the correspondent value */ + switch(tmpReg){ + case LSM_ODR_1_HZ: + return 1; + case LSM_ODR_10_HZ: + return 10; + case LSM_ODR_25_HZ: + return 25; + case LSM_ODR_50_HZ: + return 50; + case LSM_ODR_100_HZ: + return 100; + case LSM_ODR_200_HZ: + return 200; + case LSM_ODR_400_HZ: + return 400; + case LSM_ODR_1620_HZ: + return 1620; + case LSM_ODR_1344_HZ: + return 1344; + } + + return 0; +} + +/** +* @brief Change the Full Scale of LSM303DLH +* @param xFullScale : new full scale value. This parameter can be one of the AccFullScale value +* @retval None +*/ +void Lsm303dlhcAccSetFullScale(AccFullScale xFullScale) +{ + uint8_t tmpreg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL4_REG_ADDR); + + /* Compute the value */ + tmpreg &= 0xCF; + tmpreg |= (uint8_t) xFullScale; + + /* Write the computed value */ + Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL4_REG_ADDR); +} + + +/** +* @brief Returns the Full Scale of LSM303DLH as a AccFullScale enumerative value. +* @param None. +* @retval AccFullScale: Abs value of Fullscale typdef. +*/ +AccFullScale Lsm303dlhcAccGetEnumFullScale(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR); + + /* Return the enumerative type value */ + return((AccFullScale)(tmpReg & 0x30)); + +} + + +/** +* @brief Returns the Full Scale of LSM303DLH expressed in g. +* @param None. +* @retval uint8_t: Abs value of Fullscale expressed in g. +*/ +uint8_t Lsm303dlhcAccGetFullScale(void) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR); + tmpReg &= 0x30; + + /* return the correspondent value */ + switch(tmpReg) + { + case LSM_FS_2G: + return 2; + case LSM_FS_4G: + return 4; + case LSM_FS_8G: + return 8; + case LSM_FS_16G: + return 16; + } + + return 0; +} + + +/** +* @brief Returns the Full Scale of LSM303DLH expressed in LSB/mg. +* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored. +* This parameter is a pointer to a float array. +* @retval None. +*/ +void Lsm303dlhcAccGetSensitivity(float *pfSensitivityXYZ) +{ + uint8_t tmpReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR); + tmpReg &= 0x30; + + /* return the correspondent value */ + switch(tmpReg) + { + case LSM_FS_2G: + pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_2g; + pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_2g; + pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_2g; + + break; + case LSM_FS_4G: + pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_4g; + pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_4g; + pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_4g; + + break; + case LSM_FS_8G: + pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_8g; + pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_8g; + pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_8g; + + break; + case LSM_FS_16G: + pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_16g; + pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_16g; + pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_16g; + + break; + } + + +} + +/** +* @brief Reboot memory content of LSM303DLH +* @param None +* @retval None +*/ +void Lsm303dlhcAccRebootCmd(void) +{ + uint8_t tmpreg; + Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL2_REG_ADDR); + tmpreg |= 0x80; + Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL2_REG_ADDR); +} + + +/** +* @brief Read LSM303DLHC linear acceleration output register +* @param out : buffer to store data +* @retval None +*/ +void Lsm303dlhcAccReadOutReg(uint8_t* pcReg) +{ + /* Read the register content */ + Lsm303dlhcAccI2CBufferRead(pcReg, LSM_A_OUT_X_L_REG_ADDR, 6); +} + + +/** +* @brief Read LSM303DLHC output register, and calculate the raw acceleration [LSB] ACC= (out_h*256+out_l)/16 (12 bit rappresentation) +* @param pnRawData: pointer to signed 16-bit data buffer where to store data +* @retval None +*/ +void Lsm303dlhcAccReadRawData(int16_t* pnRawData) +{ + uint8_t buffer[6], ctrlx[2], cDivider; + + /* Read the register content */ + Lsm303dlhcAccI2CBufferRead(ctrlx, LSM_A_CTRL4_REG_ADDR,2); + Lsm303dlhcAccReadOutReg(&buffer[0]); + + + if(ctrlx[1]&0x40) + cDivider=64; + else + cDivider=16; + + /* check in the control register4 the data alignment*/ + if(!(ctrlx[0] & 0x40) || (ctrlx[1] & 0x40)) /* Little Endian Mode or FIFO mode */ + { + for(int i=0; i<3; i++) + { + pnRawData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i])/cDivider; + } + } + else /* Big Endian Mode */ + { + for(uint8_t i=0; i<3; i++) + pnRawData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])/cDivider; + } +} + + +/** +* @brief Read LSM303DLHC output register, and calculate the acceleration ACC=(1/SENSITIVITY)* (out_h*256+out_l)/16 (12 bit rappresentation) +* @param pnData: pointer to float buffer where to store data +* @retval None +*/ +void Lsm303dlhcAccReadAcc(float* pfData) +{ + int16_t buffer[3]; + uint8_t ctrlx[2]; + float LSM_Acc_Sensitivity; + + /* Read the raw data */ + Lsm303dlhcAccReadRawData(buffer); + + /* Read the register content */ + Lsm303dlhcAccI2CBufferRead(ctrlx, LSM_A_CTRL4_REG_ADDR,2); + + + if(ctrlx[1]&0x40){ + /* FIFO mode */ + LSM_Acc_Sensitivity = 0.25; + } + else + { + /* normal mode */ + /* switch the sensitivity value set in the CRTL4*/ + switch(ctrlx[0] & 0x30) + { + case LSM_FS_2G: + LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_2g; + break; + case LSM_FS_4G: + LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_4g; + break; + case LSM_FS_8G: + LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_8g; + break; + case LSM_FS_16G: + LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_16g; + break; + } + } + + /* Obtain the mg value for the three axis */ + for(uint8_t i=0; i<3; i++) + { + pfData[i]=(float)buffer[i]/LSM_Acc_Sensitivity; + } + +} + + +/** +* @brief Read LSM303DLHC output register when FIFO mode is active. +* @param pnData: pointer to signed integer buffer where to store data. +* This parameter is an int16_t array pointer. +* @param cDataToRead: number of samples to read. Each sample is made up of the three axis readings. +* This parameter is an uint8_t . +* @retval None +*/ +void Lsm303dlhcAccReadAccFifo(int16_t* pnData, uint8_t cDataToRead) +{ + uint8_t *pcBuffer=(uint8_t*)pnData; + uint8_t j=0; + + /* Read the register content */ + Lsm303dlhcAccI2CBufferRead(pcBuffer, LSM_A_OUT_X_L_REG_ADDR, cDataToRead*6); + + /* convert all data to signed int16 */ + for(uint16_t i=0 ; iExample: +* @code +* ... +* ExtiConfiguration(); // set the micro exti before init +* Lsm303dlhcAccIrq1Config(LSM_I1_DRDY1,LSM_ENABLE); // for example enable the data_ready IRQ on line1 +* ... +* @endcode +*/ +void Lsm303dlhcAccIrq1Config(LSMAIrq1List xLSMAIrq1Config, LSMFunctionalState xNewState) +{ + uint8_t tempReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_CTRL3_REG_ADDR); + + /* Unmask the selected IRQ */ + if(xNewState) + tempReg |= (uint8_t)xLSMAIrq1Config; + else + tempReg &= ~(uint8_t)xLSMAIrq1Config; + + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL3_REG_ADDR); + +} + + +/** +* @brief Sets the IRQ2 line to be raised on a specific event. +* @param xLSMAIrq2Config: Interrupt mask to enable. +* This parameter is a @ref LSMAIrq2List . +* @param xNewState: Enable or disable I2. +* This parameter can be LSM_ENABLE or LSM_DISABLE. +* @retval None +*/ +void Lsm303dlhcAccIrq2Config(LSMAIrq2List xLSMAIrq2Config, LSMFunctionalState xNewState) +{ + uint8_t tempReg; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_CTRL6_REG_ADDR); + + /* Unmask the selected IRQ */ + if(xNewState) + tempReg |= (uint8_t)xLSMAIrq2Config; + else + tempReg &= ~(uint8_t)xLSMAIrq2Config; + + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL6_REG_ADDR); + +} + + +/** +* @brief Configures the sensor FIFO. +* @param xNewState: New state for the FIFO use. +* This parameter is a @ref LSMFunctionalState +* @retval None +*/ +void Lsm303dlhcAccFifo(LSMFunctionalState xNewState) +{ + /* Built the byte to be written */ + uint8_t tempReg; + + /* Read the value on the CTRL5 register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL5_REG_ADDR); + + /* Build the value to write */ + if(xNewState == LSM_ENABLE) + tempReg |= 0x40; + else + tempReg &= (~0x40); + + /* Write the built value on the CTRL5 register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL5_REG_ADDR); + +} + + +/** +* @brief Configures the sensor FIFO. +* @param pxLSMAccFifoInit: pointer to the Fifo initialization structure. +* This parameter is a pointer to a @ref LSMAccFifoInit. +* @note This function won't enable the FIFO. Please call the @ref Lsm303dlhcAccFifo in order to enable this mode. +* @retval None +*/ +void Lsm303dlhcAccFifoInit(LSMAccFifoInit* pxLSMAccFifoInit) +{ + /* Built the byte to be written */ + uint8_t tempReg = (pxLSMAccFifoInit->xFifoMode | (pxLSMAccFifoInit->cWtm & 0x1F)); + + /* Select the INT line */ + if(pxLSMAccFifoInit->xTriggerSel == LSM_INT2_LINE) + tempReg |= 0x20; + + /* Write the built value on the FIFO_CTRL register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_FIFO_CTRL_REG_ADDR); + +} + + +/** +* @brief Gets the FIFO status flags and unread data. +* @param pxLSMAccFifoStatus: pointer to the Fifo status structure. +* This parameter is a pointer to a @ref LSMAccFifoStatus +* @retval None +*/ +LSMAccFifoStatus Lsm303dlhcAccFifoGetStatus(void) +{ + LSMAccFifoStatus xLSMAccFifoStatus; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead((uint8_t*)&xLSMAccFifoStatus, LSM_A_FIFO_STATUS_REG_ADDR); + + /* Return its value */ + return xLSMAccFifoStatus; +} + + +/** +* @brief Sets the IRQs on Axis. +* @param xIrqCombinations: Combination of events on axis. +* This parameter is a @ref LSMAccIrqOnaxisCombination . +* @param pxAxisEvents: Events on axis structure. +* This parameter is a pointer to a @ref LSMAccAxisEvents . +* @param xIRQLine: IRQ line to be set. +* This parameter is a @ref LSMAIrqLine . +* @param xLatched: specifies if an IRQ is latched. +* This parameter can be LSM_ENABLE or LSM_DISABLE . +* @retval None +*/ +void Lsm303dlhcAccSetAxisIrqs(LSMAccIrqOnaxisCombination xIrqCombinations, LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine, LSMFunctionalState xLatched) +{ + + /* Build the value to build on register */ + uint8_t tempReg = ((uint8_t)xIrqCombinations) | (*(uint8_t*)pxAxisEvents); + uint8_t tempLatch; + + /* Read for latch conf */ + Lsm303dlhcAccI2CByteRead(&tempLatch, LSM_A_CTRL5_REG_ADDR); + + /* Interrupt line selection */ + if(xIRQLine == LSM_INT1_LINE) + { + /* Write the built value on the LSM_A_INT1_CFG_REG register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT1_CFG_REG_ADDR); + + if(xLatched) + tempLatch |= 0x08; + else + tempLatch &= 0xF7; + } + else + { + /* Write the built value on the LSM_A_INT2_CFG_REG register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT2_CFG_REG_ADDR); + + if(xLatched) + tempLatch |= 0x02; + else + tempLatch &= 0xFD; + } + + /* Write for latch conf */ + Lsm303dlhcAccI2CByteWrite(&tempLatch, LSM_A_CTRL5_REG_ADDR); + +} + + +/** +* @brief Gets the IRQs on Axis status. +* @param pxAxisEvents: Events on axis structure. +* This parameter is a pointer to a @ref LSMAccAxisEvents . +* @param xIRQLine: IRQ line mask to be get. +* This parameter is a @ref LSMAIrqLine . +* @retval None +*/ +LSMFunctionalState Lsm303dlhcAccGetAxisIrqs(LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine) +{ + uint8_t tempReg; + + /* Interrupt line selection */ + if(xIRQLine == LSM_INT1_LINE) + { + /* Read the register for the LINE1 */ + Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_INT1_SRC_REG_ADDR); + } + else + { + /* Read the register for the LINE2 */ + Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_INT2_SRC_REG_ADDR); + } + + uint8_t tempRet = tempReg & 0x7F; + + /* Take the MSb to return */ + (*pxAxisEvents)=*(LSMAccAxisEvents*)(&tempRet); + + return (LSMFunctionalState)(tempRet>>6); + +} + + +/** +* @brief Sets threshold for acceleration. +* @param nData: Acceleration threshold. +* This parameter is a uint16_t. +* @param xIRQLine: IRQ threshold mask to be set. +* This parameter is a @ref LSMAIrqLine . +* @retval None +*/ +void Lsm303dlhcAccSetThreshold(int16_t nData, LSMAIrqLine xIRQLine) +{ + uint8_t ctrl4, accThs; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead(&ctrl4, LSM_A_CTRL4_REG_ADDR); + + /* switch the sensitivity value set in the CRTL4*/ + switch(ctrl4 & 0x30) + { + case LSM_FS_2G: + accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_2g); + break; + case LSM_FS_4G: + accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_4g); + break; + case LSM_FS_8G: + accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_8g); + break; + case LSM_FS_16G: + accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_16g); + break; + } + + /* Ensure that the MSb is 0 */ + accThs &= 0x7F; + + /* Interrupt line selection */ + if(xIRQLine == LSM_INT1_LINE) + { + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&accThs, LSM_A_INT1_THS_REG_ADDR); + } + else + { + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&accThs, LSM_A_INT2_THS_REG_ADDR); + } + +} + + +/** +* @brief Sets the minimum duration of an IRQ to be recognized. +* @param cDuration: Duration expressed in ms. +* This parameter is a uint8_t . +* @param xIRQLine: IRQ duration to be set. +* This parameter is a @ref LSMAIrqLine . +* @retval None +*/ +void Lsm303dlhcAccSetIrqDuration(uint8_t cDuration, LSMAIrqLine xIRQLine) +{ + uint8_t tempReg; + + /* Get datarate for time register value computation */ + uint16_t nDatarate = Lsm303dlhcAccGetDataRate(); + + /* Compute the duration register value */ + tempReg=(uint8_t)((float)cDuration/1000*nDatarate); + + if(xIRQLine == LSM_INT1_LINE) + { + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT1_DURATION_REG_ADDR); + } + else + { + /* Write byte on register */ + Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT2_DURATION_REG_ADDR); + } + +} + + +/** +* @brief Configures the Click or Double click recognition parameters. +* @param xClickInit: Click configuration structure. +* This parameter is a pointer to +* @retval None. +*/ +void Lsm303dlhcAccClickInit(LSMAccClickInit* pxClickInit) +{ + uint8_t tempReg[5]; + + /* Get fullscale for threshold register value computation */ + uint8_t cFullscale = Lsm303dlhcAccGetFullScale(); + + /* Get datarate for time register value computation */ + uint16_t nDatarate = Lsm303dlhcAccGetDataRate(); + + /* Read values on register */ + Lsm303dlhcI2CBufferRead(LSM_A_CLICK_SRC_REG_ADDR, tempReg, LSM_A_CTRL4_REG_ADDR, 5); + + /* Sign setting */ + tempReg[0] &= 0x08; + tempReg[0] |= (pxClickInit->xNegativeDetection)<<3; + + /* Threshold value computation */ + tempReg[1] = (uint8_t)((float)pxClickInit->nClickThreshold/1000*(128/cFullscale)); + + /* time limit computation */ + tempReg[2] = (uint8_t)((float)pxClickInit->cClickTimeLimit/1000*nDatarate); + + /* time latency computation */ + tempReg[3] = (uint8_t)((float)pxClickInit->cDClickTimeLatency/1000*nDatarate); + + /* time window computation */ + tempReg[4] = (uint8_t)((float)pxClickInit->cDClickTimeWindow/1000*nDatarate); + + /* Write values on register */ + Lsm303dlhcI2CBufferWrite(LSM_A_CLICK_SRC_REG_ADDR, tempReg, LSM_A_CTRL4_REG_ADDR, 5); + +} + + +/** +* @brief Gets status for accelerometer data. +* @param None. +* @retval LSMADataStatus: Data status in a LSMADataStatus bitfields structure. +*/ +LSMADataStatus Lsm303dlhcAccGetDataStatus(void) +{ + LSMADataStatus xStatus; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead((uint8_t*)&xStatus, LSM_A_STATUS_REG_ADDR); + + return xStatus; + +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @addtogroup Magnetometer + * @{ + */ + + +/** + * @defgroup Magnetometer_Private_TypesDefinitions Magnetometer Private TypesDefinitions + * @{ + */ + + +/** + *@} + */ + + +/** + * @defgroup Magnetometer_Private_Defines Magnetometer Private Defines + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Magnetometer_Private_Macros Magnetometer Private Macros + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Magnetometer_Private_Variables Magnetometer Private Variables + * @{ + */ + +/** + *@} + */ + + + +/** + * @defgroup Magnetometer_Private_FunctionPrototypes Magnetometer Private FunctionPrototypes + * @{ + */ + +/** + *@} + */ + + +/** + * @defgroup Magnetometer_Private_Functions Magnetometer Private Functions + * @{ + */ + +/** +* @brief Set configuration of Magnetic field measurement of LSM303DLHC. +* @param pxLSMMagInitStruct: pointer to LSMMagInit structure that +* contains the configuration setting for the LSM303DLHC Magnetometer part. +* @retval None. +* @details +* Example: +* @code +* LSMMagInit LSMMagInitStructure; +* +* LSMMagInitStructure.xOutputDataRate = LSM_ODR_30_HZ; +* LSMMagInitStructure.xFullScale = LSM_FS_1_3_GA; +* LSMMagInitStructure.xWorkingMode = LSM_CONTINUOS_CONVERSION; +* LSMMagInitStructure.xTemperatureSensor = LSM_ENABLE; +* +* Lsm303dlhcMagConfig(&LSMMagInitStructure); +* @endcode +*/ +void Lsm303dlhcMagConfig(LSMMagInit* pxLSMMagInitStruct) +{ + uint8_t CTRLx[2] = {0x00,0x00}; + uint8_t MODE = 0x00; + + CTRLx[0] |= (uint8_t) (pxLSMMagInitStruct->xOutputDataRate); + if(pxLSMMagInitStruct->xTemperatureSensor == LSM_ENABLE) + CTRLx[0] |= 0x80; + + CTRLx[1] |= (uint8_t) (pxLSMMagInitStruct->xFullScale); + + MODE |= (uint8_t) (pxLSMMagInitStruct->xWorkingMode); + + Lsm303dlhcMagI2CBufferWrite(CTRLx, LSM_M_CRA_REG_ADDR, 2); //CRTL_REGA and B + Lsm303dlhcMagI2CByteWrite(&MODE, LSM_M_MR_REG_ADDR); //Mode register + +} + + +/** +* @brief Gets the general configuration of LSM303DLHC for the magnetometer. +* @param pxLSMMagInitStruct : pointer to a LSMMagInit structure that will +* contain the configuration setting read from the LSM303DLHC registers. +* @retval None +*/ +void Lsm303dlhcMagGetInfo(LSMMagInit* pxLSMMagInitStruct) +{ + uint8_t CTRLx[2]; + uint8_t MODE; + + Lsm303dlhcMagI2CBufferRead(CTRLx, LSM_M_CRA_REG_ADDR, 2); + Lsm303dlhcMagI2CByteRead(&MODE, LSM_M_MR_REG_ADDR); + + /* Get the CTRL[0] info */ + pxLSMMagInitStruct->xOutputDataRate = (MagOutputDataRate)(CTRLx[0] & 0x1C); + + if(CTRLx[0] & 0x80) + pxLSMMagInitStruct->xTemperatureSensor = LSM_ENABLE; + else + pxLSMMagInitStruct->xTemperatureSensor = LSM_DISABLE; + + /* Get the CTRL[1] info */ + pxLSMMagInitStruct->xFullScale = (MagFullScale)(CTRLx[1] & 0xE0); + + /* Get the MODE info */ + pxLSMMagInitStruct->xWorkingMode = (MagWorkingMode)(MODE & 0x03); + +} + + +/** +* @brief Set the full scale of the Magnetic field sensor. +* @param xFullScale: FullScale value. +* This parameter must be a value of @ref MagFullScale . +* @retval None +*/ +void Lsm303dlhcMagSetFullScale(MagFullScale xFullScale) +{ + uint8_t tempReg=(uint8_t) xFullScale; + + /* Write value on register */ + Lsm303dlhcMagI2CByteWrite(&tempReg, LSM_M_CRB_REG_ADDR); + +} + + +/** +* @brief Get the full scale of the Magnetic field sensor expressed as a MagFullScale enumerative value. +* @param None +* @retval MagFullScale: full scale value expressed as a value of the enum typdef. +*/ +MagFullScale Lsm303dlhcMagGetEnumFullScale(void) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR); + + /* Mask and return it */ + return((MagFullScale)(tempReg & 0xE0)); + +} + +/** +* @brief Get the full scale of the Magnetic field sensor. +* @param None +* @retval float: full scale value expressed in gauss. +*/ +float Lsm303dlhcMagGetFullScale(void) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR); + + switch(tempReg) + { + case LSM_FS_1_3_GA: + return 1.3; + case LSM_FS_1_9_GA: + return 1.9; + case LSM_FS_2_5_GA: + return 2.5; + case LSM_FS_4_0_GA: + return 4.0; + case LSM_FS_4_7_GA: + return 4.7; + case LSM_FS_5_6_GA: + return 5.6; + case LSM_FS_8_1_GA: + return 8.1; + } + + return 0.0; +} + + +/** +* @brief Returns the Full Scale of LSM303DLH expressed in LSB/mgauss. +* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored. +* This parameter is a pointer to a float array. +* @retval None. +*/ +void Lsm303dlhcMagGetSensitivity(float *pfSensitivityXYZ) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR); + + switch(tempReg & 0xE0) + { + case LSM_FS_1_3_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_1_3Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_1_3Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_1_3Ga; + break; + case LSM_FS_1_9_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_1_9Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_1_9Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_1_9Ga; + break; + case LSM_FS_2_5_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_2_5Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_2_5Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_2_5Ga; + break; + case LSM_FS_4_0_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_4Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_4Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_4Ga; + break; + case LSM_FS_4_7_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_4_7Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_4_7Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_4_7Ga; + break; + case LSM_FS_5_6_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_5_6Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_5_6Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_5_6Ga; + break; + case LSM_FS_8_1_GA: + pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_8_1Ga; + pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_8_1Ga; + pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_8_1Ga; + break; + } +} +/** +* @brief Set the data rate of the Magnetic field sensor. +* @param xFullScale: Datarate value. +* This parameter must be a value of @ref MagOutputDataRate . +* @retval None +*/ +void Lsm303dlhcMagSetDataRate(MagOutputDataRate xDataRate) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR); + + tempReg &= 0x80; + tempReg |= (uint8_t)xDataRate; + + /* Write value on register */ + Lsm303dlhcMagI2CByteWrite(&tempReg, LSM_M_CRA_REG_ADDR); + +} + + +/** +* @brief Get the data rate of the Magnetic field sensor in the MagOutputDataRate enumerative value. +* @param None +* @retval MagOutputDataRate: data rate value expressed as enum value. +*/ +MagOutputDataRate Lsm303dlhcMagGetEnumDataRate(void) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR); + + /* Mask and return it */ + return((MagOutputDataRate)(tempReg & 0x1C)); + +} + + +/** +* @brief Get the data rate of the Magnetic field sensor. +* @param None +* @retval float: data rate value expressed in gauss. +*/ +float Lsm303dlhcMagGetDataRate(void) +{ + uint8_t tempReg; + + /* Read value on register */ + Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR); + + switch((MagOutputDataRate)(tempReg & 0x1C)) + { + case LSM_ODR_0_75_HZ: + return 0.75; + case LSM_ODR_1_5_HZ: + return 1.5; + case LSM_ODR_7_5_HZ: + return 7.5; + case LSM_ODR_15_HZ: + return 15.0; + case LSM_ODR_30_HZ: + return 30.0; + case LSM_ODR_75_HZ: + return 75.0; + case LSM_ODR_220_HZ: + return 220.0; + } + + return 0.0; +} + + + +/** +* @brief Read LSM303DLHC output register, and calculate the magnetic field Magn[mGa]=(out_h*256+out_l)*1000/ SENSITIVITY +* @param pnData: pointer to signed 16-bit buffer where to store data +* @note Despite the datasheet indications, the read axis will be stored in the passed +* array in the order X,Y,Z. +* @retval None +*/ +void Lsm303dlhcMagReadMag(float* pfData) +{ + uint8_t buffer[6]; + uint8_t CTRLB; + uint16_t LSM_Magn_Sensitivity_XY, LSM_Magn_Sensitivity_Z; + uint8_t aux[2]; + + Lsm303dlhcMagI2CByteRead(&CTRLB, LSM_M_CRB_REG_ADDR); + Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_OUT_X_H_ADDR, 6); + + /* excange Z with Y */ + aux[0]=buffer[2]; + aux[1]=buffer[3]; + + buffer[2]=buffer[4]; + buffer[3]=buffer[5]; + + buffer[4]=aux[0]; + buffer[5]=aux[1]; + + /** switch the sensitivity set in the CRTLB*/ + switch(CTRLB & 0xE0) + { + case LSM_FS_1_3_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_1_3Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_1_3Ga; + break; + case LSM_FS_1_9_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_1_9Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_1_9Ga; + break; + case LSM_FS_2_5_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_2_5Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_2_5Ga; + break; + case LSM_FS_4_0_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_4Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_4Ga; + break; + case LSM_FS_4_7_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_4_7Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_4_7Ga; + break; + case LSM_FS_5_6_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_5_6Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_5_6Ga; + break; + case LSM_FS_8_1_GA: + LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_8_1Ga; + LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_8_1Ga; + break; + } + + for(int i=0; i<2; i++) + { + pfData[i]=(float)((int16_t)(((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])*1000)/LSM_Magn_Sensitivity_XY; + } + pfData[2]=(float)((int16_t)(((uint16_t)buffer[4] << 8) + buffer[5])*1000)/LSM_Magn_Sensitivity_Z; + +} + + +/** +* @brief Read LSM303DLH magnetic field output register and compute the int16_t value. +* @param pnRawData: pointer to signed 16-bit buffer where to store data. +* @note Despite the datasheet indications, the read axis will be stored in the passed +* array in the order X,Y,Z. +* @retval None +*/ +void Lsm303dlhcMagReadRawData(int16_t* pnRawData) +{ + uint8_t buffer[6]; + uint8_t aux[2]; + + Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_OUT_X_H_ADDR, 6); + + /* excange Z with Y */ + aux[0]=buffer[2]; + aux[1]=buffer[3]; + + buffer[2]=buffer[4]; + buffer[3]=buffer[5]; + + buffer[4]=aux[0]; + buffer[5]=aux[1]; + + for(uint8_t i=0; i<3; i++) + pnRawData[i]=(int16_t)(((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]); +} + + +/** +* @brief Reads LSM303DLHC temperature output register, and calculate the Temperature=(out_h*256+out_l)*10/16* SENSITIVITY. +* The temperature is expressed in decimal of degC. The sensitivity is 8 LSB/degC +* @param pnData: pointer to a float where to store data. +* @retval None +*/ +float Lsm303dlhcMagReadTemp(void) +{ + uint8_t buffer[2]; + + /* Read register */ + Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_TEMP_H_REG_ADDR, 2); + + /* convert to float */ + return ((float)((int16_t)(((uint16_t)buffer[0]<<8)+buffer[1])/16)/LSM_Temp_Sensitivity); + +} + + +/** +* @brief Reads LSM303DLHC temperature output register and compute the int16_t value +* @param pnRawData: pointer to signed 16-bit buffer where to store data +* @retval None +*/ +int16_t Lsm303dlhcMagReadRawDataTemp(void) +{ + uint8_t buffer[2]; + + /* Read register */ + Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_TEMP_H_REG_ADDR, 2); + + /* Return the int16 value */ + return ((int16_t)(((uint16_t)buffer[0]<<8)+buffer[1])/16); + +} + + +/** +* @brief Gets status for magnetometer data. +* @param None. +* @retval LSMADataStatus: Data status in a LSMADataStatus bitfields structure. +*/ +LSMMDataStatus Lsm303dlhcMagGetDataStatus(void) +{ + LSMMDataStatus xStatus; + + /* Read the register content */ + Lsm303dlhcAccI2CByteRead((uint8_t*)&xStatus, LSM_M_SR_REG_ADDR); + + return xStatus; +} + + +/** +* @brief Configures the DATA_READY IRQ of the magnetometer. +* @param xNewState: New state for DATA_READY. +* This parameter is a @ref LSMFunctionalState +* @retval None +*/ +void Lsm303dlhcMagDataReadyIrqConfig(LSMFunctionalState xFunctionalState) +{ + uint8_t cTempReg; + + Lsm303dlhcAccI2CByteRead(&cTempReg, LSM_M_SR_REG_ADDR); + + if(xFunctionalState) + cTempReg |= 0x01; + else + cTempReg &= 0xFE; + + Lsm303dlhcAccI2CByteWrite(&cTempReg, LSM_M_SR_REG_ADDR); + +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/ diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..1e75597 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,33 @@ +#TARGET_LIB = libinemo.a + +all: +# $(TARGET_LIB) + +export BOARD = inemo + +include $(ROOTDIR)/common.mk +include config.mk +include $(ROOTDIR)/arch/config.mk +include $(ROOTDIR)/FreeRTOS/config.mk +#include ../uC-sdk/arch/config.mk + +TARGET_SRCS += spi.c +TARGET_SRCS += HAL_L3Gx.c +#TARGET_SRCS += i2c.c +#TARGET_SRCS = iNEMO_Compass/src/iNEMO_Compass.c +#TARGET_SRCS += iNEMO_M1_SensorDrivers/src/iNEMO_I2C_Driver.c +#TARGET_SRCS += iNEMO_M1_SensorDrivers/src/iNemo_SPI_Driver.c +TARGET_SRCS += L3Gx/src/L3Gx.c +#TARGET_SRCS += LPS331AP/src/LPS331AP.c +#TARGET_SRCS += LSM303DLHC/src/LSM303DLHC.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_Desc.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_Endp.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_General.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_Istr.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_Prop.c +#TARGET_SRCS += STMF1_VirtualCom/src/STM32F1_VC_Pwr.c + + +include $(ROOTDIR)/target-rules.mk + +clean: clean-generic diff --git a/lib/config.mk b/lib/config.mk new file mode 100644 index 0000000..d8d72f2 --- /dev/null +++ b/lib/config.mk @@ -0,0 +1,9 @@ +TARGET_INCLUDES += $(MAINDIR)/lib +TARGET_INCLUDES += $(MAINDIR)/lib/iNEMO_Compass/inc +TARGET_INCLUDES += $(MAINDIR)/lib/L3Gx/inc +TARGET_INCLUDES += $(MAINDIR)/lib/LPS331AP/inc +TARGET_INCLUDES += $(MAINDIR)/lib/LSM303DLHC/inc + +ifeq ($(USE_MPU),true) +TARGET_CPPFLAGS += -DportUSING_MPU_WRAPPERS=1 +endif diff --git a/lib/i2c.c b/lib/i2c.c new file mode 100644 index 0000000..d294c90 --- /dev/null +++ b/lib/i2c.c @@ -0,0 +1,391 @@ +#include "i2c.h" +#include "FreeRTOS.h" +#include +#include +#include + +#define FORCE_CRITICAL_SEC + +#define I2C1_DR_Address 0x40005410 +#define I2C2_DR_Address 0x40005810 + +#define I2C1_DMA_CHANNEL_TX DMA1_Channel6 +#define I2C1_DMA_CHANNEL_RX DMA1_Channel7 +#define I2C2_DMA_CHANNEL_TX DMA1_Channel4 +#define I2C2_DMA_CHANNEL_RX DMA1_Channel5 + +#define I2C_DIRECTION_TX 0 +#define I2C_DIRECTION_RX 1 + +#define DMA_BUFFER_SIZE 196 + +/** + * @brief Reads a block of data from the device by DMA. + * @brief I2C2: I2C peripherial to use. + * @param cAddr: slave address. + * @param pcBuffer: pointer to the buffer that receives the data read. + * @param cReadAddr: register internal address to read from. + * @param nNumByteToRead: number of bytes to read. + * @retval None + */ +void iNemoI2CBufferReadDma(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cReadAddr, uint8_t cNumByteToRead) +{ + + __IO uint32_t temp = 0; + __IO uint32_t Timeout = 0; + + /* Enable I2C errors interrupts */ + I2C2->CR2 |= I2C_IT_ERR; + + /* Set the MSb of the register address in case of multiple readings */ + if(cNumByteToRead>1) + cReadAddr |= 0x80; + +#ifdef FORCE_CRITICAL_SEC + __disable_irq(); +#endif + + /* While the bus is busy */ + while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); + + /* Send START condition */ + I2C_GenerateSTART(I2C2, ENABLE); + + /* Test on EV5 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); + + /* Send LSM303DLH address for read */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Transmitter); + + /* Test on EV6 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); + + /* Clear EV6 by setting again the PE bit */ + I2C_Cmd(I2C2, ENABLE); + + /* Send the LSM303DLH_Magn's internal address to write to */ + I2C_SendData(I2C2, cReadAddr); + + /* Test on EV8 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); + + /* Configure I2C2 DMA channel */ + iNemoI2CDMAConfig(I2C2, pcBuffer, cNumByteToRead, I2C_DIRECTION_RX); + + /* Set Last bit to have a NACK on the last received byte */ + I2C2->CR2 |= 0x1000; + + /* Enable I2C DMA requests */ + I2C_DMACmd(I2C2, ENABLE); + Timeout = 0xFFFF; + + /* Send START condition */ + I2C_GenerateSTART(I2C2, ENABLE); + + /* Wait until SB flag is set: EV5 */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) + { + if (Timeout-- == 0) + return; + } + Timeout = 0xFFFF; + + /* Send LSM303DLH address for read */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Receiver); + + /* Wait until ADDR is set: EV6 */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) + { + if (Timeout-- == 0) + return; + } + /* Clear ADDR flag by reading SR2 register */ + temp = I2C2->SR2; + + + + if(I2C2 == I2C2) + { + /* Wait until DMA end of transfer */ + while (!DMA_GetFlagStatus(DMA1_FLAG_TC5)); + /* Disable DMA Channel */ + DMA_Cmd(I2C2_DMA_CHANNEL_RX, DISABLE); + + /* Clear the DMA Transfer Complete flag */ + DMA_ClearFlag(DMA1_FLAG_TC5); + } + else + { + /* Wait until DMA end of transfer */ + while (!DMA_GetFlagStatus(DMA1_FLAG_TC7)); + /* Disable DMA Channel */ + DMA_Cmd(I2C1_DMA_CHANNEL_RX, DISABLE); + + /* Clear the DMA Transfer Complete flag */ + DMA_ClearFlag(DMA1_FLAG_TC7); + } + + + /* Disable Ack for the last byte */ + I2C_AcknowledgeConfig(I2C2, DISABLE); + + /* Send STOP Condition */ + I2C_GenerateSTOP(I2C2, ENABLE); + + /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ + while ((I2C2->CR1 & 0x0200) == 0x0200); + + /* Enable Acknowledgement to be ready for another reception */ + I2C_AcknowledgeConfig(I2C2, ENABLE); + +#ifdef FORCE_CRITICAL_SEC + __enable_irq(); +#endif + +} + + +/** + * @brief Reads a block of data from the device by polling. + * @brief I2C2: I2C peripherial to use. + * @param cAddr: slave address. + * @param pcBuffer: pointer to the buffer that receives the data read. + * @param cReadAddr: register internal address to read from. + * @param nNumByteToRead: number of bytes to read. + * @retval None + */ +void iNemoI2CBufferReadPolling(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cReadAddr, uint8_t cNumByteToRead) +{ + /* Set the MSb of the register address in case of multiple readings */ + if(cNumByteToRead>1) + cReadAddr |= 0x80; + +#ifdef FORCE_CRITICAL_SEC + __disable_irq(); +#endif + + /* While the bus is busy */ + while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); + + /* Send START condition */ + I2C_GenerateSTART(I2C2, ENABLE); + + /* Test on EV5 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); + + /* Send LSM303DLH address for write */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Transmitter); + + /* Test on EV6 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); + + /* Clear EV6 by setting again the PE bit */ + I2C_Cmd(I2C2, ENABLE); + + /* Send the LSM303DLH_Magn's internal address to write to */ + I2C_SendData(I2C2, cReadAddr); + + /* Test on EV8 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); + + /* Send START condition a second time */ + I2C_GenerateSTART(I2C2, ENABLE); + + /* Test on EV5 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); + + /* Send LSM303DLH address for read */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Receiver); + + /* Test on EV6 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); + + /* While there is data to be read */ + while(cNumByteToRead) + { + if(cNumByteToRead == 1) + { + /* Disable Acknowledgement */ + I2C_AcknowledgeConfig(I2C2, DISABLE); + + /* Send STOP Condition */ + I2C_GenerateSTOP(I2C2, ENABLE); + } + + /* Test on EV7 and clear it */ + if(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)) + { + /* Read a byte from the LSM303DLH */ + *pcBuffer = I2C_ReceiveData(I2C2); + + /* Point to the next location where the byte read will be saved */ + pcBuffer++; + + /* Decrement the read bytes counter */ + cNumByteToRead--; + } + } + + /* Enable Acknowledgement to be ready for another reception */ + I2C_AcknowledgeConfig(I2C2, ENABLE); + +#ifdef FORCE_CRITICAL_SEC + __enable_irq(); +#endif + +} + + +/** + * @brief Writes a block of data to the device by DMA. + * @brief I2C2: I2C peripherial to use. + * @param cAddr : slave address. + * @param pcBuffer : pointer to the buffer containing the data to be written. + * @param cWriteAddr : register internal address to write to. + * @param nNumByteToWrite : number of bytes to write. + * @retval None + */ +void iNemoI2CBufferWriteDma(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cWriteAddr, uint8_t cNumByteToWrite) +{ + + __IO uint32_t temp = 0; + __IO uint32_t Timeout = 0; + + static uint8_t pcDmaBuffer[DMA_BUFFER_SIZE+1]; + + /* Set to 1 the MSb of the register address in case of multiple byte writing */ + if(cNumByteToWrite>1) + cWriteAddr |= 0x80; + + pcDmaBuffer[0]=cWriteAddr; + memcpy(&pcDmaBuffer[1],pcBuffer,cNumByteToWrite); + + /* Enable Error IT */ + I2C2->CR2 |= I2C_IT_ERR; + + Timeout = 0xFFFF; + /* Configure the DMA channel for I2C2 transmission */ + iNemoI2CDMAConfig(I2C2, pcDmaBuffer, cNumByteToWrite+1, I2C_DIRECTION_TX); + + /* Enable DMA for I2C */ + I2C_DMACmd(I2C2, ENABLE); + + /* Send START condition */ + I2C_GenerateSTART(I2C2, ENABLE); + + + /* Wait until SB flag is set: EV5 */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)) + { + if (Timeout-- == 0) + return; + } + + Timeout = 0xFFFF; + + /* Send LSM303DLH address for write */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Transmitter); + + /* Wait until ADDR is set: EV6 */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + { + if (Timeout-- == 0) + return; + } + + /* Clear ADDR flag by reading SR2 register */ + temp = I2C2->SR2; + + + /* Disable the DMA1 channel */ + if(I2C2 == I2C2) + { + /* Wait until DMA end of transfer */ + while (!DMA_GetFlagStatus(DMA1_FLAG_TC4)); + /* Disable DMA Channel */ + DMA_Cmd(I2C2_DMA_CHANNEL_TX, DISABLE); + + /* Clear the DMA Transfer complete flag */ + DMA_ClearFlag(DMA1_FLAG_TC4); + } + else + { + /* Wait until DMA end of transfer */ + while (!DMA_GetFlagStatus(DMA1_FLAG_TC6)); + /* Disable DMA Channel */ + DMA_Cmd(I2C1_DMA_CHANNEL_TX, DISABLE); + + /* Clear the DMA Transfer complete flag */ + DMA_ClearFlag(DMA1_FLAG_TC6); + } + + + /* EV8_2: Wait until BTF is set before programming the STOP */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); + + /* Send STOP Condition */ + I2C_GenerateSTOP(I2C2, ENABLE); + + /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ + while ((I2C2->CR1 & 0x0200) == 0x0200); + +} + + +/** + * @brief Writes a block of data to the device by polling. + * @brief I2C2: I2C peripherial to use. + * @param cAddr : slave address. + * @param pcBuffer : pointer to the buffer containing the data to be written. + * @param cWriteAddr : register internal address to write to. + * @param nNumByteToWrite : number of bytes to write. + * @retval None + */ +void iNemoI2CBufferWritePolling(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cWriteAddr, uint8_t cNumByteToWrite) +{ + /* Set to 1 the MSb of the register address in case of multiple byte writing */ + if(cNumByteToWrite>1) + cWriteAddr |= 0x80; + +#ifdef FORCE_CRITICAL_SEC + __disable_irq(); +#endif + + /* While the bus is busy */ + while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); + + /* Send START condition */ + I2C_GenerateSTART(I2C2, ENABLE); + + /* Test on EV5 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); + + /* Send LSM303DLH address for write */ + I2C_Send7bitAddress(I2C2, cAddr, I2C_Direction_Transmitter); + + /* Test on EV6 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); + + /* Send the LSM303DLHC_internal register address to write */ + I2C_SendData(I2C2, cWriteAddr); + + /* Test on EV8 and clear it */ + while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); + + for(uint8_t i=0 ; i +#include +#include +#include + +#include + +struct spiInitDef_t { + // sck / mosi / miso / cs + SPI_TypeDef * id; + GPIO_TypeDef * tdef[4]; + GPIO_InitTypeDef gpiodef[4]; + // spi / gpio + volatile uint32_t * bridge[2]; + uint32_t peripheral[2]; +}; + +static struct spiInitDef_t spiInitDefs[3] = { + { SPI1, { GPIOA, GPIOA, GPIOA, GPIOA}, { // SPI1 + { GPIO_Pin_5 , GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // SCK + { GPIO_Pin_7, GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // MOSI + { GPIO_Pin_6, GPIO_Speed_50MHz, GPIO_Mode_IN_FLOATING }, // MISO + { GPIO_Pin_4, GPIO_Speed_50MHz, GPIO_Mode_Out_PP }, // CS + }, {&RCC->APB2ENR, &RCC->APB2ENR}, {RCC_APB2Periph_SPI1, RCC_APB2Periph_GPIOA} }, + { SPI2, { GPIOB, GPIOB, GPIOB, GPIOB}, { // SPI2 + { GPIO_Pin_13 , GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // SCK + { GPIO_Pin_15, GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // MOSI + { GPIO_Pin_14, GPIO_Speed_50MHz, GPIO_Mode_IN_FLOATING }, // MISO + { GPIO_Pin_12, GPIO_Speed_50MHz, GPIO_Mode_Out_PP }, // CS + }, {&RCC->APB1ENR, &RCC->APB2ENR}, {RCC_APB1Periph_SPI2, RCC_APB2Periph_GPIOB} }, + { SPI3, { GPIOB, GPIOB, GPIOB, GPIOA}, { // SPI3 + { GPIO_Pin_3 , GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // SCK + { GPIO_Pin_5, GPIO_Speed_50MHz, GPIO_Mode_AF_PP }, // MOSI + { GPIO_Pin_4, GPIO_Speed_50MHz, GPIO_Mode_IN_FLOATING }, // MISO + { GPIO_Pin_15, GPIO_Speed_50MHz, GPIO_Mode_Out_PP }, // CS + }, {&RCC->APB1ENR, &RCC->APB2ENR}, {RCC_APB1Periph_SPI3, RCC_APB2Periph_GPIOC} }, +}; + +void spi_init(uint8_t id) +{ + if (!((id >= 1) && (id <= 3))) + return; + + struct spiInitDef_t * spiInitDef = spiInitDefs + id - 1; + + //clock AFIO + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + + int i; + for (i = 0; i < 2; i++) + *(spiInitDef->bridge[i]) |= spiInitDef->peripheral[i]; + + for (i = 0; i < 4; i++) + GPIO_Init(spiInitDef->tdef[i], &spiInitDef->gpiodef[i]); + + //GPIO_SetBits(spiInitDef->tdef[3], spiInitDef->gpiodef[3].GPIO_Pin); + spi_stop(id); + + //Init SPI + SPI_InitTypeDef spidef; + spidef.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + spidef.SPI_Mode = SPI_Mode_Master; + spidef.SPI_DataSize = SPI_DataSize_8b; + spidef.SPI_CPOL = SPI_CPOL_Low; + spidef.SPI_CPHA = SPI_CPHA_1Edge; + spidef.SPI_NSS = SPI_NSS_Soft; + spidef.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; + spidef.SPI_FirstBit = SPI_FirstBit_MSB; + spidef.SPI_CRCPolynomial = 7; + + SPI_Init(spiInitDef->id, &spidef); + SPI_Cmd(spiInitDef->id, ENABLE); +} + +void spi_start(uint8_t id) +{ + if (!((id >= 1) && (id <= 3))) + return; + + struct spiInitDef_t * spiInitDef = spiInitDefs + id - 1; + GPIO_ResetBits(spiInitDef->tdef[3], spiInitDef->gpiodef[3].GPIO_Pin); +} + +void spi_stop(uint8_t id) +{ + if (!((id >= 1) && (id <= 3))) + return; + + struct spiInitDef_t * spiInitDef = spiInitDefs + id - 1; + GPIO_SetBits(spiInitDef->tdef[3], spiInitDef->gpiodef[3].GPIO_Pin); +} + +void spi_read(uint8_t id, uint8_t *buffer, uint8_t nb) +{ + if (!((id >= 1) && (id <= 3))) + return; + + struct spiInitDef_t * spiInitDef = spiInitDefs + id - 1; + + while(nb >= 1) + { + taskENTER_CRITICAL(); + + //send garbage to work the clock + while (SPI_I2S_GetFlagStatus(spiInitDef->id, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(spiInitDef->id, 0xFF); + + //read data + while (SPI_I2S_GetFlagStatus(spiInitDef->id, SPI_I2S_FLAG_RXNE) == RESET); + *buffer = (uint8_t) SPI_I2S_ReceiveData(spiInitDef->id); + //printf("%02x", *buffer); + + taskEXIT_CRITICAL(); + + nb--; + buffer++; + } +} + +void spi_write(uint8_t id, uint8_t *buffer, uint8_t nb) +{ + if (!((id >= 1) && (id <= 3))) + return; + + struct spiInitDef_t * spiInitDef = spiInitDefs + id - 1; + + while(nb >= 1) + { + taskENTER_CRITICAL(); + + //send data + while (SPI_I2S_GetFlagStatus(spiInitDef->id, SPI_I2S_FLAG_TXE) == RESET); + SPI_I2S_SendData(spiInitDef->id, *buffer); + + //read, because that's the rule + while (SPI_I2S_GetFlagStatus(spiInitDef->id, SPI_I2S_FLAG_RXNE) == RESET); + SPI_I2S_ReceiveData(spiInitDef->id); + + taskEXIT_CRITICAL(); + + nb--; + buffer++; + } +} diff --git a/lib/spi.dep b/lib/spi.dep new file mode 100644 index 0000000..5cca9a0 --- /dev/null +++ b/lib/spi.dep @@ -0,0 +1,35 @@ +spi.o: spi.c spi.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/FreeRTOS.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stddef.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/projdefs.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/config/arm/stm32f10/FreeRTOSConfig.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Core/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/src/CM3/CoreSupport/core_cm3.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdint.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdint-gcc.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Core/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/config/arm/stm32f10/stm32f10x_conf.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/portable.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/mpu_wrappers.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/task.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/FreeRTOS/Source/include/list.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Drivers/include/stm32f10x_gpio.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Drivers/include/stm32f10x_rcc.h \ + /Users/tom/Documents/src/multitouchglove/uC-sdk/arch/arm/stm32f10x/Drivers/include/stm32f10x_spi.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/stdio.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/_ansi.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/newlib.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/config.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/machine/ieeefp.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/features.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/include/stdarg.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/reent.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/_ansi.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/_types.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/machine/_types.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/machine/_default_types.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/lock.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/types.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/machine/types.h \ + /usr/local/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/sys/stdio.h diff --git a/lib/spi.h b/lib/spi.h new file mode 100644 index 0000000..7ca8806 --- /dev/null +++ b/lib/spi.h @@ -0,0 +1,15 @@ +#include "FreeRTOS.h" + +//setup spi +void spi_init(uint8_t id); + +//call before initiating a communication +void spi_start(uint8_t id); +//call after communication ended +void spi_stop(uint8_t id); + +//read data from SPI +void spi_read(uint8_t id, uint8_t *buffer, uint8_t nb); +//write data to SPI +void spi_write(uint8_t id, uint8_t *address, uint8_t nb); +