--- /dev/null
+#include "HAL_L3Gx.h"
+
+#include "stm32f10x.h"
+#include <stdio.h>
+
+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);
+}
+
--- /dev/null
+#ifndef __HAL_L3GX__\r
+#define __HAL_L3GX__\r
+\r
+#include "spi.h"\r
+\r
+#define L3gxCommInit() spi_init(2)\r
+#define L3gxBufferRead(pVal,cAddress,nBytes) spi_get(pVal,cAddress,nBytes)\r
+#define L3gxBufferWrite(pVal,cAddress,nBytes) spi_set(pVal,cAddress,nBytes)\r
+\r
+void spi_get(uint8_t *buffer, uint8_t address, uint8_t nb);\r
+void spi_set(uint8_t *pcBuffer, uint8_t address, uint8_t nb);\r
+\r
+#endif\r
--- /dev/null
+/**\r
+ * @file HAL_LPS331AP.h\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief Hardware Abstraction Layer for LPS331AP.\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+/* Define to prevent recursive inclusion*/\r
+#ifndef __HAL_LPS331AP_H\r
+#define __HAL_LPS331AP_H\r
+\r
+/* Includes */\r
+#include "stm32f10x.h"\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @addtogroup iNemo_Sensor_Drivers iNemo Sensor Drivers\r
+ * @{\r
+ */\r
+ \r
+/**\r
+ * @addtogroup HAL_LPS331AP HAL LPS331AP\r
+ * @brief This is an adapter header to join the platform indipendent @ref Sensor_Libraries for the LPS331AP pressure sensor\r
+ * to the low level driver on the microcontroller side.\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @addtogroup HAL_LPS331AP_Exported_Constants HAL LPS331AP Exported Constants\r
+ * @{\r
+ */\r
+\r
+#define USE_I2C \r
+ \r
+\r
+#define LPS_I2C_Speed 400000\r
+#define LPS_I2C_ADDR0 0xBB\r
+#define LPS_I2C_ADDR1 0xB8\r
+ \r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @addtogroup HAL_LPS331AP_Exported_Macros HAL LPS331AP Exported Macros\r
+ * @{\r
+ */\r
+ \r
+#ifdef USE_I2C\r
+#include "i2c.h"\r
+ \r
+#define Lps331apCommInit() //iNemoI2C1Init(LPS_I2C_Speed)\r
+ \r
+#define Lps331apBufferRead(pVal,cAddress,nBytes) iNemoI2C1BufferRead(pVal,cAddress,nBytes)\r
+#define Lps331apBufferWrite(pVal,cAddress,nBytes) iNemoI2C1BufferWrite(pVal,cAddress,nBytes)\r
+\r
+#else\r
+#include "spi.h"\r
+ \r
+ // put here the macro definition for spi drivers\r
+ \r
+#endif\r
+ \r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+/**\r
+ * @file HAL_LSM303DLHC.h\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief Hardware Abstraction Layer for LSM303DLHC.\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+/* Define to prevent recursive inclusion*/\r
+#ifndef __HAL_LSM303DLHC_H\r
+#define __HAL_LSM303DLHC_H\r
+\r
+/* Includes */\r
+#include "stm32f10x.h"\r
+#include "i2c.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+/**\r
+* @addtogroup iNemo_Sensor_Drivers iNemo Sensor Drivers\r
+* @{\r
+*/ \r
+ \r
+/**\r
+ * @addtogroup HAL_LSM303DLHC HAL LSM303DLHC\r
+ * @brief This is an adapter header to join the platform indipendent @ref Sensor_Libraries for the LSM303DLHC 6 axis sensor\r
+ * to the low level driver on the microcontroller side.\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @addtogroup HAL_LSM303DLHC_Exported_Constants HAL LSM303DLHC Exported Constants\r
+ * @{\r
+ */\r
+\r
+ \r
+#define LSM_I2C I2C2\r
+ \r
+#define LSM_I2C_Speed 400000\r
+\r
+\r
+\r
+/**\r
+ * @addtogroup HAL_LSM303DLHC_Interrupt_Pin_Define HAL LSM303DLHC Interrupt Pin Define\r
+ * @{\r
+ */\r
+\r
+#define LSM_A_INT1_Pin GPIO_Pin_2\r
+#define LSM_A_INT1_Port GPIOD\r
+#define LSM_A_INT1_RCC_Port RCC_APB2Periph_GPIOD\r
+\r
+#define LSM_A_INT2_Pin GPIO_Pin_5\r
+#define LSM_A_INT2_Port GPIOB\r
+#define LSM_A_INT2_RCC_Port RCC_APB2Periph_GPIOB\r
+\r
+\r
+/** \r
+ *@}\r
+ */\r
+ \r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ * @addtogroup HAL_LSM303DLHC_Exported_Macros HAL LSM303DLHC Exported Macros\r
+ * @{\r
+ */\r
+ \r
+#define Lsm303dlhcI2CInit() iNemoI2C2Init(LSM_I2C_Speed)\r
+#define Lsm303dlhcI2CBufferRead(cDevAddress,pVal,cAddress,nBytes) iNemoI2C2BufferRead(cDevAddress,pVal,cAddress,nBytes)\r
+#define Lsm303dlhcI2CBufferWrite(cDevAddress,pVal,cAddress,nBytes) iNemoI2C2BufferWrite(cDevAddress,pVal,cAddress,nBytes)\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+ \r
+/**\r
+ *@}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+/********************************************************************************\r
+ * @file L3GX.h\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief Header for L3Gx.c file\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+/* Define to prevent recursive inclusion -------------------------------------*/\r
+#ifndef __L3GX_H\r
+#define __L3GX_H\r
+\r
+#include <stdint.h>\r
+#include "HAL_L3Gx.h"\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup L3Gx\r
+ * @brief This module contains all the functions to configure the L3Gx (L3G4200D or L3GD20)\r
+ * gyroscopic sensor.\r
+ * @details\r
+ * Since this code is platform independent an implementation of the SPI or I2C driver must\r
+ * be provided by the user according to the used platform.\r
+ * Every function makes use of the <i>L3gxBufferRead</i> and/or <i>L3gxBufferWrite</i>\r
+ * as low level functions to write bytes through the used digital interface.\r
+ * In order to link and use this code the user should define and export these functions in a header\r
+ * file called "HAL_L3Gx.h" (included by this module).\r
+ * @{\r
+ */\r
+\r
+\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Exported_Types L3Gx Exported Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Gyroscope Functional state. Used to enable or disable a specific option.\r
+ */\r
+typedef enum\r
+{\r
+ L3G_DISABLE = 0,\r
+ L3G_ENABLE = !L3G_DISABLE\r
+}L3GFunctionalState;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Flag status. Used to set/reset the sensor flags.\r
+ */\r
+typedef enum\r
+{\r
+ L3G_RESET = 0,\r
+ L3G_SET = !L3G_RESET\r
+}L3GFlagStatus;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Output Data Rate and LPF bandwidth\r
+ */\r
+typedef enum\r
+{\r
+\r
+ L3G_ODR_100_HZ_CUTOFF_12_5 = 0x00, /*!< Output Data Rate = 100 Hz - LPF Cut-Off = 12.5 Hz */\r
+ L3G_ODR_100_HZ_CUTOFF_25 = 0x10, /*!< Output Data Rate = 100 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_200_HZ_CUTOFF_12_5 = 0x40, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 12.5 Hz */\r
+ L3G_ODR_200_HZ_CUTOFF_25 = 0x50, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_200_HZ_CUTOFF_50 = 0x60, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_200_HZ_CUTOFF_70 = 0x70, /*!< Output Data Rate = 200 Hz - LPF Cut-Off = 70 Hz */\r
+ L3G_ODR_400_HZ_CUTOFF_20 = 0x80, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 20 Hz */\r
+ L3G_ODR_400_HZ_CUTOFF_25 = 0x90, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_400_HZ_CUTOFF_50 = 0xA0, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_400_HZ_CUTOFF_110 = 0xB0, /*!< Output Data Rate = 400 Hz - LPF Cut-Off = 110 Hz */\r
+ L3G_ODR_800_HZ_CUTOFF_30 = 0xC0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 30 Hz */\r
+ L3G_ODR_800_HZ_CUTOFF_35 = 0xD0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 35 Hz */\r
+ L3G_ODR_800_HZ_CUTOFF_50 = 0xE0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_800_HZ_CUTOFF_110 = 0xF0, /*!< Output Data Rate = 800 Hz - LPF Cut-Off = 110 Hz */\r
+\r
+ L3G_ODR_95_HZ_CUTOFF_12_5 = 0x00, /*!< Output Data Rate = 95 Hz - LPF Cut-Off = 12.5 Hz */\r
+ L3G_ODR_95_HZ_CUTOFF_25 = 0x10, /*!< Output Data Rate = 95 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_190_HZ_CUTOFF_12_5 = 0x40, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 12.5 Hz */\r
+ L3G_ODR_190_HZ_CUTOFF_25 = 0x50, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_190_HZ_CUTOFF_50 = 0x60, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_190_HZ_CUTOFF_70 = 0x70, /*!< Output Data Rate = 190 Hz - LPF Cut-Off = 70 Hz */\r
+ L3G_ODR_380_HZ_CUTOFF_20 = 0x80, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 20 Hz */\r
+ L3G_ODR_380_HZ_CUTOFF_25 = 0x90, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 25 Hz */\r
+ L3G_ODR_380_HZ_CUTOFF_50 = 0xA0, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_380_HZ_CUTOFF_100 = 0xB0, /*!< Output Data Rate = 380 Hz - LPF Cut-Off = 100 Hz */\r
+ L3G_ODR_760_HZ_CUTOFF_30 = 0xC0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 30 Hz */\r
+ L3G_ODR_760_HZ_CUTOFF_35 = 0xD0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 35 Hz */\r
+ L3G_ODR_760_HZ_CUTOFF_50 = 0xE0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 50 Hz */\r
+ L3G_ODR_760_HZ_CUTOFF_100 = 0xF0, /*!< Output Data Rate = 760 Hz - LPF Cut-Off = 100 Hz */\r
+\r
+\r
+}GyroOutputDataRate;\r
+\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Power Mode\r
+ */\r
+typedef enum\r
+{\r
+ L3G_NORMAL_SLEEP_MODE = 0x08, /*!< Normal mode or Sleep mode enabled. To go in sleep mode all axes shall be disabled. */\r
+ L3G_POWER_DOWN_MODE = 0x00 /*!< Power Down mode enabled */\r
+}GyroPowerMode;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Axes\r
+ */\r
+typedef enum\r
+{\r
+ L3G_X_AXIS_DIS = 0x00, /*!< X Axis disabled */\r
+ L3G_X_AXIS_EN = 0x01, /*!< X Axis enabled */\r
+ L3G_Y_AXIS_DIS = 0x00, /*!< Y Axis disabled */\r
+ L3G_Y_AXIS_EN = 0x02, /*!< Y Axis enabled */\r
+ L3G_Z_AXIS_DIS = 0x00, /*!< Z Axis disabled */\r
+ L3G_Z_AXIS_EN = 0x04, /*!< Z Axis enabled */\r
+ L3G_ALL_AXES_DIS = 0x00, /*!< All axes disabled */\r
+ L3G_ALL_AXES_EN = 0x07 /*!< All axes enabled */\r
+}GyroAxesEnabling;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Full scale selection\r
+ */\r
+typedef enum\r
+{\r
+ L3G_FS_250_DPS = 0x00, /*!< ±250 dps */\r
+ L3G_FS_500_DPS = 0x10, /*!< ±500 dps */\r
+ L3G_FS_2000_DPS = 0x20 /*!< ±2000 dps */\r
+}GyroFullScale;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Block Data Update selection\r
+ */\r
+typedef enum\r
+{\r
+ L3G_CONTINUOS_UPDATE = 0x00, /*!< Continuos Update */\r
+ L3G_BLOCK_UPDATE = 0x80 /*!< Single Update: output registers not updated until MSB and LSB reading */\r
+}GyroBlockDataUpdate;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Endianness selection\r
+ */\r
+typedef enum\r
+{\r
+ L3G_LITTLE_ENDIAN = 0x00, /*!< Little Endian: data LSB @ lower address */\r
+ L3G_BIG_ENDIAN = 0x40 /*!< Big Endian: data MSB @ lower address */\r
+}GyroEndianness;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope High Pass Mode Filter Selection\r
+ */\r
+typedef enum\r
+{\r
+ L3G_HPFM_NORMAL = 0x00, /*!< Normal Mode */\r
+ L3G_HPFM_REFERENCE = 0x10, /*!< Reference Signal for filtering */\r
+ L3G_HPFM_AOI = 0x30 /*!< Autoreset On Interrupt event */\r
+}GyroHPFMode;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Irq on line 2 list\r
+ */\r
+typedef enum\r
+{\r
+ L3G_I2_EMPTY = 0x01, /*!< FIFO empty flag */\r
+ L3G_I2_OVERRUN = 0x02, /*!< Data over-run flag */\r
+ L3G_I2_WTM = 0x04, /*!< Watermark flag */\r
+ L3G_I2_DRDY = 0x08 /*!< Data ready flag */\r
+}L3GIrq2List;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ GyroPowerMode xPowerMode; /*!< Low power mode selection (see table 19 datasheet) */\r
+ GyroOutputDataRate xOutputDataRate; /*!< Output Data Rate */\r
+ GyroAxesEnabling xEnabledAxes; /*!< Axes Enable */\r
+ GyroFullScale xFullScale; /*!< Full Scale */\r
+ GyroBlockDataUpdate xDataUpdate; /*!< Data Update mode : Continuos update or data don`t change until MSB and LSB nex reading */\r
+ GyroEndianness xEndianness; /*!< Endianess */\r
+}L3GInit;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Filter Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ L3GFunctionalState xHPF; /*!< HPF enabling/disabling */\r
+ uint8_t cHPFCutOff; /*!< This value shall be between 0 and 10. The HPF cut-off frequency will be ODR[Hz]/(12.5(1+cHPFCutOff))*/\r
+ GyroHPFMode xHPF_Mode; /*!< HPF MODE: Normal mode or Reference signal for filtering*/\r
+ uint8_t cHPFReference; /*!< Reference value for filtering*/\r
+}L3GFilterInit;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Data status. It notifies if data on axis are available or overrided.\r
+ */\r
+typedef struct\r
+{\r
+ L3GFlagStatus X_Da:1;\r
+ L3GFlagStatus Y_Da:1;\r
+ L3GFlagStatus Z_Da:1;\r
+ L3GFlagStatus ZYX_Da:1;\r
+ L3GFlagStatus X_Or:1;\r
+ L3GFlagStatus Y_Or:1;\r
+ L3GFlagStatus Z_Or:1;\r
+ L3GFlagStatus ZYX_Or:1;\r
+}L3GDataStatus;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope Events on axis bitfield structure\r
+ * @note Workaround for X-Y axis inverded.\r
+ */\r
+typedef struct\r
+{\r
+ L3GFlagStatus Y_LOW:1; /*!< X axis low event */\r
+ L3GFlagStatus Y_HIGH:1; /*!< X axis high event */\r
+ L3GFlagStatus X_LOW:1; /*!< Y axis low event */\r
+ L3GFlagStatus X_HIGH:1; /*!< Y axis high event */\r
+ L3GFlagStatus Z_LOW:1; /*!< Z axis low event */\r
+ L3GFlagStatus Z_HIGH:1; /*!< Z axis high event */\r
+ uint8_t :2; /*!< 2 bits padding */\r
+}L3GAxisEvents;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope FIFO Working Mode\r
+ */\r
+typedef enum\r
+{\r
+ L3G_BYPASS_MODE = 0x00, /*!< Bypass mode: don't use the FIFO */\r
+ L3G_FIFO_MODE = 0x20, /*!< FIFO mode */\r
+ L3G_STREAM_MODE = 0x40, /*!< Stream mode */\r
+ L3G_STREAM_TO_FIFO = 0x60, /*!< Stream to FIFO mode */\r
+ L3G_BYPASS_TO_STREAM= 0x80 /*!< Bypass to Stream mode */\r
+}L3GFifoMode;\r
+\r
+\r
+\r
+/**\r
+ * @brief Gyroscope FIFO Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ L3GFifoMode xFifoMode; /*!< FIFO operating mode */\r
+ uint8_t cWtm; /*!< WaterMark level for FIFO in range [0, 31] */\r
+}L3GFifoInit;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope FIFO Status bitfield structure\r
+ */\r
+typedef struct\r
+{\r
+ uint8_t FIFO_FSS:5; /*!< FIFO unread samples */\r
+ L3GFlagStatus FIFO_EMPTY_FLAG:1; /*!< FIFO Empty flag */\r
+ L3GFlagStatus FIFO_OVRN_FLAG:1; /*!< FIFO Overrun flag */\r
+ L3GFlagStatus FIFO_WTM_FLAG:1; /*!< FIFO Watermark flag */\r
+\r
+}L3GFifoStatus;\r
+\r
+\r
+/**\r
+ * @brief Gyroscope External events on axis combination\r
+ */\r
+typedef enum\r
+{\r
+ L3G_OR_COMBINATION = 0x00, /*!< OR combination of enabled IRQs */\r
+ L3G_AND_COMBINATION = 0x80, /*!< AND combination of enabled IRQs */\r
+\r
+}L3GIrqOnaxisCombination;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Exported_Constants L3Gx Exported Constants\r
+ *@{\r
+ */\r
+\r
+/**\r
+ * @defgroup L3GX_Sensitivity_Defines L3Gx Sensitivity Defines\r
+ * @{\r
+ */\r
+\r
+#define L3G_Sensitivity_250dps (float) 114.285f /*!< gyroscope sensitivity with 250 dps full scale [LSB/dps] */\r
+#define L3G_Sensitivity_500dps (float) 57.1429f /*!< gyroscope sensitivity with 500 dps full scale [LSB/dps] */\r
+#define L3G_Sensitivity_2000dps (float) 14.285f /*!< gyroscope sensitivity with 2000 dps full scale [LSB/dps] */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/** @defgroup L3GX_Register_Mapping L3Gx Register Mapping\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * \brief Gyroscope WHO_AM_I Register: Device identification register.\r
+ * \code\r
+ * Read\r
+ * Default value: 0xD3\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_WHO_AM_I 0x0F\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Control Register 1\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x07\r
+ *\r
+ * 7:6 DR1-DR0: Output Data Rate selection\r
+ * 5:4 BW1-BW0: Bandwidth selection\r
+ *\r
+ * DR1-DR0 | BW1-BW0 | Gyro ODR [Hz] | LPF cut-off freq[Hz]\r
+ * ---------------------------------------------------------------\r
+ * 00 | 00 | 100 | 12.5\r
+ * 00 | 01 | 100 | 25\r
+ * 00 | 10 | 100 | 25\r
+ * 00 | 11 | 100 | 25\r
+ * ---------------------------------------------------------------\r
+ * 01 | 00 | 200 | 12.5\r
+ * 01 | 01 | 200 | 25\r
+ * 01 | 10 | 200 | 50\r
+ * 01 | 11 | 200 | 70\r
+ * ---------------------------------------------------------------\r
+ * 10 | 00 | 400 | 20\r
+ * 10 | 01 | 400 | 25\r
+ * 10 | 10 | 400 | 50\r
+ * 10 | 11 | 400 | 110\r
+ * ---------------------------------------------------------------\r
+ * 11 | 00 | 800 | 30\r
+ * 11 | 01 | 800 | 35\r
+ * 11 | 10 | 800 | 50\r
+ * 11 | 11 | 800 | 110\r
+ * ---------------------------------------------------------------\r
+ *\r
+ * 3 PD: Power down mode enable. Default value: 0 (0: power down mode, sleep, 1: normal mode or sleep mode)\r
+ * 2 Zen: Z axis enable. (0 - Z axis disabled; 1- Z axis enabled)\r
+ * 1 Yen: Y axis enable. (0 - Y axis disabled; 1- Y axis enabled)\r
+ * 0 Xen: X axis enable. (0 - X axis disabled; 1- X axis enabled)\r
+ * \endcode\r
+ */\r
+#define L3G_CTRL_REG1 0x20\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Control Register 2\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ *\r
+ * 7:6 0-0: Value loaded at boot. This value must not be changed\r
+ * 5:4 HPM1-HPM0: High Pass filter Mode Selection\r
+ *\r
+ * HPM1 | HPM0 | High Pass filter Mode\r
+ * -------------------------------------------------------------------\r
+ * 0 | 0 | Normal mode (reset reading HP_RESET_FILTER)\r
+ * 0 | 1 | Reference signal for filtering\r
+ * 1 | 0 | Normal mode\r
+ * 1 | 1 | Autoreset on interrupt event\r
+ * -------------------------------------------------------------------\r
+ *\r
+ *\r
+ *\r
+ * 3-0 HPCF3-HPCF0: High Pass filter Cut Off frequency selection\r
+ *\r
+ * HPCF3-HPCF0 | ODR= 100Hz | ODR= 200Hz | ODR= 400Hz | ODR= 800Hz\r
+ * -----------------------------------------------------------------------\r
+ * 0000 | 8 | 15 | 30 | 56\r
+ * 0001 | 4 | 8 | 15 | 30\r
+ * 0010 | 2 | 4 | 8 | 15\r
+ * 0011 | 1 | 2 | 4 | 8\r
+ * 0100 | 0.5 | 1 | 2 | 4\r
+ * 0101 | 0.2 | 0.5 | 1 | 2\r
+ * 0110 | 0.1 | 0.2 | 0.5 | 1\r
+ * 0111 | 0.05 | 0.1 | 0.2 | 0.5\r
+ * 1000 | 0.02 | 0.05 | 0.1 | 0.2\r
+ * 1001 | 0.01 | 0.02 | 0.05 | 0.1\r
+ * -----------------------------------------------------------------------\r
+ * \endcode\r
+ */\r
+#define L3G_CTRL_REG2 0x21\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Control Register 3\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ *\r
+ * 7 I1_Int1: Interrupt enable on INT1 pin. Default value 0. (0: Disable; 1: Enable)\r
+ * 6 I1_Boot: Boot status available on INT1. Default value 0. (0: Disable; 1: Enable)\r
+ * 5 H_Lactive: Interrupt active configuration on INT1. Default value 0. (0: High; 1:Low)\r
+ * 4 PP_OD: Push- Pull / Open drain. Default value: 0. (0: Push- Pull; 1: Open drain)\r
+ * 3 I2_DRDY: Date Ready on DRDY/INT2. Default value 0. (0: Disable; 1: Enable)\r
+ * 2 I2_WTM: FIFO Watermark interrupt on DRDY/INT2. Default value: 0. (0: Disable; 1: Enable)\r
+ * 1 I2_ORun: FIFO Overrun interrupt on DRDY/INT2 Default value: 0. (0: Disable; 1: Enable)\r
+ * 0 I2_Empty: FIFO Empty interrupt on DRDY/INT2. Default value: 0. (0: Disable; 1: Enable)\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_CTRL_REG3 0x22\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Control Register 4\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ *\r
+ * 7 BDU: Block Data Update. Default value: 0 (0: continous update; 1: output registers not updated until MSB and LSB reading)\r
+ * 6 BLE: Big/Little Endian Data Selection. Default value 0. (0: Data LSB @ lower address; 1: Data MSB @ lower address)\r
+ * 5-4 FS1-FS0: Full Scale selection. Default value: 00 (00: 250 dps; 01: 500 dps; 10: 2000 dps; 11: 2000 dps)\r
+ * 3 -\r
+ * 2-1 ST1-ST0: Self Test Enable. Default value: 00 (00: Self Test Disabled)\r
+ *\r
+ * ST1 | ST0 | Self test mode\r
+ * ------------------------------------\r
+ * 0 | 0 | Normal mode\r
+ * 0 | 1 | Self test 0\r
+ * 1 | 0 | --\r
+ * 1 | 1 | Self test 1\r
+ * ------------------------------------\r
+ *\r
+ * 0 SIM: SPI Serial Interface Mode selection. Default value: 0 (0: 4-wire interface; 1: 3-wire interface).\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_CTRL_REG4 0x23\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Control Register 5\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ *\r
+ * 7 BOOT: Reboot memory content. Default value: 0 (0: normal mode; 1: reboot memory content)\r
+ * 6 FIFO_EN: FIFO enable. Default value: 0 (0: FIFO disable; 1: FIFO Enable)\r
+ * 5 -\r
+ * 4 HPen: High Pass filter Enable. Default value: 0 (0: HPF disabled; 1: HPF enabled. See Figure 20)\r
+ * 3-2 INT1_Sel1-INT1_Sel0: INT1 selection configuration. Default value: 0 (See Figure 20)\r
+ *\r
+ * Hpen | INT_SEL1 | INT_SEL2 | Description\r
+ * ----------------------------------------------------------------------------------------------------------------\r
+ * x | 0 | 0 | Non-high-pass-filtered data are used for interrupt generation\r
+ * x | 0 | 1 | High-pass-filtered data are used for interrupt generation\r
+ * 0 | 1 | x | Low-pass-filtered data are used for interrupt generation\r
+ * 1 | 1 | x | High-pass and low-pass-filtered data are used for interrupt generation\r
+ * ----------------------------------------------------------------------------------------------------------------\r
+ *\r
+ * 1-0 Out_Sel1-Out_Sel0: Out selection configuration. Default value: 0\r
+ *\r
+ * Hpen | OUT_SEL1 | OUT_SEL0 | Description\r
+ * -------------------------------------------------------------------------------------------------------------\r
+ * x | 0 | 0 | Data in DataReg and FIFO are non-highpass-filtered\r
+ * x | 0 | 1 | Data in DataReg and FIFO are high-passfiltered\r
+ * 0 | 1 | x | Data in DataReg and FIFO are low-passfiltered by LPF2\r
+ * 1 | 1 | x | Data in DataReg and FIFO are high-pass and low-pass-filtered by LPF2\r
+ * -------------------------------------------------------------------------------------------------------------\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_CTRL_REG5 0x24\r
+\r
+\r
+/**\r
+ * \brief Gyroscope REFERENCE/DATACAPTURE Register\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ *\r
+ * 7-0 Ref7-Ref0: Reference value for Interrupt generation. Default value: 0\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_REFERENCE 0x25\r
+\r
+\r
+/**\r
+ * \brief Gyroscope OUT_TEMP Register\r
+ * \code\r
+ * Read\r
+ * Default value: (The value is expressed as 16bit two\92s complement)\r
+ *\r
+ * 7-0 Temp7-Temp0: Temperature data.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_TEMP 0x26\r
+\r
+\r
+/**\r
+ * \brief Gyroscope STATUS Register\r
+ * \code\r
+ * Read\r
+ * Default value: (The value is expressed as 16bit two\92s complement)\r
+ *\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ *\r
+ * \endcode\r
+*/\r
+#define L3G_STATUS_REG 0x27\r
+\r
+\r
+/**\r
+ * \brief Gyroscope X-axis angular rate data. LSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 XOUT7-XOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_X_L 0x28\r
+\r
+\r
+/**\r
+ * \brief Gyroscope X-axis angular rate data. MSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 XOUT15-XOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_X_H 0x29\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Y-axis angular rate data. LSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 YOUT7-YOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_Y_L 0x2A\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Y-axis angular rate data. MSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 YOUT15-YOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_Y_H 0x2B\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Z-axis angular rate data. LSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 ZOUT7-ZOUT0: angular rate Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * angular rate Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_Z_L 0x2C\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Z-axis angular rate data. MSB Register.\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:0 ZOUT15-ZOUT8: angular rate Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * angular rate Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define L3G_OUT_Z_H 0x2D\r
+\r
+\r
+/**\r
+ * \brief Gyroscope FIFO Control Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: ( The value is expressed as 16bit two\92s complement)\r
+ * 7:5 FM2-FM0: FIFO mode selection. Default value: 00\r
+ *\r
+ * FM2 | FM1 | FM0 | FIFO mode\r
+ * ----------------------------------------------------\r
+ * 0 | 0 | 0 | Bypass mode\r
+ * 0 | 0 | 1 | FIFO mode\r
+ * 0 | 1 | 0 | Stream mode\r
+ * 0 | 1 | 1 | Stream-to-FIFO mode\r
+ * 1 | 0 | 0 | Bypass-to-Stream mode\r
+ * ----------------------------------------------------\r
+ *\r
+ * 4-0 WTM4-WTM0: FIFO threshold. Watermark level setting\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_FIFO_CTRL_REG 0x2E\r
+\r
+\r
+/**\r
+ * \brief Gyroscope FIFO Source Register.\r
+ * \code\r
+ * Read\r
+ * Default value: output\r
+ * 7 WTM: Watermark status. (0: FIFO filling is lower than WTM level; 1: FIFO filling is equal or higher than WTM level)\r
+ * 6 OVRN: Overrun bit status. (0: FIFO is not completely filled; 1:FIFO is completely filled)\r
+ * 5 EMPTY: FIFO empty bit. (0: FIFO not empty; 1: FIFO empty)\r
+ * 4-1 FSS4-FSS1: FIFO stored data level\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_FIFO_SRC_REG 0x2F\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Configuration Register for Interrupt 1 source.\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7 AND/OR: AND/OR combination of Interrupt events.Default value: 0 (0: OR combination of interrupt events 1: AND combination of interrupt events\r
+ * 6 LIR: Latch Interrupt Request. Default value: 0 (0: interrupt request not latched; 1: interrupt request latched) Cleared by reading INT1_SRC reg.\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ * 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)\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_CFG_REG 0x30\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 source register.\r
+ * \code\r
+ * Read\r
+ * Default value: output\r
+ * 7 0\r
+ * 6 IA : Interrupt active. Default value: 0 (0: no interrupt has been generated; 1: one or more interrupts have been generated)\r
+ * 5 ZH: Z high. Default value: 0 (0: no interrupt, 1: Z High event has occurred)\r
+ * 4 ZL: Z low. Default value: 0 (0: no interrupt; 1: Z Low event has occurred)\r
+ * 3 YH: Y high. Default value: 0 (0: no interrupt, 1: Y High event has occurred)\r
+ * 2 YL: Y low. Default value: 0 (0: no interrupt; 1: Y Low event has occurred)\r
+ * 1 XH: X high. Default value: 0 (0: no interrupt, 1: X High event has occurred)\r
+ * 0 XL: X low. Default value: 0 (0: no interrupt; 1: X Low event has occurred)\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_SCR_REG 0x31\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on X-axis. MSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7 -\r
+ * 6 THSX14-THSX08: Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_THS_XH_REG 0x32\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on X-axis. LSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7-0 THSX7-THSX0 Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_TSH_XL_REG 0x33\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on Y-axis. MSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7 -\r
+ * 6 THSY14-THSY08: Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_TSH_YH_REG 0x34\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on Y-axis. LSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7-0 THSY7-THSY0 Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_TSH_YL_REG 0x35\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on Z-axis. MSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7 -\r
+ * 6 THSZ14-THSZ08: Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_TSH_ZH_REG 0x36\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Threshold on Z-axis. LSB Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7-0 THSZ7-THSZ0 Interrupt 1 threshold.\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_TSH_ZL_REG 0x37\r
+\r
+\r
+/**\r
+ * \brief Gyroscope Interrupt 1 Duration Register.\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x00\r
+ * 7 WAIT: WAIT enable. Default value: 0 (0: disable; 1: enable). Wait =\920\92: the interrupt falls immediately if signal crosses the selected threshold; Wait =\921\92: 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.\r
+ * 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).\r
+ *\r
+ * \endcode\r
+ */\r
+#define L3G_INT1_DURATION_REG 0x38\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/** @defgroup L3GX_Exported_Functions L3Gx Exported Functions\r
+ * @{\r
+ */\r
+\r
+void L3gxConfig(L3GInit *pxL3GInitStruct);\r
+void L3gxGetInfo(L3GInit *pxL3GInitStruct);\r
+void L3gxFilterConfig(L3GFilterInit *pxL3GFilterInitStruct);\r
+void L3gxFilterGetInfo(L3GFilterInit* pxL3GFilterInitStruct);\r
+void L3gxLowpower(GyroPowerMode xPowerMode);\r
+void L3gxSetDataRate(GyroOutputDataRate xDataRate);\r
+GyroOutputDataRate L3gxGetEnumDataRate(void);\r
+void L3gxSetFullScale(GyroFullScale xFullScale);\r
+GyroFullScale L3gxGetEnumFullScale(void);\r
+void L3gxGetSensitivity(float* pfSensitivityXYZ);\r
+void L3gxReboot(void);\r
+void L3gxReadRawData(int16_t* pnRawData);\r
+void L3gxReadAngRate(float* pfData);\r
+void L3gxReadFifo(float* pfData, uint8_t cDataToRead);\r
+L3GDataStatus L3gxGetDataStatus(void);\r
+void L3gxIrq1Config(L3GFunctionalState xNewState);\r
+void L3gxIrq2Config(L3GIrq2List xIrq2Config, L3GFunctionalState xNewState);\r
+void L3gxFifoInit(L3GFifoInit* pxFifoInit);\r
+L3GFifoStatus L3gxFifoGetStatus(void);\r
+void L3gxFifo(L3GFunctionalState xNewState);\r
+void L3gxSetAxisIrqs(L3GIrqOnaxisCombination xIrqCombinations, L3GAxisEvents* pxAxisEvents, L3GFunctionalState xLatched);\r
+L3GFunctionalState L3gxGetAxisIrqs(L3GAxisEvents* pxAxisEvents);\r
+void L3gxSetThreshold(float *pfData);\r
+float L3gxReadTemp(void);\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup L3GX_Exported_Macros L3Gx Exported Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup L3GX_I2C_Communication L3Gx I2C Communication\r
+ * @{\r
+ */\r
+\r
+#define L3gxByteRead(pVal,cAddress) L3gxBufferRead(pVal,cAddress,1)\r
+#define L3gxByteWrite(pVal,cAddress) L3gxBufferWrite(pVal,cAddress,1)\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/** @defgroup L3GX_L3G4200D L3Gx L3G4200D\r
+ * @{\r
+ */\r
+\r
+\r
+#define L3g4200dConfig L3gxConfig\r
+#define L3g4200dGetInfo L3gxGetInfo\r
+#define L3g4200dFilterConfig L3gxFilterConfig\r
+#define L3g4200dFilterGetInfo L3gxFilterGetInfo\r
+#define L3g4200dLowpower L3gxLowpower\r
+#define L3g4200dSetDataRate L3gxSetDataRate\r
+#define L3g4200dGetEnumDataRate L3gxGetEnumDataRate\r
+#define L3g4200dSetFullScale L3gxSetFullScale\r
+#define L3g4200dGetEnumFullScale L3gxGetEnumFullScale\r
+#define L3g4200dGetSensitivity L3gxGetSensitivity\r
+#define L3g4200dReboot L3gxReboot\r
+#define L3g4200dReadRawData L3gxReadRawData\r
+#define L3g4200dReadAngRate L3gxReadAngRate\r
+#define L3g4200dReadFifo L3gxReadFifo\r
+#define L3g4200dGetDataStatus L3gxGetDataStatus\r
+#define L3g4200dIrq1Config L3gxIrq1Config\r
+#define L3g4200dIrq2Config L3gxIrq2Config\r
+#define L3g4200dFifoInit L3gxFifoInit\r
+#define L3g4200dFifoGetStatus L3gxFifoGetStatus\r
+#define L3g4200dFifo L3gxFifo\r
+#define L3g4200dSetAxisIrqs L3gxSetAxisIrqs\r
+#define L3g4200dGetAxisIrqs L3gxGetAxisIrqs\r
+#define L3g4200dSetThreshold L3gxSetThreshold\r
+#define L3g4200dReadTemp L3gxReadTemp\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/** @defgroup L3GX_L3GD20 L3Gx L3GD20\r
+ * @{\r
+ */\r
+\r
+\r
+#define L3gd20Config L3gxConfig\r
+#define L3gd20GetInfo L3gxGetInfo\r
+#define L3gd20FilterConfig L3gxFilterConfig\r
+#define L3gd20FilterGetInfo L3gxFilterGetInfo\r
+#define L3gd20Lowpower L3gxLowpower\r
+#define L3gd20SetDataRate L3gxSetDataRate\r
+#define L3gd20GetEnumDataRate L3gxGetEnumDataRate\r
+#define L3gd20SetFullScale L3gxSetFullScale\r
+#define L3gd20GetEnumFullScale L3gxGetEnumFullScale\r
+#define L3gd20GetSensitivity L3gxGetSensitivity\r
+#define L3gd20Reboot L3gxReboot\r
+#define L3gd20ReadRawData L3gxReadRawData\r
+#define L3gd20ReadAngRate L3gxReadAngRate\r
+#define L3gd20ReadFifo L3gxReadFifo\r
+#define L3gd20GetDataStatus L3gxGetDataStatus\r
+#define L3gd20Irq1Config L3gxIrq1Config\r
+#define L3gd20Irq2Config L3gxIrq2Config\r
+#define L3gd20FifoInit L3gxFifoInit\r
+#define L3gd20FifoGetStatus L3gxFifoGetStatus\r
+#define L3gd20Fifo L3gxFifo\r
+#define L3gd20SetAxisIrqs L3gxSetAxisIrqs\r
+#define L3gd20GetAxisIrqs L3gxGetAxisIrqs\r
+#define L3gd20SetThreshold L3gxSetThreshold\r
+#define L3gd20ReadTemp L3gxReadTemp\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+/**\r
+ * @file L3GX.c\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief This file provides a set of functions needed to manage the L3Gx slave.\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+#include "L3Gx.h"\r
+\r
+#include <BoardConsole.h>\r
+\r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+* @defgroup L3Gx\r
+* @{\r
+*/\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Private_TypesDefinitions L3Gx Private TypesDefinitions\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Private_Defines L3Gx Private Defines\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Private_Macros L3Gx Private Macros\r
+ * @{\r
+ */\r
+\r
+#define L3G_ABS(a) (a>0?(a):-(a))\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup L3GX_Private_FunctionPrototypes L3Gx Private FunctionPrototypes\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+* @defgroup L3GX_Private_Functions L3Gx Private Functions\r
+* @{\r
+*/\r
+\r
+\r
+/**\r
+* @brief Set configuration of angular rate of L3GX pointer to a L3GInit structure that contains\r
+* the configuration setting for the L3GX.\r
+* @param pxL3GInitStruct : pointer to a L3GInit structure that contains the configuration setting.\r
+* This parameter is a pointer to @ref L3GInit .\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* L3GInit L3GInitStructure;\r
+*\r
+* L3GInitStructure.xPowerMode = L3G_NORMAL_SLEEP_MODE;\r
+* L3GInitStructure.xOutputDataRate = L3G_ODR_100_HZ_CUTOFF_12_5;\r
+* L3GInitStructure.xEnabledAxes = L3G_ALL_AXES_EN;\r
+* L3GInitStructure.xFullScale = L3G_FS_500_DPS;\r
+* L3GInitStructure.xDataUpdate = L3G_CONTINUOS_UPDATE;\r
+* L3GInitStructure.xEndianness = L3G_LITTLE_ENDIAN;\r
+*\r
+* L3gxConfig(&L3GInitStructure);\r
+* @endcode\r
+*/\r
+void L3gxConfig(L3GInit *pxL3GInitStruct)\r
+{\r
+ uint8_t CTRL1 = 0x00, CTRL4 = 0x00;\r
+\r
+ CTRL1 |= ((uint8_t)pxL3GInitStruct->xPowerMode | (uint8_t)pxL3GInitStruct->xOutputDataRate | (uint8_t)pxL3GInitStruct->xEnabledAxes);\r
+ CTRL4 |= ((uint8_t)pxL3GInitStruct->xFullScale | (uint8_t)pxL3GInitStruct->xDataUpdate | (uint8_t)pxL3GInitStruct->xEndianness);\r
+\r
+ L3gxByteWrite(&CTRL1,L3G_CTRL_REG1);\r
+ L3gxByteWrite(&CTRL4,L3G_CTRL_REG4);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the general configuration of L3GX for the magnetometer.\r
+* @param pxL3GInitStruct : pointer to a L3GInit structure that will\r
+* contain the configuration setting read from the L3GX registers.\r
+* @retval None\r
+*/\r
+void L3gxGetInfo(L3GInit *pxL3GInitStruct)\r
+{\r
+ uint8_t CTRL1, CTRL4;\r
+\r
+ /* Read the registers content */\r
+ L3gxByteRead(&CTRL4, L3G_CTRL_REG4);\r
+ L3gxByteRead(&CTRL1, L3G_CTRL_REG1);\r
+\r
+ /* Fill the structure fields from CTRL1 reg info */\r
+ pxL3GInitStruct->xPowerMode = (GyroPowerMode)(CTRL1 & 0x08);\r
+ pxL3GInitStruct->xOutputDataRate = (GyroOutputDataRate)(CTRL1 & 0xF0);\r
+ pxL3GInitStruct->xEnabledAxes = (GyroAxesEnabling)(CTRL1 & 0x07);\r
+\r
+ /* Fill the structure fields from CTRL4 reg info */\r
+ pxL3GInitStruct->xFullScale = (GyroFullScale)(CTRL4 & 0x30);\r
+ pxL3GInitStruct->xDataUpdate = (GyroBlockDataUpdate)(CTRL4 & 0x80);\r
+ pxL3GInitStruct->xEndianness = (GyroEndianness)(CTRL4 & 0x40);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Set configuration of angular rate of L3GX pointer to a L3GFilterInit structure\r
+* that contains the filter configuration setting for the L3GX.\r
+* @param pxL3GFilterInitStruct: pointer to a L3GInit structure that contains the filter configuration setting.\r
+* This parameter is a pointer to @ref L3GFilterInit .\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* L3GFilterInit FilterInitStr;\r
+*\r
+* FilterInitStr.xHPF = L3G_NORMAL_SLEEP_MODE;\r
+* FilterInitStr.cHPFCutOff = 5;\r
+* FilterInitStr.xHPF_Mode = L3G_HPFM_NORMAL;\r
+* FilterInitStr.cHPFReference = 0;\r
+*\r
+* L3gxFilterConfig(&FilterInitStr);\r
+* @endcode\r
+*/\r
+void L3gxFilterConfig(L3GFilterInit *pxL3GFilterInitStruct)\r
+{\r
+ uint8_t CTRL2 = 0x00, CTRL5 = 0x00;\r
+\r
+ L3gxByteRead(&CTRL5,L3G_CTRL_REG5);\r
+ if(pxL3GFilterInitStruct->xHPF == L3G_ENABLE)\r
+ {\r
+ CTRL5 |= 0x10;\r
+ }\r
+ else\r
+ {\r
+ CTRL5 &= 0xCF;\r
+ }\r
+\r
+ CTRL2 |= (uint8_t)(pxL3GFilterInitStruct->xHPF_Mode | pxL3GFilterInitStruct->cHPFCutOff);\r
+\r
+ L3gxByteWrite(&CTRL5,L3G_CTRL_REG5);\r
+ L3gxByteWrite(&CTRL2,L3G_CTRL_REG2);\r
+ L3gxByteWrite(&pxL3GFilterInitStruct->cHPFReference,L3G_REFERENCE);\r
+}\r
+\r
+/**\r
+* @brief Get configuration of Internal High Pass Filter of L3GX for the linear acceleration\r
+* @param L3GFilterInit : pointer to a L3GFilterInit structure that will\r
+* contain the configuration setting read from the L3GX registers.\r
+* @retval None\r
+*/\r
+void L3gxFilterGetInfo(L3GFilterInit* pxL3GFilterInitStruct)\r
+{\r
+ uint8_t CTRL2 = 0x00, CTRL5 = 0x00;\r
+\r
+ /* Read the sensor registers */\r
+ L3gxByteRead(&CTRL5,L3G_CTRL_REG5);\r
+ L3gxByteRead(&CTRL2,L3G_CTRL_REG2);\r
+\r
+ /* check if enabled */\r
+ if(CTRL5 & 0x10)\r
+ pxL3GFilterInitStruct->xHPF=L3G_ENABLE;\r
+ else\r
+ pxL3GFilterInitStruct->xHPF=L3G_DISABLE;\r
+\r
+ /* Get mode and cutoff */\r
+ pxL3GFilterInitStruct->xHPF_Mode = (GyroHPFMode)(CTRL2 & 0x30);\r
+ pxL3GFilterInitStruct->cHPFCutOff = (CTRL2 & 0x0F);\r
+\r
+ /* Get reference */\r
+ L3gxByteRead(&pxL3GFilterInitStruct->cHPFReference,L3G_REFERENCE);\r
+}\r
+\r
+\r
+/**\r
+* @brief Set the L3GX Power Mode.\r
+* @param xPowerMode: Power Mode selection.\r
+* This parameter is a value of @ref GyroPowerMode .\r
+* @retval None.\r
+*/\r
+void L3gxLowpower(GyroPowerMode xPowerMode)\r
+{\r
+ uint8_t tmpreg;\r
+ L3gxByteRead(&tmpreg,L3G_CTRL_REG1);\r
+ tmpreg &= 0xF7;\r
+\r
+ tmpreg |= (uint8_t) xPowerMode;\r
+ L3gxByteWrite(&tmpreg,L3G_CTRL_REG1);\r
+}\r
+\r
+\r
+/**\r
+* @brief Set the L3GX Data Rate.\r
+* @param xDataRate: Datarate value.\r
+* This parameter can be any value of @ref GyroOutputDataRate .\r
+* @retval None.\r
+*/\r
+void L3gxSetDataRate(GyroOutputDataRate xDataRate)\r
+{\r
+ uint8_t tmpreg;\r
+\r
+ /* Read the register value */\r
+ L3gxByteRead(&tmpreg,L3G_CTRL_REG1);\r
+\r
+ /* mask and set it */\r
+ tmpreg &= 0x0F;\r
+ tmpreg |= (uint8_t)xDataRate;\r
+\r
+ /* write value on the register */\r
+ L3gxByteWrite(&tmpreg,L3G_CTRL_REG1);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the output data rate as a GyroOutputDataRate enumerative value.\r
+* @param None.\r
+* @retval GyroOutputDataRate: GyroOutputDataRate enumerative value.\r
+*/\r
+GyroOutputDataRate L3gxGetEnumDataRate(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register value */\r
+ L3gxByteRead(&tmpReg,L3G_CTRL_REG1);\r
+\r
+ /* return the masked value */\r
+ return ((GyroOutputDataRate)(tmpReg & 0xF0));\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Set the L3GX Full Scale register\r
+* @param xFullScale: new full scale value.\r
+* This parameter can be any value of @ref GyroFullScale .\r
+* @retval None.\r
+*/\r
+void L3gxSetFullScale(GyroFullScale xFullScale)\r
+{\r
+ uint8_t tmpreg;\r
+\r
+ /* Read the register value */\r
+ L3gxByteRead(&tmpreg,L3G_CTRL_REG4);\r
+\r
+ /* mask and set it */\r
+ tmpreg &= 0xCF;\r
+ tmpreg |= (uint8_t)xFullScale;\r
+\r
+ /* write value on the register */\r
+ L3gxByteWrite(&tmpreg,L3G_CTRL_REG4);\r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Returns the full scale as a GyroFullScale enumerative value.\r
+* @param None.\r
+* @retval GyroFullScale: GyroFullScale enumerative value.\r
+*/\r
+GyroFullScale L3gxGetEnumFullScale(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register value */\r
+ L3gxByteRead(&tmpReg,L3G_CTRL_REG4);\r
+\r
+ /* return the masked value */\r
+ return ((GyroFullScale)(tmpReg & 0x30));\r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Returns the Full Scale of Gyro expressed in LSB/dps.\r
+* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored.\r
+* This parameter is a pointer to a float array.\r
+* @retval None.\r
+*/\r
+void L3gxGetSensitivity(float *pfSensitivityXYZ)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ L3gxByteRead(&tmpReg,L3G_CTRL_REG4);\r
+ tmpReg &= 0x30;\r
+\r
+ /* return the correspondent value */\r
+ switch(tmpReg)\r
+ {\r
+ case L3G_FS_250_DPS:\r
+ pfSensitivityXYZ[0]=L3G_Sensitivity_250dps;\r
+ pfSensitivityXYZ[1]=L3G_Sensitivity_250dps;\r
+ pfSensitivityXYZ[2]=L3G_Sensitivity_250dps;\r
+ \r
+ break;\r
+ case L3G_FS_500_DPS:\r
+ pfSensitivityXYZ[0]=L3G_Sensitivity_500dps;\r
+ pfSensitivityXYZ[1]=L3G_Sensitivity_500dps;\r
+ pfSensitivityXYZ[2]=L3G_Sensitivity_500dps;\r
+ \r
+ break;\r
+ case L3G_FS_2000_DPS:\r
+ pfSensitivityXYZ[0]=L3G_Sensitivity_2000dps;\r
+ pfSensitivityXYZ[1]=L3G_Sensitivity_2000dps;\r
+ pfSensitivityXYZ[2]=L3G_Sensitivity_2000dps;\r
+ \r
+ break;\r
+ }\r
+ \r
+ \r
+}\r
+\r
+/**\r
+* @brief Reboots the L3GX.\r
+* @param None.\r
+* @retval None.\r
+*/\r
+void L3gxReboot(void)\r
+{\r
+ uint8_t tmpreg, value;\r
+ L3gxByteRead(&tmpreg,L3G_CTRL_REG5);\r
+\r
+ /* Take memory of the register content */\r
+ tmpreg &= 0x7F;\r
+\r
+ /* Put the BOOT field to 1 and make the reboot */\r
+ value = 0x80;\r
+ L3gxByteWrite(&value,L3G_CTRL_REG5);\r
+ /* Rewrite the old content of the register */\r
+ L3gxByteWrite(&tmpreg,L3G_CTRL_REG5);\r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Read L3GX output register, and calculate the raw angular\r
+* rate [LSB] AngRate= (out_h*256+out_l)/16 (12 bit rappresentation)\r
+* @param pnRawData: pointer to the uint16_t array where the read data must be stored.\r
+* @retval None.\r
+*/\r
+void L3gxReadRawData(int16_t* pnRawData)\r
+{\r
+ int i;\r
+ uint8_t buffer[6];\r
+ uint8_t reg;\r
+ L3gxByteRead(®,L3G_CTRL_REG4);\r
+ L3gxBufferRead(buffer,L3G_OUT_X_L, 6);\r
+\r
+ /* check in the control register 4 the data alignment (Big Endian or Little Endian)*/\r
+ if(!(reg & 0x40))\r
+ {\r
+ for(i=0; i<3; i++)\r
+ pnRawData[i]=(int16_t)(((uint16_t)buffer[2*i+1] << 8) + buffer[2*i]);\r
+ }\r
+ else\r
+ {\r
+ for(i=0; i<3; i++)\r
+ pnRawData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]);\r
+ }\r
+}\r
+\r
+\r
+/**\r
+* @brief Read L3GX output register, and calculate the angular rate expressed in dps.\r
+* @param pfData: pointer to the uint16_t array where the read data must be stored.\r
+* @retval None.\r
+*/\r
+void L3gxReadAngRate(float* pfData)\r
+{\r
+ int16_t buffer[3];\r
+ uint8_t reg;\r
+ float fSensitivity = 0.0f;\r
+ //BoardConsolePrintf("Sensitivity : %2.4f\n", fSensitivity);\r
+\r
+ /* read the register values */\r
+ L3gxReadRawData(buffer);\r
+ L3gxByteRead(®,L3G_CTRL_REG4);\r
+\r
+ /* switch the sensitivity value set in the CRTL4 */\r
+ switch(reg & 0x30)\r
+ {\r
+ case 0x00:\r
+ fSensitivity=L3G_Sensitivity_250dps;\r
+ break;\r
+\r
+ case 0x10:\r
+ fSensitivity=L3G_Sensitivity_500dps;\r
+ break;\r
+\r
+ case 0x30:\r
+ fSensitivity=L3G_Sensitivity_2000dps;\r
+ break;\r
+ }\r
+\r
+ //BoardConsolePrintf("So...\n");\r
+\r
+ //BoardConsolePrintf("Sensitivity : %2.4f\n", fSensitivity);\r
+\r
+ /* divide by sensitivity */\r
+ uint8_t i;\r
+ for(i=0; i<3; i++)\r
+ {\r
+ //BoardConsolePrintf("value=%02x\n", buffer[i]);\r
+ pfData[i]=(float)buffer[i];\r
+ //BoardConsolePrintf("data=%2.4f\n", pfData[i]);\r
+ pfData[i]/=fSensitivity;\r
+ //BoardConsolePrintf("newdata=%2.4f\n", pfData[i]);\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Read L3GX output register when FIFO mode is active.\r
+* @param pfData: pointer to float buffer where to store data.\r
+* This parameter is a float array pointer.\r
+* @param cDataToRead: number of samples to read. Each sample is made up of the three axis readings.\r
+* This parameter is an uint8_t .\r
+* @retval None\r
+*/\r
+void L3gxReadFifo(float* pfData, uint8_t cDataToRead)\r
+{\r
+ uint8_t *pcBuffer=(uint8_t*)pfData;\r
+ uint8_t j=0,reg;\r
+ float fSensitivity = 0.0;\r
+ uint16_t aux;\r
+\r
+ L3gxByteRead(®,L3G_CTRL_REG4);\r
+\r
+ /* switch the sensitivity value set in the CRTL4 */\r
+ switch(reg & 0x30)\r
+ {\r
+ case 0x00:\r
+ fSensitivity=L3G_Sensitivity_250dps;\r
+ break;\r
+\r
+ case 0x10:\r
+ fSensitivity=L3G_Sensitivity_500dps;\r
+ break;\r
+\r
+ case 0x30:\r
+ fSensitivity=L3G_Sensitivity_2000dps;\r
+ break;\r
+ }\r
+\r
+ /* Read the register content */\r
+ L3gxBufferRead(pcBuffer, L3G_OUT_X_L, cDataToRead*6);\r
+\r
+ /* convert all data to float */\r
+ uint16_t i;\r
+ for(i=0 ; i<cDataToRead*3 ; i++)\r
+ {\r
+ aux=(((uint16_t)pcBuffer[cDataToRead*6-j-1]<<8)+(uint16_t)pcBuffer[cDataToRead*6-j-2]);\r
+ pfData[cDataToRead*3-i-1] = (float)(*(int16_t*)&aux)/fSensitivity;\r
+ j+=2;\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets status for gyro data.\r
+* @param None.\r
+* @retval L3GDataStatus: Data status in a L3GDataStatus bitfields structure.\r
+*/\r
+L3GDataStatus L3gxGetDataStatus(void)\r
+{\r
+ L3GDataStatus xStatus;\r
+\r
+ /* Read the register content */\r
+ L3gxByteRead((uint8_t*)&xStatus, L3G_STATUS_REG);\r
+\r
+ return xStatus;\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Enable or disable the IRQ1 line.\r
+* @param xNewState: Enable or disable I1.\r
+* This parameter can be L3G_ENABLE or L3G_DISABLE.\r
+* @retval None\r
+*/\r
+void L3gxIrq1Config(L3GFunctionalState xNewState)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read the register content */\r
+ L3gxByteRead(&tempReg, L3G_CTRL_REG3);\r
+\r
+ /* Enable or disable I1 */\r
+ if(xNewState)\r
+ tempReg |= 0x80;\r
+ else\r
+ tempReg &= 0x7F;\r
+\r
+ /* Write byte on register */\r
+ L3gxByteWrite(&tempReg, L3G_CTRL_REG3);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the IRQ2 line to be raised on a specific event.\r
+* @param xIrq2Config: Interrupt mask to enable.\r
+* This parameter is a @ref L3GIrq2List\r
+* @param xNewState: Enable or disable I2.\r
+* This parameter can be L3G_ENABLE or L3G_DISABLE.\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* ...\r
+* ExtiConfiguration(); // set the micro exti before init\r
+* L3gxIrq2Config(L3G_I2_DRDY,L3G_ENABLE); // for example enable the data_ready IRQ\r
+* ...\r
+* @endcode\r
+*/\r
+void L3gxIrq2Config(L3GIrq2List xIrq2Config, L3GFunctionalState xNewState)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read the register content */\r
+ L3gxByteRead(&tempReg, L3G_CTRL_REG3);\r
+\r
+ /* Unmask the selected IRQ */\r
+ if(xNewState)\r
+ tempReg |= (uint8_t)xIrq2Config;\r
+ else\r
+ tempReg &= ~(uint8_t)xIrq2Config;\r
+\r
+ /* Write byte on register */\r
+ L3gxByteWrite(&tempReg, L3G_CTRL_REG3);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the sensor FIFO.\r
+* @param L3GFifoInit: pointer to the Fifo initialization structure.\r
+* This parameter is a pointer to a @ref L3GFifoInit.\r
+* @note This function won't enable the FIFO. Please call the @ref Lsm303dlhcAccFifo in order to enable this mode.\r
+* @retval None\r
+*/\r
+void L3gxFifoInit(L3GFifoInit* pxFifoInit)\r
+{\r
+ /* Built the byte to be written */\r
+ uint8_t tempReg = (pxFifoInit->xFifoMode | (pxFifoInit->cWtm & 0x1F));\r
+\r
+ /* Write the built value on the FIFO_CTRL register */\r
+ L3gxByteWrite(&tempReg, L3G_FIFO_CTRL_REG);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the sensor FIFO.\r
+* @param xNewState: New state for the FIFO use.\r
+* This parameter is a pointer to a @ref L3gxFifo\r
+* @retval None\r
+*/\r
+void L3gxFifo(L3GFunctionalState xNewState)\r
+{\r
+ /* Built the byte to be written */\r
+ uint8_t tempReg;\r
+\r
+ /* Read the value on the CTRL5 register */\r
+ L3gxByteRead(&tempReg, L3G_CTRL_REG5);\r
+\r
+ /* Build the value to write */\r
+ if(xNewState == L3G_ENABLE)\r
+ tempReg |= 0x40;\r
+ else\r
+ tempReg &= (~0x40);\r
+\r
+ /* Write the built value on the CTRL5 register */\r
+ L3gxByteWrite(&tempReg, L3G_CTRL_REG5);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the FIFO status flags and unread data.\r
+* @param None.\r
+* @retval L3GFifoStatus Fifo status descriptor.\r
+*/\r
+L3GFifoStatus L3gxFifoGetStatus(void)\r
+{\r
+ L3GFifoStatus xL3GFifoStatus;\r
+\r
+ /* Read the register content */\r
+ L3gxByteRead((uint8_t*)&xL3GFifoStatus, L3G_FIFO_SRC_REG);\r
+\r
+ /* Return its value */\r
+ return xL3GFifoStatus;\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the IRQs on Axis.\r
+* @param xIrqCombinations: Combination of events on axis.\r
+* This parameter is a @ref L3GIrqOnaxisCombination .\r
+* @param pxAxisEvents: Events on axis structure.\r
+* This parameter is a pointer to a @ref L3GAxisEvents .\r
+* @param xLatched: Latched interrupt.\r
+* This parameter can be L3G_ENABLE or L3G_DISABLE .\r
+* @retval None\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* L3GAxisEvents xAxisEvents;\r
+*\r
+* xAxisEvents.X_LOW=0;\r
+* xAxisEvents.X_HIGH=0;\r
+* xAxisEvents.Y_LOW=1;\r
+* xAxisEvents.Y_HIGH=0;\r
+* xAxisEvents.Z_LOW=0;\r
+* xAxisEvents.Z_HIGH=1;\r
+*\r
+* L3gxSetAxisIrqs(L3G_OR_COMBINATION,&xAxisEvents,L3G_DISABLE);\r
+* @endcode\r
+*/\r
+void L3gxSetAxisIrqs(L3GIrqOnaxisCombination xIrqCombinations, L3GAxisEvents* pxAxisEvents, L3GFunctionalState xLatched)\r
+{\r
+ /* Build the value to build on register */\r
+ uint8_t tempReg = ((uint8_t)xIrqCombinations) | (*(uint8_t*)pxAxisEvents);\r
+\r
+ /* if required, set the IRQ latched bit */\r
+ if(xLatched)\r
+ tempReg |= 0x40;\r
+\r
+ /* Write the built value on the irq1 configuration register */\r
+ L3gxByteWrite(&tempReg, L3G_INT1_CFG_REG);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the IRQs on Axis status.\r
+* @param pxAxisEvents: Events on axis structure.\r
+* This parameter is a pointer to a @ref L3GAxisEvents .\r
+* @retval None\r
+*/\r
+L3GFunctionalState L3gxGetAxisIrqs(L3GAxisEvents* pxAxisEvents)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read register */\r
+ L3gxByteRead(&tempReg, L3G_INT1_SCR_REG);\r
+\r
+ uint8_t tempRet = tempReg & 0x3F;\r
+\r
+ /* Take the MSb to return */\r
+ (*pxAxisEvents)=*(L3GAxisEvents*)(&tempRet);\r
+\r
+ return (L3GFunctionalState)((tempReg & 0x40)>>6);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets threshold for the angular rate.\r
+* @param pfData: Angular rate threshold ordered by axis (XYZ) and expressed in dps.\r
+* This parameter is a float array.\r
+* @retval None\r
+*/\r
+void L3gxSetThreshold(float *pfData)\r
+{\r
+ uint8_t reg, j=0, pcData[6];\r
+ float fSensitivity = 0.0, aux;\r
+ int16_t pnData[3];\r
+\r
+ /* X and Y thresholds and flags are inverted.. here a workaround */\r
+ aux=pfData[1];\r
+ pfData[1]=pfData[0];\r
+ pfData[0]=aux;\r
+\r
+ /* Read the CTRL4 register */\r
+ L3gxByteRead(®,L3G_CTRL_REG4);\r
+\r
+ /* switch the sensitivity value set in the CRTL4\r
+ (00: 250 dps; 01: 500 dps; 10: 2000 dps; 11: 2000 dps)\r
+ */\r
+ switch(reg & 0x30)\r
+ {\r
+ case 0x00:\r
+ fSensitivity=L3G_Sensitivity_250dps;\r
+ break;\r
+\r
+ case 0x10:\r
+ fSensitivity=L3G_Sensitivity_500dps;\r
+ break;\r
+\r
+ case 0x20: case 0x30:\r
+ fSensitivity=L3G_Sensitivity_2000dps;\r
+ break;\r
+ }\r
+\r
+ /* Convert the dps values in register values */\r
+ uint8_t i;\r
+ for(i=0;i<3;i++)\r
+ {\r
+ pnData[i] = (int16_t)(pfData[i]*fSensitivity);\r
+\r
+ pcData[j++] = (uint8_t)(pnData[i]>>8);\r
+ pcData[j++] = (uint8_t)pnData[i];\r
+ }\r
+\r
+ /* Write the values on registers */\r
+ L3gxBufferWrite(pcData,L3G_INT1_THS_XH_REG,6);\r
+\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Read L3G4300D temperature output register.\r
+* @param None.\r
+* @retval float: Temperature (C/LSB).\r
+*/\r
+float L3gxReadTemp(void)\r
+{\r
+ int8_t buffer;\r
+\r
+ /* Read register */\r
+ L3gxByteRead((uint8_t*)&buffer, L3G_OUT_TEMP);\r
+\r
+ /* convert to float */\r
+ return (float)buffer;\r
+\r
+}\r
+\r
+\r
+/**\r
+*@}\r
+*/\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+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
--- /dev/null
+/**\r
+ * @file LSM303DLHC.h\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief Header for LPS331AP.c file\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+\r
+/* Define to prevent recursive inclusion -------------------------------------*/\r
+#ifndef __LPS331AP_H\r
+#define __LPS331AP_H\r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include <stdint.h>\r
+#include "HAL_LPS331AP.h"\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+ \r
+/**\r
+ * @defgroup LPS331AP\r
+ * @brief This module contains all the functions to configure the LPS331AP pressure sensor.\r
+ * @details\r
+ * Since this code is platform independent an implementation of the SPI or I2C driver must\r
+ * be provided by the user according to the used platform.\r
+ * Every function makes use of the <i>Lps331apBufferRead</i> and/or <i>Lps331apBufferWrite</i>\r
+ * as low level functions to write bytes through the used digital interface.\r
+ * In order to link and use this code the user should define and export these functions in a header\r
+ * file called "HAL_LPS331AP.h" (included by this module).\r
+ * \r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup LPS331AP_Exported_Types LPS331AP Exported Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief LPS331AP Functional state. Used to enable or disable a specific option. \r
+ */ \r
+typedef enum\r
+{\r
+ LPS_DISABLE = 0,\r
+ LPS_ENABLE = !LPS_DISABLE\r
+}LPSFunctionalState; \r
+ \r
+ \r
+/**\r
+ * @brief Pressure Flag status. Used to set/reset the sensor flags.\r
+ */ \r
+typedef enum\r
+{\r
+ LPS_RESET = 0,\r
+ LPS_SET = !LPS_RESET\r
+}LPSFlagStatus;\r
+\r
+\r
+/**\r
+ * @brief LPS331AP Output Data Rate\r
+ */ \r
+typedef enum\r
+{\r
+ ODR_P_T_ONE_SHOT = 0x00, /*!< Output Data Rate: P - one shot, T - one shot */\r
+ ODR_P_1HZ_T_1HZ = 0x10, /*!< Output Data Rate: P - 1Hz, T - 1Hz */\r
+ ODR_P_7HZ_T_1HZ = 0x20, /*!< Output Data Rate: P - 7Hz, T - 1Hz */\r
+ ODR_P_12_5HZ_T_1HZ = 0x30, /*!< Output Data Rate: P - 12.5Hz, T - 1Hz */\r
+ ODR_P_25HZ_T_1HZ = 0x40, /*!< Output Data Rate: P - 25Hz, T - 1Hz */\r
+ ODR_P_7HZ_T_7HZ = 0x50, /*!< Output Data Rate: P - 7Hz, T - 7Hz */\r
+ ODR_P_12_5HZ_T_12_5HZ = 0x60, /*!< Output Data Rate: P - 12.5Hz, T - 12.5Hz */\r
+ ODR_P_25HZ_T_25HZ = 0x70, /*!< Output Data Rate: P - 25Hz, T - 25Hz */\r
+}LPSOutputDataRate;\r
+\r
+\r
+/**\r
+ * @brief LPS331AP Pressure resolution\r
+ */ \r
+typedef enum\r
+{\r
+ LPS_PRESS_AVG_1 = 0x00, /*!< Internal average on 1 sample */\r
+ LPS_PRESS_AVG_2 = 0x01, /*!< Internal average on 2 sample */\r
+ LPS_PRESS_AVG_4 = 0x02, /*!< Internal average on 4 sample */\r
+ LPS_PRESS_AVG_8 = 0x03, /*!< Internal average on 8 sample */\r
+ LPS_PRESS_AVG_16 = 0x04, /*!< Internal average on 16 sample */\r
+ LPS_PRESS_AVG_32 = 0x05, /*!< Internal average on 32 sample */\r
+ LPS_PRESS_AVG_64 = 0x06, /*!< Internal average on 64 sample */\r
+ LPS_PRESS_AVG_128 = 0x07, /*!< Internal average on 128 sample */\r
+ LPS_PRESS_AVG_256 = 0x08, /*!< Internal average on 256 sample */\r
+ LPS_PRESS_AVG_384 = 0x09, /*!< Internal average on 384 sample */\r
+ LPS_PRESS_AVG_512 = 0x0A, /*!< Internal average on 512 sample */\r
+}LPSPressureResolution;\r
+\r
+\r
+/**\r
+ * @brief LPS331AP Temperature resolution\r
+ */ \r
+typedef enum\r
+{\r
+ LPS_TEMP_AVG_1 = 0x00, /*!< Internal average on 1 sample */\r
+ LPS_TEMP_AVG_2 = 0x10, /*!< Internal average on 2 sample */\r
+ LPS_TEMP_AVG_4 = 0x20, /*!< Internal average on 4 sample */\r
+ LPS_TEMP_AVG_8 = 0x30, /*!< Internal average on 8 sample */\r
+ LPS_TEMP_AVG_16 = 0x40, /*!< Internal average on 16 sample */\r
+ LPS_TEMP_AVG_32 = 0x50, /*!< Internal average on 32 sample */\r
+ LPS_TEMP_AVG_64 = 0x60, /*!< Internal average on 64 sample */\r
+ LPS_TEMP_AVG_128 = 0x70, /*!< Internal average on 128 sample */\r
+}LPSTemperatureResolution;\r
+\r
+\r
+\r
+/**\r
+ * @brief LPS331AP Irq list\r
+ */\r
+typedef enum\r
+{\r
+ LPS_GND = 0x00,\r
+ LPS_P_HIGH = 0x01,\r
+ LPS_P_LOW = 0x02,\r
+ LPS_P_LOW_HIGH = 0x03,\r
+ LPS_DATA_READY = 0x04,\r
+ LPS_TRISTATE = 0x07,\r
+}LPSIrqList;\r
+\r
+\r
+/**\r
+ * @brief LPS331AP Irq pin output configuration\r
+ */\r
+typedef enum\r
+{\r
+ LPS_PP = 0x00,\r
+ LPS_OD = 0x40\r
+}LPSOutputType;\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor Irq initialization structure\r
+ */\r
+typedef struct\r
+{\r
+ LPSFunctionalState xIrqActiveLow;\r
+ LPSOutputType xOutType;\r
+ LPSIrqList xInt1List;\r
+ LPSIrqList xInt2List;\r
+ float fPressThr;\r
+ LPSFunctionalState xIrqPressLow;\r
+ LPSFunctionalState xIrqPressHigh;\r
+}LPSIrqInit;\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ LPSOutputDataRate xOutputDataRate; /*!< Output Data Rate */\r
+ LPSPressureResolution xPresRes; /*!< Pressure sensor resolution */\r
+ LPSTemperatureResolution xTempRes; /*!< Temperature sensor resolution */\r
+ LPSFunctionalState xPressureAutoZero; /*!< Auto zero feature enabled */\r
+ float fPressureRef; /*!< Pressure sensor reference value */\r
+ LPSFunctionalState xBDU; /*!< Auto zero feature enabled */\r
+}LPS331Init;\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor data status structure structure\r
+ */\r
+typedef struct\r
+{\r
+ LPSFlagStatus cTempDataAvailable:1; /*!< Temperature data available bit */\r
+ LPSFlagStatus cPressDataAvailable:1; /*!< Pressure data available bit */\r
+ uint8_t :2; /*!< 2 bits padding */\r
+ LPSFlagStatus cTempDataOverrun:1; /*!< Temperature data over-run bit */\r
+ LPSFlagStatus cPressDataOverrun:1; /*!< Pressure data over-run bit */\r
+ uint8_t :2; /*!< 2 bits padding */\r
+}LPS331DataStatus;\r
+\r
+\r
+/**\r
+ * @}\r
+ */ \r
+ \r
+/**\r
+ * @defgroup LPS331AP_Exported_Constants LPS331AP Exported Constants\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup LPS331AP_Exported_Macros LPS331AP Exported Macros\r
+ * @{\r
+ */\r
+\r
+/**\r
+* @brief Read LPS331AP output register, and calculate the pressure in mbar.\r
+* @param None.\r
+* @retval float: pressure expressed in mbar.\r
+*/\r
+#define Lps331apReadPressure() ((float)Lps331apReadRawPressure()/4096)\r
+\r
+\r
+/**\r
+* @brief Read LPS331AP output register, and calculate the temperature in C deg.\r
+* @param None.\r
+* @retval float: temperature expressed in C deg.\r
+*/\r
+#define Lps331apReadTemperature() ((float)Lps331apReadRawTemperature()/480.0+42.5)\r
+\r
+\r
+/** @defgroup LPS331AP_Communication LPS331AP Communication\r
+ * @{\r
+ */\r
+\r
+#define Lps331apByteRead(pVal,cAddress) Lps331apBufferRead(pVal,cAddress,1)\r
+#define Lps331apByteWrite(pVal,cAddress) Lps331apBufferWrite(pVal,cAddress,1)\r
+\r
+\r
+/**\r
+ * @} \r
+ */\r
+\r
+/**\r
+ * @} \r
+ */ \r
+\r
+\r
+/** @defgroup LPS331AP_Register_Mapping LPS331AP Register Mapping\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Reference pressure (LSB data)\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 REF7-ODR0: Lower part of the reference pressure that\r
+ * is sum to the sensor output pressure.\r
+ * \endcode\r
+ */\r
+#define LPS_REF_P_XL_ADDR 0x08\r
+\r
+\r
+/**\r
+ * @brief Reference pressure (middle part)\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 REF15-ODR8: Middle part of the reference pressure that\r
+ * is sum to the sensor output pressure.\r
+ * \endcode\r
+ */\r
+#define LPS_REF_P_L_ADDR 0x09\r
+\r
+\r
+/**\r
+ * @brief Reference pressure (MSB part)\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 REF15-ODR8: Higher part of the reference pressure that\r
+ * is sum to the sensor output pressure.\r
+ * \endcode\r
+ */\r
+#define LPS_REF_P_H_ADDR 0x0A\r
+\r
+\r
+/**\r
+ * @brief Device identifier register.\r
+ * \code\r
+ * Read\r
+ * Default value: 0xBB\r
+ * 7:0 This read-only register contains the device identifier that, for LPS331AP, is set to BBh.\r
+ * \endcode\r
+ */\r
+#define LPS_WHO_AM_I_ADDR 0x0F\r
+\r
+\r
+/**\r
+ * @brief Pressure resolution Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x7A\r
+ * 7 RFU\r
+ * 6:4 AVGT2-AVGT0: temperature internal average.\r
+ * AVGT2 | AVGT1 | AVGT0 | Nr. Internal Average\r
+ * ------------------------------------------------------\r
+ * 0 | 0 | 0 | 1 \r
+ * 0 | 0 | 1 | 2 \r
+ * 0 | 1 | 0 | 4 \r
+ * 0 | 1 | 1 | 8 \r
+ * 1 | 0 | 0 | 16 \r
+ * 1 | 0 | 1 | 32\r
+ * 1 | 1 | 0 | 64\r
+ * 1 | 1 | 1 | 128\r
+ *\r
+ * 3:0 AVGP3-AVGP0: pressure internal average.\r
+ * AVGP3 | AVGP2 | AVGP1 | AVGP0 | Nr. Internal Average\r
+ * ------------------------------------------------------\r
+ * 0 | 0 | 0 | 0 | 1\r
+ * 0 | 0 | 0 | 1 | 2 \r
+ * 0 | 0 | 1 | 0 | 4 \r
+ * 0 | 0 | 1 | 1 | 8\r
+ * 0 | 1 | 0 | 0 | 16 \r
+ * 0 | 1 | 0 | 1 | 32 \r
+ * 0 | 1 | 1 | 0 | 64\r
+ * 0 | 1 | 1 | 1 | 128 \r
+ * 1 | 0 | 0 | 0 | 256 \r
+ * 1 | 0 | 0 | 1 | 384\r
+ * 1 | 0 | 1 | 0 | 512 \r
+ *\r
+ * \endcode\r
+ */\r
+#define LPS_RES_CONF_ADDR 0x10 \r
+\r
+\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor control register 1\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 PD: power down control. 0 - disable; 1 - enable\r
+ * 6:4 ODR2, ODR1, ODR0: output data rate selection.\r
+ * ODR2 | ODR1 | ODR0 | Pressure output data-rate(Hz) | Temperature output data-rate(Hz)\r
+ * ----------------------------------------------------------------------------------\r
+ * 0 | 0 | 0 | one shot | one shot \r
+ * 0 | 0 | 1 | 1 | 1 \r
+ * 0 | 1 | 0 | 7 | 1 \r
+ * 0 | 1 | 1 | 12.5 | 1 \r
+ * 1 | 0 | 0 | 25 | 1 \r
+ * 1 | 0 | 1 | 7 | 7 \r
+ * 1 | 1 | 0 | 12.5 | 12.5 \r
+ * 1 | 1 | 1 | 25 | 25\r
+ *\r
+ * 3 DIFF_EN: Interrupt circuit. 0 - disable; 1 - enable\r
+ * 2 BDU: block data update. 0 - disable; 1 - enable\r
+ * 1 DELTA_EN: delta pressure. 0 - disable; 1 - enable\r
+ * 0 SIM: SPI Serial Interface Mode selection. 0 - disable; 1 - enable\r
+ * \endcode\r
+ */\r
+#define LPS_CTRL_REG1_ADDR 0x20\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor control register 2\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 BOOT: Reboot memory content. 0: normal mode; 1: reboot memory content\r
+ * 6:3 Reserved.\r
+ * 2 SWRESET: Software reset. 0: normal mode; 1: SW reset.\r
+ * 1 AUTO_ZERO: Autozero enable. 0: normal mode; 1: autozero enable.\r
+ * 0 ONE_SHOT: One shot enable. 0: waiting for start of conversion; 1: start for a new dataset\r
+ * \endcode\r
+ */\r
+#define LPS_CTRL_REG2_ADDR 0x21\r
+\r
+\r
+/**\r
+ * @brief Pressure sensor control register 3\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 INT_H_L: Interrupt active high, low.\r
+ * 6 PP_OD: Push-pull/open drain selection on interrupt pads.\r
+ * 5:3 INT2_S3, INT2_S2, INT2_S1: data signal on INT2 pad control bits.\r
+ * 2:0 INT1_S3, INT1_S2, INT1_S1: data signal on INT1 pad control bits.\r
+ * INT1(2)_S3 | INT1(2)_S2 | INT1(2)_S1 | INT1(2) pin\r
+ * ------------------------------------------------------\r
+ * 0 | 0 | 0 | GND \r
+ * 0 | 0 | 1 | Pressure high (P_high) \r
+ * 0 | 1 | 0 | Pressure low (P_low) \r
+ * 0 | 1 | 1 | P_low OR P_high \r
+ * 1 | 0 | 0 | Data ready \r
+ * 1 | 0 | 1 | Reserved\r
+ * 1 | 1 | 0 | Reserved\r
+ * 1 | 1 | 1 | Tri-state\r
+\r
+ * \endcode\r
+ */\r
+#define LPS_CTRL_REG3_ADDR 0x22 \r
+\r
+\r
+/**\r
+ * @brief Interrupt configuration Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00.\r
+ * 7:3 Reserved.\r
+ * 2 LIR: Latch Interrupt request into INT_SOURCE register. 0 - disable; 1 - enable\r
+ * 1 PL_E: Enable interrupt generation on differential pressure low event. 0 - disable; 1 - enable\r
+ * 0 PH_E: Enable interrupt generation on differential pressure high event. 0 - disable; 1 - enable\r
+ * \endcode\r
+ */\r
+#define LPS_INT_CFG_REG_ADDR 0x23 \r
+\r
+\r
+/**\r
+ * @brief Interrupt source Register\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * 7:3 0.\r
+ * 2 IA: Interrupt Active.0: no interrupt has been generated; 1: one or more interrupt events have been generated.\r
+ * 1 PL: Differential pressure Low. 0: no interrupt has been generated; 1: Low differential pressure event has occurred.\r
+ * 0 PH: Differential pressure High. 0: no interrupt has been generated; 1: High differential pressure event has occurred.\r
+ * \endcode\r
+ */\r
+#define LPS_INT_SOURCE_REG_ADDR 0x24 \r
+\r
+\r
+/**\r
+ * @brief Threshold pressure (LSB)\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * 7:0 THS7-THS0: Low part of threshold value for pressure interrupt\r
+ * generation. The complete threshold value is given by THS_P_H & THS_P_L and is\r
+ * expressed as unsigned number. P_ths(mbar)=(THS_P_H & THS_P_L)[dec]/16.\r
+ * \endcode\r
+ */\r
+#define LPS_THS_P_LOW_REG_ADDR 0x25 \r
+\r
+\r
+/**\r
+ * @brief Threshold pressure (MSB)\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * 7:0 THS15-THS8: High part of threshold value for pressure interrupt\r
+ * generation. The complete threshold value is given by THS_P_H & THS_P_L and is\r
+ * expressed as unsigned number. P_ths(mbar)=(THS_P_H & THS_P_L)[dec]/16.\r
+ * \endcode\r
+ */\r
+#define LPS_THS_P_HIGH_REG_ADDR 0x26 \r
+\r
+\r
+/**\r
+ * @brief Status Register\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7:6 0\r
+ * 5 P_OR: Pressure data overrun. 0: no overrun has occurred; 1: new data for pressure has overwritten the previous one.\r
+ * 4 T_OR: Temperature data overrun. 0: no overrun has occurred; 1: a new data for temperature has overwritten the previous one.\r
+ * 3:2 0\r
+ * 1 P_DA: Pressure data available. 0: new data for pressure is not yet available; 1: new data for pressure is available.\r
+ * 0 T_DA: Temperature data available. 0: new data for temperature is not yet available; 1: new data for temperature is available.\r
+ * \endcode\r
+ */\r
+#define LPS_STATUS_REG_ADDR 0x27 \r
+\r
+\r
+/**\r
+ * @brief Pressure data (LSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * POUT7 - POUT0: Pressure data LSB (2's complement). \r
+ * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L &\r
+ * PRESS_OUT_XL)[dec]/4096.\r
+ * \endcode\r
+ */\r
+#define LPS_PRESS_POUT_XL_ADDR 0x28 \r
+\r
+\r
+/**\r
+ * @brief Pressure data (Middle part).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x80.\r
+ * POUT15 - POUT8: Pressure data middle part (2's complement). \r
+ * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L &\r
+ * PRESS_OUT_XL)[dec]/4096.\r
+ * \endcode\r
+ */\r
+#define LPS_PRESS_OUT_L_ADDR 0x29\r
+\r
+\r
+/**\r
+ * @brief Pressure data (MSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x2F.\r
+ * POUT23 - POUT16: Pressure data MSB (2's complement).\r
+ * Pressure output data: Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L &\r
+ * PRESS_OUT_XL)[dec]/4096.\r
+ * \endcode\r
+ */\r
+#define LPS_PRESS_OUT_H_ADDR 0x2A\r
+\r
+\r
+/**\r
+ * @brief Temperature data (LSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * TOUT7 - TOUT0: temperature data LSB. \r
+ * T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec]/480.\r
+ * \endcode\r
+ */\r
+#define LPS_TEMP_OUT_L_ADDR 0x2B\r
+\r
+\r
+/**\r
+ * @brief Temperature data (MSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * TOUT15 - TOUT8: temperature data MSB. \r
+ * T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec]/480.\r
+ * \endcode\r
+ */\r
+#define LPS_TEMP_OUT_H_ADDR 0x2C \r
+\r
+\r
+/**\r
+ * @brief Analog front end control\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:1 Reserved.\r
+ * 0 SELMAIN: Current of operational amplifier selector.\r
+ * -\911\92 always high current\r
+ * -\910\92 high current during pressure acquisition and low current during temperature acquisition\r
+ * \endcode\r
+ */\r
+#define LPS_AMP_CTRL_ADDR 0x30 \r
+\r
+\r
+\r
+/**\r
+ * @brief Pressure offset (LSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00.\r
+ * DELTA0 - DELTA7: Delta pressure register for One Point calibration. \r
+ * \endcode\r
+ */\r
+#define LPS_DELTA_PRESS_XL_ADDR 0x3C \r
+\r
+\r
+/**\r
+ * @brief Pressure offset (Middle part).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x80.\r
+ * DELTA15-DELTA8: Delta pressure register for One Point calibration. \r
+ * \endcode\r
+ */\r
+#define LPS_DELTA_PRESS_L_ADDR 0x3D\r
+\r
+\r
+/**\r
+ * @brief Pressure offset (MSB).\r
+ * \code\r
+ * Read\r
+ * Default value: 0x2F.\r
+ * DELTA23-DELTA16: Delta pressure register for One Point calibration.\r
+ * \endcode\r
+ */\r
+#define LPS_DELTA_PRESS_H_ADDR 0x3E\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+\r
+/** @defgroup LPS331AP_Exported_Functions LPS331AP Exported Functions\r
+ * @{\r
+ */\r
+\r
+void Lps331apConfig(LPS331Init* pxLPS331InitStruct);\r
+void Lps331apGetInfo(LPS331Init* pxLPS331InitStruct);\r
+void Lps331apLowPowerMode(LPSFunctionalState xFunctionalState);\r
+void Lps331apSetPressureResolution(LPSPressureResolution xPressureResolution);\r
+void Lps331apSetTemperatureResolution(LPSTemperatureResolution xTemperatureResolution);\r
+void Lps331apSetDataRate(LPSOutputDataRate xDataRate);\r
+LPSOutputDataRate Lps331apGetDataRate(void);\r
+void Lps331apRebootCmd(void);\r
+void Lps331apEnterShutdownCmd(void);\r
+void Lps331apExitShutdownCmd(void);\r
+int32_t Lps331apReadRawPressure(void);\r
+int16_t Lps331apReadRawTemperature(void);\r
+void Lps331apIrqInit(LPSIrqInit* pxLPSIrqInit);\r
+void Lps331apOneShot(void);\r
+LPS331DataStatus Lps331apGetDataStatus(void);\r
+void Lps331apSetThreshold(float fThreshold);\r
+float Lps331apGetThreshold(void);\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
+\r
--- /dev/null
+/**\r
+ * @file LSM303DLH.c\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief This file provides a set of functions needed to manage the LPS331AP slave.\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+#include "LPS331AP.h"\r
+\r
+\r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+* @addtogroup LPS331AP\r
+* @{\r
+*/\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_TypesDefinitions LPS331AP Private TypesDefinitions\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_Defines LPS331AP Private Defines\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_Macros LPS331AP Private Macros\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_Variables LPS331AP Private Variables\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_FunctionPrototypes LPS331AP Private FunctionPrototypes\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup LPS331AP_Private_Functions LPS331AP Private Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+* @brief Set configuration of pressure sensor LPS331AP\r
+* @param pxLPS331InitStruct : pointer to a LPS331Init structure that contains the configuration setting for the LPS331AP.\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* LPS331Init xLps331apInit;\r
+*\r
+* xLps331apInit.xOutputDataRate=ODR_P_7HZ_T_1HZ;\r
+* xLps331apInit.xPresRes=LPS_PRESS_AVG_1;\r
+* xLps331apInit.xTempRes=LPS_TEMP_AVG_1;\r
+* xLps331apInit.xPressureAutoZero=LPS_DISABLE;\r
+* xLps331apInit.fPressureRef=0;\r
+* xLps331apInit.xBDU=LPS_DISABLE;\r
+*\r
+* Lps331apInit(&xLps331apInit);\r
+* @endcode\r
+*/\r
+void Lps331apConfig(LPS331Init* pxLPS331InitStruct)\r
+{\r
+ uint8_t tempReg[3];\r
+ uint8_t i;\r
+ \r
+ for(i=0 ; i<3 ; i++)\r
+ tempReg[i]=(uint8_t)(((uint32_t)(4096.0*pxLPS331InitStruct->fPressureRef))>>(8*i));\r
+ \r
+ /* Write the reference value on register */\r
+ Lps331apBufferWrite(tempReg, LPS_REF_P_XL_ADDR,3);\r
+ \r
+ /* Resolution register setting */\r
+ tempReg[0] = (uint8_t)pxLPS331InitStruct->xPresRes | (uint8_t)pxLPS331InitStruct->xTempRes;\r
+ \r
+ /* Write the value on register */ \r
+ Lps331apByteWrite(&tempReg[0], LPS_RES_CONF_ADDR);\r
+ \r
+ /* Read the CTRL1 and 2 register content */\r
+ Lps331apBufferRead(tempReg, LPS_CTRL_REG1_ADDR,2); \r
+ \r
+ /* Enter the SDN mode */\r
+ tempReg[0] &= 0x7F;\r
+ Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /* CTRL1 register */\r
+ tempReg[0] &= 0x8B;\r
+ tempReg[0] |= pxLPS331InitStruct->xOutputDataRate;\r
+ \r
+ if(pxLPS331InitStruct->xBDU)\r
+ tempReg[0] |= 0x04;\r
+ else\r
+ tempReg[0] &= 0xFB;\r
+ \r
+ /* CTRL2 register */\r
+ if(pxLPS331InitStruct->xPressureAutoZero)\r
+ tempReg[1] |= 0x02;\r
+ else\r
+ tempReg[1] &= 0xFD;\r
+\r
+ /* Write the reference value on register */\r
+ Lps331apBufferWrite(tempReg, LPS_CTRL_REG1_ADDR,2);\r
+ \r
+ /* Exit the SDN mode */\r
+ tempReg[0] |= 0x80;\r
+ Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the general configuration of LPS331AP.\r
+* @param pxLPS331InitStruct : pointer to a LPS331Init structure that will\r
+* contain the configuration setting read from the LPS331AP registers.\r
+* @retval None\r
+*/\r
+void Lps331apGetInfo(LPS331Init* pxLPS331InitStruct)\r
+{\r
+ uint8_t tempReg[4];\r
+ \r
+ Lps331apBufferRead(tempReg, LPS_REF_P_XL_ADDR,3);\r
+ tempReg[3]=0;\r
+ \r
+ /* Get the reference value */\r
+ pxLPS331InitStruct->fPressureRef = (float)(*((uint32_t*)tempReg))/4096.0;\r
+\r
+ /* Read register */ \r
+ Lps331apByteRead(&tempReg[0], LPS_RES_CONF_ADDR);\r
+ \r
+ pxLPS331InitStruct->xPresRes=(LPSPressureResolution)(tempReg[0] & 0x0F);\r
+ pxLPS331InitStruct->xTempRes=(LPSTemperatureResolution)(tempReg[0] & 0x70);\r
+ \r
+ /* Read the CTRL1 and 2 register content */\r
+ Lps331apBufferRead(tempReg, LPS_CTRL_REG1_ADDR,2);\r
+ \r
+ /* get info */\r
+ if(tempReg[0] & 0x04)\r
+ pxLPS331InitStruct->xBDU = LPS_ENABLE;\r
+ else\r
+ pxLPS331InitStruct->xBDU = LPS_DISABLE;\r
+ \r
+\r
+ if(tempReg[1] & 0x02)\r
+ pxLPS331InitStruct->xPressureAutoZero = LPS_ENABLE;\r
+ else\r
+ pxLPS331InitStruct->xPressureAutoZero = LPS_DISABLE;\r
+ \r
+ /* Get the ODR info */\r
+ Lps331apByteRead(tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ pxLPS331InitStruct->xOutputDataRate = (LPSOutputDataRate)(tempReg[0] & 0x70);\r
+ \r
+}\r
+\r
+\r
+/**\r
+* @brief Enable or disable the lowpower mode for pressure sensor LPS331AP.\r
+* @param xFunctionalState : new state for the lowpower mode.\r
+* This parameter can be: LPS_ENABLE or LPS_DISABLE\r
+* @retval None\r
+*/\r
+void Lps331apLowPowerMode(LPSFunctionalState xFunctionalState)\r
+{\r
+ uint8_t tmpreg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tmpreg, LPS_AMP_CTRL_ADDR);\r
+ \r
+ /* modify the specified bit */\r
+ if(xFunctionalState == LPS_ENABLE)\r
+ {\r
+ tmpreg |= 0x01;\r
+ }\r
+ else\r
+ {\r
+ tmpreg &= 0xFE;\r
+ }\r
+ \r
+ /* Write the computed values on register */\r
+ Lps331apByteWrite(&tmpreg, LPS_AMP_CTRL_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Change pressure resolution for Pressure sensor LPS331AP.\r
+* @param xPressureResolution : new pressure resolution value. \r
+* This parameter can be one of the @ref LPSPressureResolution value.\r
+* @retval None\r
+*/\r
+void Lps331apSetPressureResolution(LPSPressureResolution xPressureResolution)\r
+{\r
+ uint8_t tempReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tempReg, LPS_RES_CONF_ADDR);\r
+ \r
+ /* CTRL1 register */\r
+ tempReg &= 0xF0;\r
+ tempReg |= xPressureResolution;\r
+ \r
+ /* Write computed byte onto register */\r
+ Lps331apByteWrite(&tempReg, LPS_RES_CONF_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Change temperature resolution for Pressure sensor LPS331AP.\r
+* @param xTemperatureResolution : new pressure resolution value. \r
+* This parameter can be one of the @ref LPSTemperatureResolution value.\r
+* @retval None\r
+*/\r
+void Lps331apSetTemperatureResolution(LPSTemperatureResolution xTemperatureResolution)\r
+{\r
+ uint8_t tempReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tempReg, LPS_RES_CONF_ADDR);\r
+ \r
+ /* CTRL1 register */\r
+ tempReg &= 0x8F;\r
+ tempReg |= xTemperatureResolution;\r
+ \r
+ /* Write computed byte onto register */\r
+ Lps331apByteWrite(&tempReg, LPS_RES_CONF_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Change the ODR(Output data rate) for pressure sensor LPS331AP.\r
+* @param xDataRate : new ODR value. \r
+* This parameter can be one of the @ref LPSOutputDataRate value.\r
+* @retval None\r
+*/\r
+void Lps331apSetDataRate(LPSOutputDataRate xDataRate)\r
+{\r
+ uint8_t tempReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /* CTRL1 register */\r
+ tempReg &= 0x8F;\r
+ tempReg |= xDataRate;\r
+ \r
+ /*Enter Power Down mode*/\r
+ Lps331apEnterShutdownCmd();\r
+ \r
+ /* Write computed byte onto register */\r
+ Lps331apByteWrite(&tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /*Exit from Power down mode*/\r
+ Lps331apExitShutdownCmd();\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the output data rate.\r
+* @param None.\r
+* @retval Datarate in Hz.\r
+* This parameter is a @ref LPSOutputDataRate.\r
+*/\r
+LPSOutputDataRate Lps331apGetDataRate(void)\r
+{\r
+ uint8_t tmpReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /* ..mask it */\r
+ tmpReg &= 0x70;\r
+\r
+ /* return the correspondent value */\r
+ return ((LPSOutputDataRate)tmpReg);\r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Reboot memory content of LPS331AP.\r
+* @param None\r
+* @retval None\r
+*/\r
+void Lps331apRebootCmd(void)\r
+{\r
+ uint8_t tmpReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tmpReg, LPS_CTRL_REG2_ADDR);\r
+ \r
+ /* Set the BOOT bit */\r
+ tmpReg |= 0x80;\r
+ \r
+ /* Write register */\r
+ Lps331apByteWrite(&tmpReg, LPS_CTRL_REG2_ADDR);\r
+ \r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Enter the shutdown mode for LPS331AP.\r
+* @param None\r
+* @retval None\r
+*/\r
+void Lps331apEnterShutdownCmd(void)\r
+{\r
+ uint8_t tmpReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /* Reset the power down bit */\r
+ tmpReg &= 0x7F;\r
+ \r
+ /* Write register */\r
+ Lps331apByteWrite(&tmpReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+}\r
+\r
+\r
+/**\r
+* @brief Exit the shutdown mode for LPS331AP.\r
+* @param None\r
+* @retval None\r
+*/\r
+void Lps331apExitShutdownCmd(void)\r
+{\r
+ uint8_t tmpReg;\r
+ \r
+ /* Read the register content */\r
+ Lps331apByteRead(&tmpReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+ /* Set the power down bit */\r
+ tmpReg |= 0x80;\r
+ \r
+ /* Write register */\r
+ Lps331apByteWrite(&tmpReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+}\r
+\r
+/**\r
+* @brief Read LPS331AP output register, and calculate the raw pressure.\r
+* @param None.\r
+* @retval int32_t: pressure raw value.\r
+*/\r
+int32_t Lps331apReadRawPressure(void)\r
+{\r
+ uint8_t buffer[3];\r
+ uint32_t tempVal=0;\r
+ \r
+ /* Read the register content */\r
+ Lps331apBufferRead(buffer, LPS_PRESS_POUT_XL_ADDR, 3);\r
+ \r
+ /* Build the raw data */\r
+ uint8_t i;\r
+ for(i=0; i<3; i++)\r
+ tempVal |= (((uint32_t)buffer[i]) << (8*i));\r
+ \r
+ /* convert the 2's complement 24 bit to 2's complement 32 bit */\r
+ if(tempVal & 0x00800000)\r
+ tempVal |= 0xFF000000;\r
+ \r
+ /* return the built value */\r
+ return ((int32_t)tempVal);\r
+ \r
+}\r
+\r
+\r
+/**\r
+* @brief Read LPS331AP output register, and calculate the raw temperature.\r
+* @param None.\r
+* @retval int16_t: temperature raw value.\r
+*/\r
+int16_t Lps331apReadRawTemperature(void)\r
+{\r
+ uint8_t buffer[2];\r
+ uint16_t tempVal=0;\r
+ \r
+ /* Read the register content */\r
+ Lps331apBufferRead(buffer, LPS_TEMP_OUT_L_ADDR, 2);\r
+ \r
+ /* Build the raw value */\r
+ tempVal = (((uint16_t)buffer[1]) << 8)+(uint16_t)buffer[0];\r
+ \r
+ /* Return it */\r
+ return ((int16_t)tempVal);\r
+ \r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the LPS331AP IRQ outout pins.\r
+* @param pxLPSIrqInit: pointer to the LPSIrqInit structure that defines the IRQ parameters.\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* LPSIrqInit xLps331apIrqInit;\r
+*\r
+* xLps331apIrqInit.xIrqActiveLow = LPS_DISABLE;\r
+* xLps331apIrqInit.xOutType = LPS_PP;\r
+* xLps331apIrqInit.xInt1List = LPS_DATA_READY;\r
+* xLps331apIrqInit.xInt2List = LPS_P_LOW_HIGH;\r
+* xLps331apIrqInit.fPressThr = 1006.2;\r
+* xLps331apIrqInit.xIrqPressLow=LPS_ENABLE;\r
+* xLps331apIrqInit.xIrqPressHigh=LPS_ENABLE;\r
+*\r
+* ExtiConfiguration(); // set the micro exti before init\r
+* Lps331apIrqInit(&xLps331apIrqInit);\r
+* @endcode\r
+*/\r
+void Lps331apIrqInit(LPSIrqInit* pxLPSIrqInit)\r
+{\r
+ uint8_t tempReg[2];\r
+ \r
+ /* From the structure build the value to write on CTRL3 reg */\r
+ tempReg[0] = (((uint8_t)(pxLPSIrqInit->xIrqActiveLow))<<7) | ((uint8_t)(pxLPSIrqInit->xOutType)) | ((uint8_t)(pxLPSIrqInit->xInt2List)<<3) | ((uint8_t)(pxLPSIrqInit->xInt1List));\r
+\r
+ /* Read the register content */\r
+ Lps331apByteWrite(tempReg, LPS_CTRL_REG3_ADDR);\r
+ \r
+ /* Build the threshold register values */\r
+ tempReg[0]=(uint8_t)(16.0*pxLPSIrqInit->fPressThr);\r
+ tempReg[1]=(uint8_t)(((uint16_t)(16.0*pxLPSIrqInit->fPressThr))>>8); \r
+ \r
+ /* Read the registers content */\r
+ Lps331apBufferWrite(tempReg, LPS_THS_P_LOW_REG_ADDR, 2);\r
+ \r
+ Lps331apByteRead(tempReg, LPS_INT_CFG_REG_ADDR);\r
+ \r
+ /* Enable or disable the high pressure interrupt */\r
+ if(pxLPSIrqInit->xIrqPressHigh)\r
+ tempReg[0] |= 0x01;\r
+ else\r
+ tempReg[0] &= 0xFE;\r
+ \r
+ /* Enable or disable the low pressure interrupt */\r
+ if(pxLPSIrqInit->xIrqPressLow)\r
+ tempReg[0] |= 0x02;\r
+ else\r
+ tempReg[0] &= 0xFD;\r
+ \r
+ tempReg[0]|=0x04;\r
+ \r
+ /* Write the register or disable the high pressure interrupt */\r
+ Lps331apByteWrite(tempReg, LPS_INT_CFG_REG_ADDR);\r
+ \r
+ /* if one has been requested then enable the differential circuit */\r
+ Lps331apByteRead(tempReg, LPS_CTRL_REG1_ADDR);\r
+ if(pxLPSIrqInit->xIrqPressHigh || pxLPSIrqInit->xIrqPressLow)\r
+ { \r
+ tempReg[0] |= 0x08; \r
+ }\r
+ else\r
+ /* else disable it */\r
+ {\r
+ tempReg[0] &= 0xF7; \r
+ }\r
+ Lps331apByteWrite(tempReg, LPS_CTRL_REG1_ADDR);\r
+ \r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Sets the one-shot bit in order to start acquisition when the ONE SHOT mode has been selected by the ODR configuration.\r
+* @param None.\r
+* @retval None.\r
+*/\r
+void Lps331apOneShot(void)\r
+{\r
+ uint8_t tempReg;\r
+ \r
+ /* Read the CTRL2 register */\r
+ Lps331apByteRead(&tempReg, LPS_CTRL_REG2_ADDR);\r
+ \r
+ /* Set the one shot bit */\r
+ tempReg |= 0x01;\r
+ \r
+ /* Write the CTRL2 register */\r
+ Lps331apByteWrite(&tempReg, LPS_CTRL_REG2_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets status for LPS331AP data.\r
+* @param None.\r
+* @retval LPS331DataStatus: Data status in a LPS331DataStatus bitfields structure.\r
+*/\r
+LPS331DataStatus Lps331apGetDataStatus(void)\r
+{\r
+ uint8_t tempReg;\r
+ \r
+ /* Read the status register */\r
+ Lps331apByteRead(&tempReg, LPS_STATUS_REG_ADDR);\r
+ \r
+ /* cast and return it */\r
+ return(*(LPS331DataStatus*)&tempReg);\r
+ \r
+}\r
+\r
+\r
+/** \r
+* @brief Sets the pressure threshold.\r
+* @param fThreshold: Threshold expressed in mbar.\r
+* This parameter is a float value.\r
+* @retval None.\r
+*/\r
+void Lps331apSetThreshold(float fThreshold)\r
+{\r
+ uint8_t tempReg[2];\r
+ \r
+ /* Build the threshold register values */\r
+ tempReg[0]=(uint8_t)(16.0*fThreshold);\r
+ tempReg[1]=(uint8_t)(((uint16_t)(16.0*fThreshold))>>8); \r
+ \r
+ /* write the register content */\r
+ Lps331apBufferWrite(tempReg, LPS_THS_P_LOW_REG_ADDR, 2);\r
+ \r
+}\r
+\r
+\r
+/** \r
+* @brief Gets the pressure threshold.\r
+* @param None.\r
+* @retval float: threshold value expressed in mbar.\r
+*/\r
+float Lps331apGetThreshold(void)\r
+{\r
+ uint8_t tempReg[2];\r
+ \r
+ /* read the register content */\r
+ Lps331apBufferRead(tempReg, LPS_THS_P_LOW_REG_ADDR, 2);\r
+ \r
+ /* return the float value */\r
+ return ((float)((((uint16_t)tempReg[1])<<8) + tempReg[0])/16);\r
+ \r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+/**\r
+ * @file LSM303DLHC.h\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief Header for LSM303DLHC.c file\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+\r
+/* Define to prevent recursive inclusion -------------------------------------*/\r
+#ifndef __LSM303DLHC_H\r
+#define __LSM303DLHC_H\r
+\r
+/* Includes ------------------------------------------------------------------*/\r
+#include <stdint.h>\r
+#include "HAL_LSM303DLHC.h"\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+ \r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+ \r
+/**\r
+ * @addtogroup LSM303DLHC\r
+ * @brief This module contains all the functions to configure the LSM303DLHC accelerometer+magnetometer.\r
+ * @details\r
+ * Since this code is platform independent an implementation of the I2C driver must\r
+ * be provided by the user according to the used platform.\r
+ * Every function makes use of the <i>Lsm303dlhcAccI2CBufferRead</i> and/or <i>Lsm303dlhcAccI2CBufferWrite</i>\r
+ * for the accelerometer and <i>Lsm303dlhcMagI2CBufferRead</i> and/or <i>Lsm303dlhcMagI2CBufferWrite</i> for\r
+ * magnetometer as low level functions to write bytes through the used digital interface.\r
+ * In order to link and use this code the user should define and export these functions in a header\r
+ * file called "HAL_LSM303DLHC.h" (included by this module).\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @addtogroup Accelerometer\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup Accelerometer_Exported_Types Accelerometer Exported Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Accelerometer/Magnetometer Functional state. Used to enable or disable a specific option.\r
+ */\r
+typedef enum\r
+{\r
+ LSM_DISABLE = 0,\r
+ LSM_ENABLE = !LSM_DISABLE\r
+}LSMFunctionalState;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer/Magnetometer Flag status. Used to set/reset the sensor flags.\r
+ */ \r
+typedef enum\r
+{\r
+ LSM_RESET = 0,\r
+ LSM_SET = !LSM_RESET\r
+}LSMFlagStatus;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Output Data Rate\r
+ */\r
+typedef enum\r
+{\r
+ LSM_ODR_1_HZ = 0x10, /*!< Output Data Rate = 1 Hz */\r
+ LSM_ODR_10_HZ = 0x20, /*!< Output Data Rate = 10 Hz */\r
+ LSM_ODR_25_HZ = 0x30, /*!< Output Data Rate = 25 Hz */\r
+ LSM_ODR_50_HZ = 0x40, /*!< Output Data Rate = 50 Hz */\r
+ LSM_ODR_100_HZ = 0x50, /*!< Output Data Rate = 100 Hz */\r
+ LSM_ODR_200_HZ = 0x60, /*!< Output Data Rate = 200 Hz */\r
+ LSM_ODR_400_HZ = 0x70, /*!< Output Data Rate = 400 Hz */\r
+ LSM_ODR_1620_HZ = 0x80, /*!< Output Data Rate = 1620 Hz only in Low Power Mode */\r
+ LSM_ODR_1344_HZ = 0x90 /*!< Output Data Rate = 1344 Hz in Normal mode and 5376 Hz in Low Power Mode */\r
+}AccOutputDataRate;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Power Mode\r
+ */\r
+typedef enum\r
+{\r
+ LSM_NORMAL_MODE = 0x00, /*!< Normal mode enabled */\r
+ LSM_LOW_POWER_MODE = 0x08 /*!< Low Power mode enabled */\r
+}AccPowerMode;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Axes\r
+ */\r
+typedef enum\r
+{\r
+ LSM_X_AXIS_DIS = 0x00, /*!< X Axis disabled */\r
+ LSM_X_AXIS_EN = 0x01, /*!< X Axis enabled */\r
+ LSM_Y_AXIS_DIS = 0x00, /*!< Y Axis disabled */\r
+ LSM_Y_AXIS_EN = 0x02, /*!< Y Axis enabled */\r
+ LSM_Z_AXIS_DIS = 0x00, /*!< Z Axis disabled */\r
+ LSM_Z_AXIS_EN = 0x04, /*!< Z Axis enabled */\r
+ LSM_ALL_AXES_DIS = 0x00, /*!< All axes disabled */\r
+ LSM_ALL_AXES_EN = 0x07 /*!< All axes enabled */\r
+}AccAxesEnabling;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Full scale selection\r
+ */\r
+typedef enum\r
+{\r
+ LSM_FS_2G = 0x00, /*!< ±2 g */\r
+ LSM_FS_4G = 0x10, /*!< ±4 g */\r
+ LSM_FS_8G = 0x20, /*!< ±8 g */\r
+ LSM_FS_16G = 0x30 /*!< ±16 g */\r
+}AccFullScale;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Block Data Update selection\r
+ */\r
+typedef enum\r
+{\r
+ LSM_CONTINUOS_UPDATE = 0x00, /*!< Continuos Update */\r
+ LSM_BLOCK_UPDATE = 0x80 /*!< Single Update: output registers not updated until MSB and LSB reading */\r
+}AccBlockDataUpdate;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Endianness selection\r
+ */\r
+typedef enum\r
+{\r
+ LSM_LITTLE_ENDIAN = 0x00, /*!< Little Endian: data LSB @ lower address */\r
+ LSM_BIG_ENDIAN = 0x40 /*!< Big Endian: data MSB @ lower address */\r
+}AccEndianness;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer High Pass Mode Filter Selection\r
+ */\r
+typedef enum\r
+{\r
+ LSM_HPFM_NORMAL = 0x00, /*!< Normal Mode */\r
+ LSM_HPFM_REFERENCE = 0x40, /*!< Reference Signal for filtering */\r
+ LSM_HPFM_AOI = 0xC0 /*!< Autoreset On Interrupt event */\r
+}AccHPFMode;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer High Pass Filter Cut-Off\r
+ */\r
+typedef enum\r
+{\r
+ LSM_HPCF_8 = 0x00, /*!< ft= ODR[hz]/(6*8). For more details see Accelerometer Control Register 2 description */\r
+ LSM_HPCF_16 = 0x10, /*!< ft= ODR[hz]/(6*16). For more details see Accelerometer Control Register 2 description */\r
+ LSM_HPCF_32 = 0x20, /*!< ft= ODR[hz]/(6*32). For more details see Accelerometer Control Register 2 description */\r
+ LSM_HPCF_64 = 0x30 /*!< ft= ODR[hz]/(6*64). For more details see Accelerometer Control Register 2 description */\r
+}AccHPFCutOff;\r
+\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Irq on line 1 list\r
+ */\r
+typedef enum\r
+{\r
+ LSM_I1_OVERRUN = 0x02,\r
+ LSM_I1_WTM = 0x04,\r
+ LSM_I1_DRDY2 = 0x08,\r
+ LSM_I1_DRDY1 = 0x10,\r
+ LSM_I1_AOI2 = 0x20,\r
+ LSM_I1_AOI1 = 0x40,\r
+ LSM_I1_CLICK = 0x80\r
+}LSMAIrq1List;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Irq on line 2 list\r
+ */\r
+typedef enum\r
+{\r
+ LSM_I2_CLICK = 0x80,\r
+ LSM_I2_INT1 = 0x40,\r
+ LSM_I2_INT2 = 0x20,\r
+ LSM_I2_BOOT = 0x10,\r
+ LSM_I2_P2ACT = 0x08,\r
+ LSM_I2_H_LACTIVE = 0x02,\r
+}LSMAIrq2List;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer data status. It notifies if data on axis are available or overrided\r
+ */\r
+typedef struct\r
+{\r
+ LSMFlagStatus X_Da:1;\r
+ LSMFlagStatus Y_Da:1;\r
+ LSMFlagStatus Z_Da:1;\r
+ LSMFlagStatus ZYX_Da:1;\r
+ LSMFlagStatus X_Or:1;\r
+ LSMFlagStatus Y_Or:1;\r
+ LSMFlagStatus Z_Or:1;\r
+ LSMFlagStatus ZYX_Or:1;\r
+}LSMADataStatus;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ AccPowerMode xPowerMode; /*!< Power mode selection */\r
+ AccOutputDataRate xOutputDataRate; /*!< Output Data Rate */\r
+ AccAxesEnabling xEnabledAxes; /*!< Axes to be enabled */\r
+ AccFullScale xFullScale; /*!< Full Scale */\r
+ AccBlockDataUpdate xDataUpdate; /*!< Data Update mode : Continuos update or data don`t change until MSB and LSB nex reading */\r
+ AccEndianness xEndianness; /*!< Endianness */\r
+ LSMFunctionalState xHighResolution; /*!< High Resolution enabling/disabling */\r
+}LSMAccInit;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Filter Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ LSMFunctionalState xHPF; /*!< HPF enabling/disabling */\r
+ AccHPFMode xHPF_Mode; /*!< HPF MODE: Normal mode, Reference signal or Auntoreset on interrupt event for filtering */\r
+ uint8_t cHPFReference; /*!< Reference value for filtering. Used only in case the mode is "Reference Signal" */\r
+ AccHPFCutOff xHPFCutOff; /*!< HPF_frequency ft=ODR/6*HPc HPc=8,16,32,64 */\r
+ LSMFunctionalState xHPFClick; /*!< HPF_enabling/disabling on CLICK function */\r
+ LSMFunctionalState xHPFAOI2; /*!< HPF_enabling/disabling for AOI function on interrupt 2 */\r
+ LSMFunctionalState xHPFAOI1; /*!< HPF_enabling/disabling for AOI function on interrupt 1 */\r
+}LSMAccFilterInit;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer FIFO Working Mode\r
+ */\r
+typedef enum\r
+{\r
+ LSM_BYPASS_MODE = 0x00, /*!< Bypass mode: don't use the FIFO */\r
+ LSM_FIFO_MODE = 0x40, /*!< FIFO mode */\r
+ LSM_STREAM_MODE = 0x80, /*!< Stream mode */\r
+ LSM_TRIGGER_MODE = 0xC0 /*!< Trigger mode */\r
+}LSMAFifoMode;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Sensor IRQ line\r
+ */\r
+typedef enum\r
+{\r
+ LSM_INT1_LINE=0x01, /*!< Sensor IRQ line 1 */\r
+ LSM_INT2_LINE /*!< Sensor IRQ line 2 */\r
+}LSMAIrqLine;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer FIFO Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ LSMAFifoMode xFifoMode; /*!< FIFO operating mode */\r
+ LSMAIrqLine xTriggerSel; /*!< External interrupt line linked to the FIFO trigger event */\r
+ uint8_t cWtm; /*!< WaterMark level for FIFO in range [0, 31] */\r
+}LSMAccFifoInit;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer FIFO Status bitfield structure\r
+ */\r
+typedef struct\r
+{\r
+ uint8_t FIFO_FSS:5; /*!< FIFO unread samples */\r
+ LSMFlagStatus FIFO_EMPTY_FLAG:1; /*!< FIFO Empty flag */\r
+ LSMFlagStatus FIFO_OVRN_FLAG:1; /*!< FIFO Overrun flag */\r
+ LSMFlagStatus FIFO_WTM_FLAG:1; /*!< FIFO Watermark flag */\r
+\r
+}LSMAccFifoStatus;\r
+\r
+/**\r
+ * @brief Accelerometer Events on axis bitfield structure\r
+ */\r
+typedef struct\r
+{\r
+ LSMFlagStatus X_LOW:1; /*!< X axis low event */\r
+ LSMFlagStatus X_HIGH:1; /*!< X axis high event */\r
+ LSMFlagStatus Y_LOW:1; /*!< Y axis low event */\r
+ LSMFlagStatus Y_HIGH:1; /*!< Y axis high event */\r
+ LSMFlagStatus Z_LOW:1; /*!< Z axis low event */\r
+ LSMFlagStatus Z_HIGH:1; /*!< Z axis high event */\r
+ uint8_t :2; /*!< 2 bits padding */\r
+}LSMAccAxisEvents;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer External events on axis combination\r
+ */\r
+typedef enum\r
+{\r
+ LSM_OR_COMBINATION = 0x00, /*!< OR combination of enabled IRQs */\r
+ LSM_AND_COMBINATION = 0x80, /*!< AND combination of enabled IRQs */\r
+ LSM_SIXD_MOV_RECOGNITION = 0x40, /*!< 6D movement recognition */\r
+ LSM_SIXD_POS_RECOGNITION = 0xC0 /*!< 6D position recognition */\r
+\r
+}LSMAccIrqOnaxisCombination;\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Click initialization structure\r
+ */\r
+typedef struct\r
+{\r
+ uint16_t nClickThreshold; /*!< Click acceleration threshold expressed in mg */\r
+ LSMFunctionalState xNegativeDetection; /*!< Click negative detection */\r
+ uint8_t cClickTimeLimit; /*!< Click time limit expressed in ms */\r
+ uint8_t cDClickTimeLatency; /*!< Click time latency expressed in ms (only for double click) */\r
+ uint8_t cDClickTimeWindow; /*!< Click time window expressed in ms (only for double click) */\r
+}LSMAccClickInit;\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup Accelerometer_Exported_Constants Accelerometer Exported Constants\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Sensitivity_Defines Accelerometer Sensitivity Defines\r
+ * @{\r
+ */\r
+\r
+#define LSM_Acc_Sensitivity_2g 1.0 /*!< accelerometer sensitivity with 2 g full scale [LSB/mg] */\r
+#define LSM_Acc_Sensitivity_4g 0.5 /*!< accelerometer sensitivity with 4 g full scale [LSB/mg] */\r
+#define LSM_Acc_Sensitivity_8g 0.25 /*!< accelerometer sensitivity with 8 g full scale [LSB/mg] */\r
+#define LSM_Acc_Sensitivity_16g 0.0834 /*!< accelerometer sensitivity with 12 g full scale [LSB/mg] */\r
+\r
+/**\r
+ * @}\r
+ */ /* end of group Accelerometer_Sensitivity_Defines */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup Accelerometer_Exported_Macros Accelerometer Exported Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup Accelerometer_I2C_Communication Accelerometer I2C Communication\r
+ * @{\r
+ */\r
+\r
+#define Lsm303dlhcAccI2CBufferRead(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferRead(LSM_A_I2C_ADDRESS,pVal,cAddress,nBytes)\r
+#define Lsm303dlhcAccI2CBufferWrite(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferWrite(LSM_A_I2C_ADDRESS,pVal,cAddress,nBytes)\r
+\r
+#define Lsm303dlhcAccI2CByteRead(pVal,cAddress) Lsm303dlhcAccI2CBufferRead(pVal,cAddress,1)\r
+#define Lsm303dlhcAccI2CByteWrite(pVal,cAddress) Lsm303dlhcAccI2CBufferWrite(pVal,cAddress,1)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/** @defgroup Accelerometer_Register_Mapping Accelerometer Register Mapping\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Accelerometer I2C Slave Address\r
+ */\r
+#define LSM_A_I2C_ADDRESS 0x33\r
+\r
+/**\r
+ * @brief Accelerometer Control Register 1\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x07\r
+ * 7:4 ODR3-ODR0: Data Rate selection\r
+ * ODR3 | ODR2 | ODR1 | ODR0 | Power Mode Sel & Out Data Rate[Hz]\r
+ * --------------------------------------------------------------\r
+ * 0 | 0 | 0 | 0 | Power Down\r
+ * 0 | 0 | 0 | 1 | Normal / Low Power (1 Hz)\r
+ * 0 | 0 | 1 | 0 | Normal / Low Power (10 Hz)\r
+ * 0 | 0 | 1 | 1 | Normal / Low Power (25 Hz)\r
+ * 0 | 1 | 0 | 0 | Normal / Low Power (50 Hz)\r
+ * 0 | 1 | 0 | 1 | Normal / Low Power (100 Hz)\r
+ * 0 | 1 | 1 | 0 | Normal / Low Power (200 Hz)\r
+ * 0 | 1 | 1 | 1 | Normal / Low Power (400 Hz)\r
+ * 1 | 0 | 0 | 0 | Low Power (1620 Hz)\r
+ * 1 | 0 | 0 | 1 | Normal (1344 Hz) / Low Power (5376 Hz)\r
+ * 3 LPen: Low Power Mode Enable. 0 - Normal Mode 1 - Low Power Mode\r
+ * 2 Zen: Z axis enable. 0 - Z axis disabled 1- Z axis enabled\r
+ * 1 Yen: Y axis enable. 0 - Y axis disabled 1- Y axis enabled\r
+ * 0 Xen: X axis enable. 0 - X axis disabled 1- X axis enabled\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL1_REG_ADDR 0x20\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Control Register 2\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:6 HPM1-HPM0: High pass filter mode selection:\r
+ * HPM1 | HPM0 | High pass filter mode\r
+ * -----------------------------------------\r
+ * 0 | 0 | Normal mode (reset reading HP_RESET_FILTER)\r
+ * 0 | 1 | Reference signal for filtering\r
+ * 1 | 0 | Normal mode (reset reading HP_RESET_FILTER)\r
+ * 1 | 1 | Autoreset on interrupt event\r
+ * 5:4 HPCF1-HPCF0: High pass filter cut-off frequency (ft) configuration\r
+ * ft= ODR[hz]/6*HPc\r
+ * HPCF1 | HPCF0 | HPc | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz] | ft[Hz]\r
+ * | | | ODR 1 Hz | ODR 10 Hz | ODR 25 Hz | ODR 50 Hz | ODR 100 Hz | ODR 200 HZ | ODR 400 Hz | ODR 1344 HZ\r
+ * ------------------------------------------------------------------------------------------------------------------------------------\r
+ * 0 | 0 | 8 | 0.02 | 0.2 | 0.52 | 1.04 | 2.08 | 4.16 | 8.33 | 28\r
+ * 0 | 1 | 16 | 0.01 | 0.1 | 0.26 | 0.52 | 1.04 | 2.08 | 4.16 | 14\r
+ * 1 | 0 | 32 | 0.005 | 0.05 | 0.13 | 0.26 | 0.52 | 1.04 | 2.08 | 7\r
+ * 1 | 1 | 64 | 0.0026 | 0.026 | 0.065 | 0.13 | 0.26 | 0.52 | 1.04 | 3.5\r
+ * 3 FDS: Filtered data selection. 0 - internal filter bypassed; 1 - data from internal filter sent to output register and FIFO\r
+ * 2 HPCLICK: High pass filter enabled for CLICK function. 0 - filter bypassed; 1 - filter enabled\r
+ * 1 HPIS2: High pass filter enabled for interrupt 2 source. 0 - filter bypassed; 1 - filter enabled\r
+ * 0 HPIS1: High pass filter enabled for interrupt 1 source. 0 - filter bypassed; 1 - filter enabled\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL2_REG_ADDR 0x21\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Control Register 3 Interrupt Control Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 I1_CLICK: Click interrupt on INT1. 0 - disable; 1 - enable\r
+ * 6 I1_AOI1: AOI1 interrupt on INT1. 0 - disable; 1 - enable\r
+ * 5 I1_AOI2: AOI2 interrupt on INT1. 0 - disable; 1 - enable\r
+ * 4 I1_DRDY1: DRDY1 interrupt on INT1. 0 - disable; 1 - enable\r
+ * 3 I1_DRDY2: DRDY2 interrupt on INT1. 0 - disable; 1 - enable\r
+ * 2 I1_WTM: FIFO watermark interrupt on INT1. 0 - disable; 1 - enable\r
+ * 1 I1_OVERRUN: FIFO overrun interrup on INT1. 0 - disable; 1 - enable\r
+ * 0 -: Not used. It shall be zero\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL3_REG_ADDR 0x22\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Control Register 4\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 BDU: Block data update. 0 -continuos update; 1- output registers not updated between MSB and LSB reading\r
+ * 6 BLE: Big/little endian data selection. 0 - data LSB @ lower address; 1 - data MSB @ lower address\r
+ * 5:4 FS1 - FS0: Full-scale selection\r
+ * FS1 | FS0 | Full Scale\r
+ * -----------------------------------------\r
+ * 0 | 0 | ±2 g\r
+ * 0 | 1 | ±4 g\r
+ * 1 | 0 | ±8 g\r
+ * 1 | 1 | ±16 g\r
+ * 3 HR: High resolution output mode. 0 - disable; 1- enable\r
+ * 2:1 -: Not used. They shall be zero\r
+ * 0 SIM: SPI serial interface mode selection. 0 - 4 wire interface; 1 - 3 wire interface\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL4_REG_ADDR 0x23\r
+\r
+\r
+/**\r
+ * @brief Accelometer Control Register 5\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 BOOT: Reboot memory content. 0 - Normal mode; 1 - Reboot memory content\r
+ * 6 FIFO_EN: FIFO enable. 0 - FIFO disabled; 1 - FIFO enabled\r
+ * 5:4 -: Not used. They shall be zero\r
+ * 3 LIR_INT1: Latch interrupt request on INT1_SRC register. 0 - Interrupt request not latched; 1 - Interrupt request latched\r
+ * 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\r
+ * 1 LIR_INT2: Latch interrupt request on INT2_SRC register. 0 - Interrupt request not latched; 1 - Interrupt request latched\r
+ * 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\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL5_REG_ADDR 0x24\r
+\r
+\r
+/**\r
+ * @brief Accelometer Control Register 6\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 I2_CLICKen: CLICK interrupt on PAD2. 0 - disable; 1 - enable\r
+ * 6 I2_INT1: Interrupt 1 on PAD2. 0 - disable; 1 - enable\r
+ * 5 I2_INT2: Interrupt 2 on PAD2. 0 - disable; 1 - enable\r
+ * 4 BOOT_I1: Reboot memory content on PAD2. 0 - disable; 1 - enable\r
+ * 3 P2_ACT: Active function status on PAD2. 0 - disable; 1 - enable\r
+ * 2 -: Not used. It shall be zero\r
+ * 1 H_LACTIVE: Interrupt active high, low. 0 - active high; 1 - active low\r
+ * 0 -: Not used. It shall be zero.\r
+ * \endcode\r
+ */\r
+#define LSM_A_CTRL6_REG_ADDR 0x25\r
+\r
+\r
+/**\r
+ * @brief Accelrometer HP Reference register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 Ref7 - Ref0: Reference value for high-pass filter.\r
+ * This register sets the acceleration value taken as a reference for the high-pass filter output\r
+ * When filter is turned on (at least one of FDS, HPen2, or HPen1 bit is equal to \911\92) and HPM\r
+ * bits are set to \9301\94, filter out is generated taking this value as a reference.\r
+ * \endcode\r
+ */\r
+#define LSM_A_REFERENCE_REG_ADDR 0x26\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Status Register\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 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\r
+ * 6 ZOR: Z axis data overrun. 0 - No overrun has occurred; 1 - A new data for the Z-axis has overwritten the previous one\r
+ * 5 YOR: Y axis data overrun. 0 - No overrun has occurred; 1 - A new data for the Y-axis has overwritten the previous one\r
+ * 4 XOR: X axis data overrun. 0 - No overrun has occurred; 1 - A new data for the X-axis has overwritten the previous one\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * \endcode\r
+ */\r
+#define LSM_A_STATUS_REG_ADDR 0x27\r
+\r
+\r
+/**\r
+ * @brief Accelerometer X axis Output Data Low Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 XOUT7-XOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_X_L_REG_ADDR 0x28\r
+\r
+\r
+/**\r
+ * @brief Acceleration X-axis Output Data High Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 XOUT15-XOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_X_H_REG_ADDR 0x29\r
+\r
+\r
+/**\r
+ * @brief Acceleration Y-axis Output Data Low Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 YOUT7-YOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_Y_L_REG_ADDR 0x2A\r
+\r
+\r
+/**\r
+ * @brief Acceleration Y-axis Output Data High Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 YOUT15-YOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_Y_H_REG_ADDR 0x2B\r
+\r
+\r
+/**\r
+ * @brief Acceleration Z-axis Output Data Low Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 ZOUT7-ZOUT0: ACC Data LSB (if in Little Endian Mode --> BLE bit in CTRL_REG4 is 0)\r
+ * ACC Data MSB (if in Big Endian Mode --> BLE bit in CTRL_REG4 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_Z_L_REG_ADDR 0x2C\r
+\r
+\r
+/**\r
+ * @brief Acceleration Z-axis Output Data High Register\r
+ * \code\r
+ * Read\r
+ * Default value: ( The value is expressed as 16bit two\92s complement). Because the resolution is 12 bit,\r
+ * the entire acceleration data (expressed as signed 16-bit) shall be divided by 16.\r
+ * 7:0 ZOUT15-ZOUT8: ACC Data MSB (if in Little Endian Mode --> BLE bit in CTRL_REG1 is 0)\r
+ * ACC Data LSB (if in Big Endian Mode --> BLE bit in CTRL_REG1 is 1)\r
+ * \endcode\r
+ */\r
+#define LSM_A_OUT_Z_H_REG_ADDR 0x2D\r
+\r
+\r
+/**\r
+ * @brief FIFO Control Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:6 FM1 - FM0: FIFO Mode selection\r
+ * FM1 | FM0 | FIFO Mode Configuration\r
+ * -------------------------------------\r
+ * 0 | 0 | Bypass Mode\r
+ * 0 | 1 | FIFO Mode\r
+ * 1 | 0 | Stream Mode\r
+ * 1 | 1 | Trigger Mode\r
+ * 5 TR: Trigger selection. 0 - trigger event linked to trigger signal on INT1; 1 - trigger event linked to trigger signal on INT2\r
+ * 4:0 FTH4 - FTH0: ?????\r
+ * \endcode\r
+ */\r
+#define LSM_A_FIFO_CTRL_REG_ADDR 0x2E\r
+\r
+\r
+/**\r
+ * @brief FIFO Status Register\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7 WTM:\r
+ * 6 OVRN_FIFO:\r
+ * 5 EMPTY:\r
+ * 4:0 FSS4 - FSSO:\r
+ * \endcode\r
+ */\r
+#define LSM_A_FIFO_STATUS_REG_ADDR 0x2F\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Configuration Register for Interrupt 1 source.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 AOI: AND/OR combination of Interrupt events. See table below\r
+ * 6 6D: 6 direction detection function enable. See table below\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * AOI | 6D | Interrupt mode\r
+ * --------------------------------------------------------\r
+ * 0 | 0 | OR combination of interrupt events\r
+ * 0 | 1 | 6 direction movement recognition\r
+ * 1 | 0 | AND combination of interrupt events\r
+ * 1 | 1 | 6 direction position recognition\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT1_CFG_REG_ADDR 0x30\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Interrupt 1 source register.\r
+ * Reading at this address clears INT1_SRC IA bit (and the interrupt signal on INT 1 pin) and\r
+ * allows the refreshment of data in the INT1_SRC register if the latched option was chosen.\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 IA : Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated\r
+ * 5 ZH: Z high. 0: no interrupt, 1: Z High event has occurred\r
+ * 4 ZL: Z low. 0: no interrupt; 1: Z Low event has occurred\r
+ * 3 YH: Y high. 0: no interrupt, 1: Y High event has occurred\r
+ * 2 YL: Y low. 0: no interrupt; 1: Y Low event has occurred\r
+ * 1 XH: X high. 0: no interrupt, 1: X High event has occurred\r
+ * 0 XL: X low. 0: no interrupt; 1: X Low event has occurred\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT1_SRC_REG_ADDR 0x31\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Interrupt 1 Threshold Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 THS6-THS0: Interrupt 1 threshold.\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT1_THS_REG_ADDR 0x32\r
+\r
+\r
+/**\r
+ * @brief Acceleroemter INT1_DURATION Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 D6-D0: Duration value. (Duration steps and maximum values depend on the ODR chosen)\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT1_DURATION_REG_ADDR 0x33\r
+\r
+\r
+/**\r
+ * @brief INT2_CFG Register Configuration register for Interrupt 2 source.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 AOI: AND/OR combination of Interrupt events. See table below\r
+ * 6 6D: 6 direction detection function enable. See table below\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * AOI | 6D | Interrupt mode\r
+ * --------------------------------------------------------\r
+ * 0 | 0 | OR combination of interrupt events\r
+ * 0 | 1 | 6 direction movement recognition\r
+ * 1 | 0 | AND combination of interrupt events\r
+ * 1 | 1 | 6 direction position recognition\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT2_CFG_REG_ADDR 0x34\r
+\r
+\r
+/**\r
+ * @brief INT2_SCR Register Interrupt 2 source register.\r
+ * Reading at this address clears INT2_SRC IA bit (and the interrupt signal on INT 2 pin) and\r
+ * allows the refreshment of data in the INT2_SRC register if the latched option was chosen.\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 IA : Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated\r
+ * 5 ZH: Z high. 0: no interrupt, 1: Z High event has occurred\r
+ * 4 ZL: Z low. 0: no interrupt; 1: Z Low event has occurred\r
+ * 3 YH: Y high. 0: no interrupt, 1: Y High event has occurred\r
+ * 2 YL: Y low. 0: no interrupt; 1: Y Low event has occurred\r
+ * 1 YH: X high. 0: no interrupt, 1: X High event has occurred\r
+ * 0 YL: X low. 0: no interrupt; 1: X Low event has occurred\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT2_SRC_REG_ADDR 0x35\r
+\r
+\r
+/**\r
+ * @brief Accelerometer Interrupt 2 Threshold Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 THS6-THS0: Interrupt 2 threshold.\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT2_THS_REG_ADDR 0x36\r
+\r
+\r
+/**\r
+ * @brief Acceromter INT2_DURATION Register\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 D6-D0: Duration value. (Duration steps and maximum values depend on the ODR chosen)\r
+ * \endcode\r
+ */\r
+#define LSM_A_INT2_DURATION_REG_ADDR 0x37\r
+\r
+\r
+/**\r
+ * @brief CLICK Configuration register.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:6 -: It shall be zero for correct working of the device\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * 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\r
+ * \endcode\r
+*/\r
+#define LSM_A_CLICK_CONF_REG_ADDR 0x38\r
+\r
+\r
+/**\r
+ * @brief CLICK source register.\r
+ * \code\r
+ * Read\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 IA: Interrupt active. 0: no interrupt has been generated; 1: one or more interrupts have been generated\r
+ * 5 DCLICK: Double CLICK-CLICK enable. 0: Double CLICK-CLICK detection disable; 1: Double CLICK-CLICK detection enable\r
+ * 4 SCLICK: Single CLICK-CLICK enable. 0: Single CLICK-CLICK detection disable; 1: Single CLICK-CLICK detection enable\r
+ * 3 Sign: CLICK-CLICK Sign. 0: positive detection; 1: negative detection\r
+ * 2 Z: Z CLICK-CLICK detection. 0: no interrupt; 1: Z high event has occurred\r
+ * 1 Y: Y CLICK-CLICK detection. 0: no interrupt; 1: Y high event has occurred\r
+ * 0 X: X CLICK-CLICK detection. 0: no interrupt; 1: X high event has occurred\r
+ * \endcode\r
+*/\r
+#define LSM_A_CLICK_SRC_REG_ADDR 0x39\r
+\r
+\r
+/**\r
+ * @brief CLICK Threshold Register. 1LSB = full-scale/128. THS6 through THS0 define the threshold which is used by the system to\r
+ * start the click detection procedure. The threshold value is expressed over 7 bits as an unsigned number.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7 0: It shall be zero for correct working of the device\r
+ * 6 THS6-THS0: CLICK-CLICK threshold.\r
+ * \endcode\r
+ */\r
+#define LSM_A_CLICK_THS_REG_ADDR 0x3A\r
+\r
+\r
+/**\r
+ * @brief CLICK Time Limit Register. 1LSB = 1/ODR. TLI7 through TLI0 define the maximum time interval that can elapse\r
+ * between the start of the click detection procedure (the accelration on the selected channel exceeds the programmed\r
+ * threshold) and when the acceleration goes back below the threshold\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 TLI7-TLI0: CLICK-CLICK time limit.\r
+ * \endcode\r
+ */\r
+#define LSM_A_CLICK_TIME_LIMIT_REG_ADDR 0x3B\r
+\r
+\r
+/**\r
+ * @brief CLICK Time Latency Register. 1LSB = 1/ODR. TLA7 through TLA0 define the time interval that starts after the first\r
+ * click detection where the click detection procedure is disabled, in cases where the device is configured for double click\r
+ * detection.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 TLA7-TLA0: CLICK-CLICK time latency.\r
+ * \endcode\r
+ */\r
+#define LSM_A_CLICK_TIME_LATENCY_REG_ADDR 0x3C\r
+\r
+\r
+/**\r
+ * @brief CLICK Time Window Register. 1LSB = 1/ODR. TW7 through TW0 define the maximum interval of time\r
+ * that can elapse after the end of latency interval in which the click detection procedure can start,\r
+ * in cases where the device is configured for double click detection.\r
+ * \code\r
+ * Read/write\r
+ * Default value: 0x00\r
+ * 7:0 TW7-TW0: CLICK-CLICK time window.\r
+ * \endcode\r
+ */\r
+#define LSM_A_CLICK_TIME_WINDOW_REG_ADDR 0x3D\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+\r
+/** @defgroup Accelerometer_Exported_Functions Accelerometer Exported Functions\r
+ * @{\r
+ */\r
+void Lsm303dlhcAccConfig(LSMAccInit* pxLSMAccInitStruct);\r
+void Lsm303dlhcAccGetInfo(LSMAccInit* pxLSMAccInitStruct);\r
+void Lsm303dlhcAccFilterConfig(LSMAccFilterInit* pxLSMAccFilterInitStruct);\r
+void Lsm303dlhcAccFilterGetInfo(LSMAccFilterInit* pxLSMAccFilterInitStruct);\r
+void Lsm303dlhcAccLowPowerMode(LSMFunctionalState xFunctionalState);\r
+void Lsm303dlhcAccSetFullScale(AccFullScale xFullScale);\r
+AccFullScale Lsm303dlhcAccGetEnumFullScale(void);\r
+uint8_t Lsm303dlhcAccGetFullScale(void);\r
+void Lsm303dlhcAccGetSensitivity(float *pfSensitivityXYZ);\r
+void Lsm303dlhcAccSetDataRate(AccOutputDataRate xDataRate);\r
+AccOutputDataRate Lsm303dlhcAccGetEnumDataRate(void);\r
+uint16_t Lsm303dlhcAccGetDataRate(void);\r
+void Lsm303dlhcAccRebootCmd(void);\r
+void Lsm303dlhcAccReadOutReg(uint8_t* pcReg);\r
+void Lsm303dlhcAccReadRawData(int16_t* pnRawData);\r
+void Lsm303dlhcAccReadAcc(float* pfData);\r
+void Lsm303dlhcAccReadAccFifo(int16_t* pnData, uint8_t cDataToRead);\r
+LSMADataStatus Lsm303dlhcAccGetDataStatus(void);\r
+void Lsm303dlhcAccIrq1Config(LSMAIrq1List xLSMAIrq1Config, LSMFunctionalState xNewState);\r
+void Lsm303dlhcAccIrq2Config(LSMAIrq2List xLSMAIrq2Config, LSMFunctionalState xNewState);\r
+void Lsm303dlhcAccFifo(LSMFunctionalState xNewState);\r
+void Lsm303dlhcAccFifoInit(LSMAccFifoInit* pxLSMAccFifoInit);\r
+LSMAccFifoStatus Lsm303dlhcAccFifoGetStatus(void);\r
+void Lsm303dlhcAccSetAxisIrqs(LSMAccIrqOnaxisCombination xIrqCombinations, LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine, LSMFunctionalState xLatched);\r
+LSMFunctionalState Lsm303dlhcAccGetAxisIrqs(LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine);\r
+void Lsm303dlhcAccSetThreshold(int16_t nData, LSMAIrqLine xIRQLine);\r
+void Lsm303dlhcAccSetIrqDuration(uint8_t cDuration, LSMAIrqLine xIRQLine);\r
+void Lsm303dlhcAccClickInit(LSMAccClickInit* pxClickInit);\r
+\r
+/**\r
+ * @}\r
+ */ \r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @addtogroup Magnetometer\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup Magnetometer_Exported_Types Magnetometer Exported Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Magnetometer Output Data Rate\r
+ */\r
+typedef enum\r
+{\r
+ LSM_ODR_0_75_HZ = 0x00, /*!< Output Data Rate = 0.75 Hz */\r
+ LSM_ODR_1_5_HZ = 0x04, /*!< Output Data Rate = 1.5 Hz */\r
+ LSM_ODR_3_0_HZ = 0x08, /*!< Output Data Rate = 3 Hz */\r
+ LSM_ODR_7_5_HZ = 0x0C, /*!< Output Data Rate = 7.5 Hz */\r
+ LSM_ODR_15_HZ = 0x10, /*!< Output Data Rate = 15 Hz */\r
+ LSM_ODR_30_HZ = 0x14, /*!< Output Data Rate = 30 Hz */\r
+ LSM_ODR_75_HZ = 0x18, /*!< Output Data Rate = 75 Hz */\r
+ LSM_ODR_220_HZ = 0x1C /*!< Output Data Rate = 220 Hz */\r
+}MagOutputDataRate;\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Full Scale\r
+ */\r
+typedef enum\r
+{\r
+ LSM_FS_1_3_GA = 0x20, /*!< Full scale = ±1.3 Gauss */\r
+ LSM_FS_1_9_GA = 0x40, /*!< Full scale = ±1.9 Gauss */\r
+ LSM_FS_2_5_GA = 0x60, /*!< Full scale = ±2.5 Gauss */\r
+ LSM_FS_4_0_GA = 0x80, /*!< Full scale = ±4.0 Gauss */\r
+ LSM_FS_4_7_GA = 0xA0, /*!< Full scale = ±4.7 Gauss */\r
+ LSM_FS_5_6_GA = 0xC0, /*!< Full scale = ±5.6 Gauss */\r
+ LSM_FS_8_1_GA = 0xE0 /*!< Full scale = ±8.1 Gauss */\r
+}MagFullScale;\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Working Mode\r
+ */\r
+typedef enum\r
+{\r
+ LSM_CONTINUOS_CONVERSION = 0x00, /*!< Continuous-Conversion Mode */\r
+ LSM_SINGLE_CONVERSION = 0x01, /*!< Single-Conversion Mode */\r
+ LSM_SLEEP = 0x02 /*!< Sleep Mode */\r
+}MagWorkingMode;\r
+\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Init structure definition\r
+ */\r
+typedef struct\r
+{\r
+ MagOutputDataRate xOutputDataRate; /*!< Magnetometer Output data Rate */\r
+ MagFullScale xFullScale; /*!< Full Scale Configuration */\r
+ MagWorkingMode xWorkingMode; /*!< Mode Configuration: Continuos, Single or Sleep Mode */\r
+ LSMFunctionalState xTemperatureSensor; /*!< Temperature sensor enabling/disabling */\r
+}LSMMagInit;\r
+\r
+\r
+/**\r
+ * @brief Magnetometer data status. It notifies if data on axis are available or overrun.\r
+ */\r
+typedef struct\r
+{\r
+ uint8_t xDataReady:1; /*!< DataReady bit flag */\r
+ uint8_t xDataLock:1; /*!< DataLock bit flag */\r
+ uint8_t :6; /*!< RFU */\r
+}LSMMDataStatus;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup Magnetometer_Exported_Constants Magnetometer Exported Constants\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup Magnetometer_Sensitivity Magnetometer Sensitivity \r
+ * @{\r
+ */\r
+\r
+#define LSM_Magn_Sensitivity_XY_1_3Ga 1100 /*!< magnetometer X Y axes sensitivity for 1.3 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_1_9Ga 855 /*!< magnetometer X Y axes sensitivity for 1.9 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_2_5Ga 670 /*!< magnetometer X Y axes sensitivity for 2.5 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_4Ga 450 /*!< magnetometer X Y axes sensitivity for 4 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_4_7Ga 400 /*!< magnetometer X Y axes sensitivity for 4.7 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_5_6Ga 330 /*!< magnetometer X Y axes sensitivity for 5.6 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_XY_8_1Ga 230 /*!< magnetometer X Y axes sensitivity for 8.1 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_1_3Ga 980 /*!< magnetometer Z axis sensitivity for 1.3 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_1_9Ga 760 /*!< magnetometer Z axis sensitivity for 1.9 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_2_5Ga 600 /*!< magnetometer Z axis sensitivity for 2.5 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_4Ga 400 /*!< magnetometer Z axis sensitivity for 4 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_4_7Ga 355 /*!< magnetometer Z axis sensitivity for 4.7 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_5_6Ga 295 /*!< magnetometer Z axis sensitivity for 5.6 Ga full scale [LSB/Ga] */\r
+#define LSM_Magn_Sensitivity_Z_8_1Ga 205 /*!< magnetometer Z axis sensitivity for 8.1 Ga full scale [LSB/Ga] */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Temperature_Sensitivity Temperature Sensitivity\r
+ * @{\r
+ */\r
+#define LSM_Temp_Sensitivity 8 /*!< temperature sensitivity [LSB/deg] */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Exported_Macros Magnetometer Exported Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup Magnetometer_I2C_Communication Magnetometer I2C Communication\r
+ * @{\r
+ */\r
+#define Lsm303dlhcMagI2CBufferRead(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferRead(LSM_M_I2C_ADDRESS,pVal,cAddress,nBytes)\r
+#define Lsm303dlhcMagI2CBufferWrite(pVal,cAddress,nBytes) Lsm303dlhcI2CBufferWrite(LSM_M_I2C_ADDRESS,pVal,cAddress,nBytes)\r
+\r
+#define Lsm303dlhcMagI2CByteRead(pVal,cAddress) Lsm303dlhcMagI2CBufferRead(pVal,cAddress,1)\r
+#define Lsm303dlhcMagI2CByteWrite(pVal,cAddress) Lsm303dlhcMagI2CBufferWrite(pVal,cAddress,1)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+/**\r
+ * @defgroup Magnetometer_Register_Mapping Magnetometer Register Mapping\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Magnetometer I2C Slave Address\r
+ */\r
+#define LSM_M_I2C_ADDRESS 0x3D\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Control Register A\r
+ * \code\r
+ * Read Write\r
+ * Default value: 0x10\r
+ * 7 TEMP_EN: Temperature sensor enabling. 0: temperature sensor disabled; 1: temperature sensor enabled\r
+ * 6:5 0: They shall be zero for correct working of the device\r
+ * 4:2 DO2-DO0: Data Output Rate Bits\r
+ * DO2 | DO1 | DO0 | Minimum Data Output Rate (Hz)\r
+ * ------------------------------------------------------\r
+ * 0 | 0 | 0 | 0.75\r
+ * 0 | 0 | 1 | 1.5\r
+ * 0 | 1 | 0 | 3.0\r
+ * 0 | 1 | 1 | 7.5\r
+ * 1 | 0 | 0 | 15(default)\r
+ * 1 | 0 | 1 | 30\r
+ * 1 | 1 | 0 | 75\r
+ * 1 | 1 | 1 | 220\r
+ * 1:0 0: They shall be zero for correct working of the device\r
+ * \endcode\r
+ */\r
+#define LSM_M_CRA_REG_ADDR 0x00\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Control Register B\r
+ * \code\r
+ * Read/Write\r
+ * Default value: 0x20\r
+ * 7:5 GN2-GN0: Gain Configuration Bits\r
+ * GN2 | GN1 | GN0 | Mag Input | Gain X, Y | Gain Z | Output Range\r
+ * | | | Range[Ga] | [LSB/Gauss] | [LSB/Gauss] |\r
+ * -------------------------------------------------------------------------------------------\r
+ * 0 | 0 | 0 | NA | NA | NA | 0xF800\960x07FF (-2048:2047)\r
+ * 0 | 0 | 1 | ±1.3 | 1100 | 980 | ""\r
+ * 0 | 1 | 0 | ±1.9 | 855 | 760 | ""\r
+ * 0 | 1 | 1 | ±2.5 | 670 | 600 | ""\r
+ * 1 | 0 | 0 | ±4.0 | 450 | 400 | ""\r
+ * 1 | 0 | 1 | ±4.7 | 400 | 355 | ""\r
+ * 1 | 1 | 0 | ±5.6 | 330 | 295 | ""\r
+ * 1 | 1 | 1 | ±8.1 | 230 | 205 | ""\r
+ * 4:0 0: They shall be zero for correct working of the device\r
+ * \endcode\r
+ */\r
+#define LSM_M_CRB_REG_ADDR (uint8_t) 0x01\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Mode Register\r
+ * \code\r
+ * Read/Write\r
+ * Default value: 0x02\r
+ * 7:2 0: They shall be zero for correct working of the device\r
+ * 1:0 MD1-MD0: Mode Select Bits\r
+ * MD1 | MD0 | MODE\r
+ * ------------------------------\r
+ * 0 | 0 | Continuous-Conversion Mode.\r
+ * 0 | 1 | Single-Conversion Mode\r
+ * 1 | 0 | Sleep Mode. Device is placed in sleep mode.\r
+ * 1 | 1 | Sleep Mode. Device is placed in sleep mode.\r
+ * \endcode\r
+ */\r
+#define LSM_M_MR_REG_ADDR (uint8_t) 0x02\r
+\r
+\r
+/**\r
+ * @brief Magnetometer X-axis Magnetic Field Data MSB register.\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * endcode\r
+ */\r
+#define LSM_M_OUT_X_H_ADDR 0x03\r
+\r
+\r
+/**\r
+ * @brief Magnetometer X-axis Magnetic Field Data LSB register\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * \endcode\r
+ */\r
+#define LSM_M_OUT_X_L_ADDR 0x04\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Z-axis Magnetic Field Data MSB register\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * \endcode\r
+ */\r
+#define LSM_M_OUT_Z_H_ADDR 0x05\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Z-axis Magnetic Field Data LSB register\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * \endcode\r
+ */\r
+#define LSM_M_OUT_Z_L_ADDR 0x06\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Y-axis Magnetic Field Data MSB register\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * \endcode\r
+ */\r
+#define LSM_M_OUT_Y_H_ADDR 0x07\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Y-axis Magnetic Field Data LSB register\r
+ * The value (MSB+LSB) is expressed as 16bit two\92s complement\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * \endcode\r
+ */\r
+#define LSM_M_OUT_Y_L_ADDR 0x08\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Status Register\r
+ * \code\r
+ * Read Only\r
+ * Default value: 0x00\r
+ * 7:2 0: They shall be zero for correct working of the device\r
+ * 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.\r
+ * 0 RDY: Data ready bit. This bit is set when a new set of measurements are available\r
+ * \endcode\r
+ */\r
+#define LSM_M_SR_REG_ADDR 0x09\r
+\r
+\r
+/**\r
+ * \brief Magnetometer Identification Register A\r
+ * \code\r
+ * Read\r
+ * Default value: 0x48\r
+ * \endcode\r
+ */\r
+#define LSM_M_IRA_REG_ADDR 0x0A\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Identification Register B\r
+ * \code\r
+ * Read\r
+ * Default value: 0x34\r
+ * \endcode\r
+ */\r
+#define LSM_M_IRB_REG_ADDR 0x0B\r
+\r
+\r
+/**\r
+ * @brief Magnetometer Identification Register C\r
+ * \code\r
+ * Read\r
+ * Default value: 0x33\r
+ * \endcode\r
+ */\r
+#define LSM_M_IRC_REG_ADDR 0x0C\r
+\r
+\r
+/**\r
+ * @brief Temperature Data MSB register\r
+ * The value (MSB+LSB) is expressed as 12bit two\92s complement with a sensitivity of 8LSB/deg\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * 7:0 TEMP11-TEMP4: MSB byte of temperature data.\r
+ * \endcode\r
+ */\r
+#define LSM_M_TEMP_H_REG_ADDR 0x31\r
+\r
+\r
+/**\r
+ * @brief Temperature Data LSB register\r
+ * The value (MSB+LSB) is expressed as 12bit two\92s complement with a sensitivity of 8LSB/deg\r
+ * \code\r
+ * Read\r
+ * Default value:\r
+ * 7:4 TEMP3-TEMP0: LSB byte of temperature data.\r
+ * 3-0 -: Do not consider.\r
+ * \endcode\r
+ */\r
+#define LSM_M_TEMP_L_REG_ADDR 0x32\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/** @defgroup Magnetometer_Exported_Functions Magnetometer Exported Functions\r
+ * @{\r
+ */\r
+\r
+\r
+void Lsm303dlhcMagConfig(LSMMagInit* pxLSMMagInitStruct);\r
+void Lsm303dlhcMagGetInfo(LSMMagInit* pxLSMMagInitStruct);\r
+void Lsm303dlhcMagSetFullScale(MagFullScale xFullScale);\r
+MagFullScale Lsm303dlhcMagGetEnumFullScale(void);\r
+void Lsm303dlhcMagGetSensitivity(float *pfSensitivityXYZ);\r
+float Lsm303dlhcMagGetFullScale(void);\r
+void Lsm303dlhcMagSetDataRate(MagOutputDataRate xDataRate);\r
+MagOutputDataRate Lsm303dlhcMagGetEnumDataRate(void);\r
+float Lsm303dlhcMagGetDataRate(void);\r
+void Lsm303dlhcMagReadMag(float* pfData);\r
+void Lsm303dlhcMagReadRawData(int16_t* pnRawData);\r
+int16_t Lsm303dlhcMagReadRawDataTemp(void);\r
+float Lsm303dlhcMagReadTemp(void);\r
+LSMMDataStatus Lsm303dlhcMagGetDataStatus(void);\r
+void Lsm303dlhcMagDataReadyIrqConfig(LSMFunctionalState xFunctionalState);\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __LSM303DLHC_H */\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
+\r
--- /dev/null
+/**\r
+ * @file LSM303DLH.c\r
+ * @author ART Team IMS-Systems Lab\r
+ * @version V2.3.0\r
+ * @date 12 April 2012\r
+ * @brief This file provides a set of functions needed to manage the LSM303DLH slave.\r
+ * @details\r
+ *\r
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
+ *\r
+ * THIS SOURCE CODE IS PROTECTED BY A LICENSE.\r
+ * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED\r
+ * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.\r
+ *\r
+ * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2>\r
+ */\r
+\r
+\r
+/* Includes */\r
+#include "LSM303DLHC.h"\r
+\r
+\r
+\r
+/**\r
+ * @addtogroup Sensor_Libraries Sensor Libraries\r
+ * @{\r
+ */\r
+\r
+/**\r
+* @defgroup LSM303DLHC\r
+* @{\r
+*/\r
+\r
+/**\r
+ * @addtogroup Accelerometer\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_TypesDefinitions Accelerometer Private TypesDefinitions\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_Defines Accelerometer Private Defines\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_Macros Accelerometer Private Macros\r
+ * @{\r
+ */\r
+\r
+#define LSM_ABS(a) (a>0?(a):-(a))\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_Variables Accelerometer Private Variables\r
+ * @{\r
+ */\r
+\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_FunctionPrototypes Accelerometer Private FunctionPrototypes\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Accelerometer_Private_Functions Accelerometer Private Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+* @brief Set configuration of Linear Acceleration measurement of LSM303DLHC\r
+* @param pxLSMAccInitStruct : pointer to a LSMAccInit structure that contains the configuration setting for the Accelerometer LSM303DLH.\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* LSMAccInit LSMAccInitStructure;\r
+*\r
+* LSMAccInitStructure.xPowerMode = LSM_NORMAL_MODE;\r
+* LSMAccInitStructure.xOutputDataRate = LSM_ODR_400_HZ;\r
+* LSMAccInitStructure.xEnabledAxes= LSM_ALL_AXES_EN;\r
+* LSMAccInitStructure.xFullScale = LSM_FS_2G;\r
+* LSMAccInitStructure.xDataUpdate = LSM_CONTINUOS_UPDATE;\r
+* LSMAccInitStructure.xEndianness = LSM_BIG_ENDIAN;\r
+* LSMAccInitStructure.xHighResolution = LSM_ENABLE;\r
+*\r
+* Lsm303dlhcAccConfig(&LSMAccInitStructure);\r
+* @endcode\r
+*/\r
+void Lsm303dlhcAccConfig(LSMAccInit* pxLSMAccInitStruct)\r
+{\r
+ uint8_t CTRL1 = 0x00, CTRL4 = 0x00;\r
+\r
+ /* Read the CTRL4 register content */\r
+ Lsm303dlhcAccI2CByteRead(&CTRL4, LSM_A_CTRL4_REG_ADDR);\r
+\r
+ /* Compute the register values */\r
+ CTRL1 |= (uint8_t) ((uint8_t)pxLSMAccInitStruct->xPowerMode | (uint8_t)pxLSMAccInitStruct->xOutputDataRate | (uint8_t)pxLSMAccInitStruct->xEnabledAxes);\r
+ CTRL4 |= (uint8_t) ((uint8_t)pxLSMAccInitStruct->xFullScale | (uint8_t)pxLSMAccInitStruct->xDataUpdate | (uint8_t)pxLSMAccInitStruct->xEndianness);\r
+ if(pxLSMAccInitStruct->xHighResolution == LSM_ENABLE)\r
+ {\r
+ CTRL4 |= 0x08;\r
+ }\r
+ else\r
+ {\r
+ CTRL4 &= 0xF0;\r
+ }\r
+\r
+ /* Write the computed values on registers */\r
+ Lsm303dlhcAccI2CByteWrite(&CTRL1, LSM_A_CTRL1_REG_ADDR);\r
+ Lsm303dlhcAccI2CByteWrite(&CTRL4, LSM_A_CTRL4_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the general configuration of LSM303DLHC for the linear acceleration.\r
+* @param pxLSMAccInitStruct : pointer to a LSMAccInit structure that will\r
+* contain the configuration setting read from the LSM303DLHC registers.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccGetInfo(LSMAccInit* pxLSMAccInitStruct)\r
+{\r
+ uint8_t CTRL1, CTRL4;\r
+\r
+ /* Read the registers content */\r
+ Lsm303dlhcAccI2CByteRead(&CTRL4, LSM_A_CTRL4_REG_ADDR);\r
+ Lsm303dlhcAccI2CByteRead(&CTRL1, LSM_A_CTRL1_REG_ADDR);\r
+\r
+ /* Fill the structure fields from CTRL1 reg info */\r
+ pxLSMAccInitStruct->xPowerMode = (AccPowerMode)(CTRL1 & 0x08);\r
+ pxLSMAccInitStruct->xOutputDataRate = (AccOutputDataRate)(CTRL1 & 0xF0);\r
+ pxLSMAccInitStruct->xEnabledAxes = (AccAxesEnabling)(CTRL1 & 0x07);\r
+\r
+ /* Fill the structure fields from CTRL4 reg info */\r
+ pxLSMAccInitStruct->xFullScale = (AccFullScale)(CTRL4 & 0x30);\r
+ pxLSMAccInitStruct->xDataUpdate = (AccBlockDataUpdate)(CTRL4 & 0x80);\r
+ pxLSMAccInitStruct->xEndianness = (AccEndianness)(CTRL4 & 0x40);\r
+\r
+ if(CTRL4 & 0x08)\r
+ pxLSMAccInitStruct->xHighResolution = LSM_ENABLE;\r
+ else\r
+ pxLSMAccInitStruct->xHighResolution = LSM_DISABLE;\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Set configuration of Internal High Pass Filter of LSM303DLHC for the linear acceleration\r
+* @param pxLSMAccFilterInitStruct : pointer to a LSMAccFilterInit structure that\r
+* contains the configuration setting for the LSM303DLHC.\r
+* @retval None\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* LSMAccFilterInit LSMAccFilterInitStructure;\r
+*\r
+* LSMAccFilterInitStructure.xHPF=LSM_DISABLE;\r
+* LSMAccFilterInitStructure.xHPF_Mode=LSM_HPFM_NORMAL;\r
+* LSMAccFilterInitStructure.cHPFReference=0x00;\r
+* LSMAccFilterInitStructure.xHPFCutOff=LSM_HPCF_16;\r
+* LSMAccFilterInitStructure.xHPFClick=LSM_DISABLE;\r
+* LSMAccFilterInitStructure.xHPFAOI2=LSM_DISABLE;\r
+* LSMAccFilterInitStructure.xHPFAOI1=LSM_DISABLE;\r
+*\r
+* Lsm303dlhcAccFilterConfig(&LSMAccFilterInitStructure);\r
+* @endcode\r
+*/\r
+void Lsm303dlhcAccFilterConfig(LSMAccFilterInit* pxLSMAccFilterInitStruct)\r
+{\r
+ uint8_t CTRL2 = 0x00;\r
+ uint8_t REF = 0x00;\r
+\r
+ /* Compute the register values */\r
+ CTRL2 |= (uint8_t) ((uint8_t)pxLSMAccFilterInitStruct->xHPF_Mode| (uint8_t)pxLSMAccFilterInitStruct->xHPFCutOff);\r
+ if(pxLSMAccFilterInitStruct->xHPF == LSM_ENABLE)\r
+ {\r
+ CTRL2 |= 0x08;\r
+ }\r
+ else\r
+ {\r
+ CTRL2 &= 0xF7;\r
+ }\r
+ if(pxLSMAccFilterInitStruct->xHPFClick == LSM_ENABLE)\r
+ {\r
+ CTRL2 |= 0x04;\r
+ }\r
+ else\r
+ {\r
+ CTRL2 &= 0xFB;\r
+ }\r
+ if(pxLSMAccFilterInitStruct->xHPFAOI2 == LSM_ENABLE)\r
+ {\r
+ CTRL2 |= 0x02;\r
+ }\r
+ else\r
+ {\r
+ CTRL2 &= 0xFD;\r
+ }\r
+ if(pxLSMAccFilterInitStruct->xHPFAOI1 == LSM_ENABLE)\r
+ {\r
+ CTRL2 |= 0x01;\r
+ }\r
+ else\r
+ {\r
+ CTRL2 &= 0xFE;\r
+ }\r
+\r
+ REF |= (uint8_t) (pxLSMAccFilterInitStruct->cHPFReference);\r
+\r
+ /* Write the computed values on registers */\r
+ Lsm303dlhcAccI2CByteWrite(&CTRL2, LSM_A_CTRL2_REG_ADDR);\r
+ Lsm303dlhcAccI2CByteWrite(&REF, LSM_A_REFERENCE_REG_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Get configuration of Internal High Pass Filter of LSM303DLHC for the linear acceleration\r
+* @param pxLSMAccFilterInitStruct : pointer to a LSMAccFilterInit structure that will\r
+* contain the configuration setting read from the LSM303DLHC registers.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccFilterGetInfo(LSMAccFilterInit* pxLSMAccFilterInitStruct)\r
+{\r
+ uint8_t ctrl2, ref;\r
+\r
+ Lsm303dlhcAccI2CByteRead(&ctrl2, LSM_A_CTRL2_REG_ADDR);\r
+ Lsm303dlhcAccI2CByteRead(&ref, LSM_A_REFERENCE_REG_ADDR);\r
+\r
+ /* Get the filter mode and the cut-off frequency */\r
+ pxLSMAccFilterInitStruct->xHPF_Mode = (AccHPFMode)(ctrl2 & 0xC0);\r
+ pxLSMAccFilterInitStruct->xHPFCutOff = (AccHPFCutOff)(ctrl2 & 0x30);\r
+\r
+ /* Get the enable/disable filter bit */\r
+ if(ctrl2 & 0x08)\r
+ pxLSMAccFilterInitStruct->xHPF = LSM_ENABLE;\r
+ else\r
+ pxLSMAccFilterInitStruct->xHPF = LSM_DISABLE;\r
+\r
+ /* Get the enable/disable filter for click bit */\r
+ if(ctrl2 & 0x04)\r
+ pxLSMAccFilterInitStruct->xHPFClick = LSM_ENABLE;\r
+ else\r
+ pxLSMAccFilterInitStruct->xHPFClick = LSM_DISABLE;\r
+\r
+ /* Get the enable/disable int2 bit */\r
+ if(ctrl2 & 0x02)\r
+ pxLSMAccFilterInitStruct->xHPFAOI2 = LSM_ENABLE;\r
+ else\r
+ pxLSMAccFilterInitStruct->xHPFAOI2 = LSM_DISABLE;\r
+\r
+ /* Get the enable/disable int1 bit */\r
+ if(ctrl2 & 0x01)\r
+ pxLSMAccFilterInitStruct->xHPFAOI1 = LSM_ENABLE;\r
+ else\r
+ pxLSMAccFilterInitStruct->xHPFAOI1 = LSM_DISABLE;\r
+\r
+ /* Get the reference value */\r
+ pxLSMAccFilterInitStruct->cHPFReference=ref;\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Enable or disable the lowpower mode for Accelerometer of LSM303DLHC\r
+* @param xFunctionalState : new state for the lowpower mode. This parameter can be: LSM_ENABLE or LSM_DISABLE\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccLowPowerMode(LSMFunctionalState xFunctionalState)\r
+{\r
+ uint8_t tmpreg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL1_REG_ADDR);\r
+\r
+ /* modify the specified bit */\r
+ if(xFunctionalState == LSM_ENABLE)\r
+ {\r
+ tmpreg |= 0x08;\r
+ }\r
+ else\r
+ {\r
+ tmpreg &= 0xF7;\r
+ }\r
+\r
+ /* Write the computed values on registers */\r
+ Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL1_REG_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Change the ODR(Output data rate) for Acceleromter of LSM303DLH\r
+* @param xDataRate : new ODR value. This parameter can be one of the AccOutputDataRate value\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccSetDataRate(AccOutputDataRate xDataRate)\r
+{\r
+ uint8_t tmpreg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL1_REG_ADDR);\r
+ tmpreg &= 0x0F;\r
+ tmpreg |= (uint8_t) xDataRate;\r
+\r
+ /* Write computed byte onto register */\r
+ Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL1_REG_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the output data rate as a AccOutputDataRate enumerative value.\r
+* @param None.\r
+* @retval AccOutputDataRate: AccOutputDataRate enumerative value.\r
+*/\r
+AccOutputDataRate Lsm303dlhcAccGetEnumDataRate(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL1_REG_ADDR);\r
+\r
+ /* mask and return it */\r
+ return((AccOutputDataRate)(tmpReg & 0xF0));\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the output data rate.\r
+* @param None.\r
+* @retval Datarate in Hz.\r
+* This parameter is an uint16_t.\r
+*/\r
+uint16_t Lsm303dlhcAccGetDataRate(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL1_REG_ADDR);\r
+\r
+ /* ..mask it */\r
+ tmpReg &= 0xF0;\r
+\r
+ /* return the correspondent value */\r
+ switch(tmpReg){\r
+ case LSM_ODR_1_HZ:\r
+ return 1;\r
+ case LSM_ODR_10_HZ:\r
+ return 10;\r
+ case LSM_ODR_25_HZ:\r
+ return 25;\r
+ case LSM_ODR_50_HZ:\r
+ return 50;\r
+ case LSM_ODR_100_HZ:\r
+ return 100;\r
+ case LSM_ODR_200_HZ:\r
+ return 200;\r
+ case LSM_ODR_400_HZ:\r
+ return 400;\r
+ case LSM_ODR_1620_HZ:\r
+ return 1620;\r
+ case LSM_ODR_1344_HZ:\r
+ return 1344;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/**\r
+* @brief Change the Full Scale of LSM303DLH\r
+* @param xFullScale : new full scale value. This parameter can be one of the AccFullScale value\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccSetFullScale(AccFullScale xFullScale)\r
+{\r
+ uint8_t tmpreg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL4_REG_ADDR);\r
+\r
+ /* Compute the value */\r
+ tmpreg &= 0xCF;\r
+ tmpreg |= (uint8_t) xFullScale;\r
+\r
+ /* Write the computed value */\r
+ Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL4_REG_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the Full Scale of LSM303DLH as a AccFullScale enumerative value.\r
+* @param None.\r
+* @retval AccFullScale: Abs value of Fullscale typdef.\r
+*/\r
+AccFullScale Lsm303dlhcAccGetEnumFullScale(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR);\r
+\r
+ /* Return the enumerative type value */\r
+ return((AccFullScale)(tmpReg & 0x30));\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the Full Scale of LSM303DLH expressed in g.\r
+* @param None.\r
+* @retval uint8_t: Abs value of Fullscale expressed in g.\r
+*/\r
+uint8_t Lsm303dlhcAccGetFullScale(void)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR);\r
+ tmpReg &= 0x30;\r
+\r
+ /* return the correspondent value */\r
+ switch(tmpReg)\r
+ {\r
+ case LSM_FS_2G:\r
+ return 2;\r
+ case LSM_FS_4G:\r
+ return 4;\r
+ case LSM_FS_8G:\r
+ return 8;\r
+ case LSM_FS_16G:\r
+ return 16;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the Full Scale of LSM303DLH expressed in LSB/mg.\r
+* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored.\r
+* This parameter is a pointer to a float array.\r
+* @retval None.\r
+*/\r
+void Lsm303dlhcAccGetSensitivity(float *pfSensitivityXYZ)\r
+{\r
+ uint8_t tmpReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tmpReg, LSM_A_CTRL4_REG_ADDR);\r
+ tmpReg &= 0x30;\r
+\r
+ /* return the correspondent value */\r
+ switch(tmpReg)\r
+ {\r
+ case LSM_FS_2G:\r
+ pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_2g;\r
+ pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_2g;\r
+ pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_2g;\r
+ \r
+ break;\r
+ case LSM_FS_4G:\r
+ pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_4g;\r
+ pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_4g;\r
+ pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_4g;\r
+ \r
+ break;\r
+ case LSM_FS_8G:\r
+ pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_8g;\r
+ pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_8g;\r
+ pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_8g;\r
+ \r
+ break;\r
+ case LSM_FS_16G:\r
+ pfSensitivityXYZ[0]=LSM_Acc_Sensitivity_16g;\r
+ pfSensitivityXYZ[1]=LSM_Acc_Sensitivity_16g;\r
+ pfSensitivityXYZ[2]=LSM_Acc_Sensitivity_16g;\r
+ \r
+ break;\r
+ }\r
+ \r
+ \r
+}\r
+\r
+/**\r
+* @brief Reboot memory content of LSM303DLH\r
+* @param None\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccRebootCmd(void)\r
+{\r
+ uint8_t tmpreg;\r
+ Lsm303dlhcAccI2CByteRead(&tmpreg, LSM_A_CTRL2_REG_ADDR);\r
+ tmpreg |= 0x80;\r
+ Lsm303dlhcAccI2CByteWrite(&tmpreg, LSM_A_CTRL2_REG_ADDR);\r
+}\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLHC linear acceleration output register\r
+* @param out : buffer to store data\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccReadOutReg(uint8_t* pcReg)\r
+{\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CBufferRead(pcReg, LSM_A_OUT_X_L_REG_ADDR, 6);\r
+}\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLHC output register, and calculate the raw acceleration [LSB] ACC= (out_h*256+out_l)/16 (12 bit rappresentation)\r
+* @param pnRawData: pointer to signed 16-bit data buffer where to store data\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccReadRawData(int16_t* pnRawData)\r
+{\r
+ uint8_t buffer[6], ctrlx[2], cDivider;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CBufferRead(ctrlx, LSM_A_CTRL4_REG_ADDR,2);\r
+ Lsm303dlhcAccReadOutReg(&buffer[0]);\r
+\r
+\r
+ if(ctrlx[1]&0x40)\r
+ cDivider=64;\r
+ else\r
+ cDivider=16;\r
+\r
+ /* check in the control register4 the data alignment*/\r
+ if(!(ctrlx[0] & 0x40) || (ctrlx[1] & 0x40)) /* Little Endian Mode or FIFO mode */\r
+ {\r
+ for(int i=0; i<3; i++)\r
+ {\r
+ pnRawData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i])/cDivider;\r
+ }\r
+ }\r
+ else /* Big Endian Mode */\r
+ {\r
+ for(uint8_t i=0; i<3; i++)\r
+ pnRawData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])/cDivider;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLHC output register, and calculate the acceleration ACC=(1/SENSITIVITY)* (out_h*256+out_l)/16 (12 bit rappresentation)\r
+* @param pnData: pointer to float buffer where to store data\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccReadAcc(float* pfData)\r
+{\r
+ int16_t buffer[3];\r
+ uint8_t ctrlx[2];\r
+ float LSM_Acc_Sensitivity;\r
+\r
+ /* Read the raw data */\r
+ Lsm303dlhcAccReadRawData(buffer);\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CBufferRead(ctrlx, LSM_A_CTRL4_REG_ADDR,2);\r
+\r
+\r
+ if(ctrlx[1]&0x40){\r
+ /* FIFO mode */\r
+ LSM_Acc_Sensitivity = 0.25;\r
+ }\r
+ else\r
+ {\r
+ /* normal mode */\r
+ /* switch the sensitivity value set in the CRTL4*/\r
+ switch(ctrlx[0] & 0x30)\r
+ {\r
+ case LSM_FS_2G:\r
+ LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_2g;\r
+ break;\r
+ case LSM_FS_4G:\r
+ LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_4g;\r
+ break;\r
+ case LSM_FS_8G:\r
+ LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_8g;\r
+ break;\r
+ case LSM_FS_16G:\r
+ LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_16g;\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* Obtain the mg value for the three axis */\r
+ for(uint8_t i=0; i<3; i++)\r
+ {\r
+ pfData[i]=(float)buffer[i]/LSM_Acc_Sensitivity;\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLHC output register when FIFO mode is active.\r
+* @param pnData: pointer to signed integer buffer where to store data.\r
+* This parameter is an int16_t array pointer.\r
+* @param cDataToRead: number of samples to read. Each sample is made up of the three axis readings.\r
+* This parameter is an uint8_t .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccReadAccFifo(int16_t* pnData, uint8_t cDataToRead)\r
+{\r
+ uint8_t *pcBuffer=(uint8_t*)pnData;\r
+ uint8_t j=0;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CBufferRead(pcBuffer, LSM_A_OUT_X_L_REG_ADDR, cDataToRead*6);\r
+\r
+ /* convert all data to signed int16 */\r
+ for(uint16_t i=0 ; i<cDataToRead*3 ; i++)\r
+ {\r
+ pnData[i] = (int16_t)(((uint16_t)pcBuffer[j+1]<<8)+(uint16_t)pcBuffer[j])/16;\r
+ j+=2;\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the IRQ1 line to be raised on a specific event.\r
+* @param xLSMAIrq1Config: Interrupt mask to enable.\r
+* This parameter is a @ref LSMAIrq1List .\r
+* @param xNewState: Enable or disable I1.\r
+* This parameter can be LSM_ENABLE or LSM_DISABLE.\r
+* @retval None\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* ...\r
+* ExtiConfiguration(); // set the micro exti before init\r
+* Lsm303dlhcAccIrq1Config(LSM_I1_DRDY1,LSM_ENABLE); // for example enable the data_ready IRQ on line1\r
+* ...\r
+* @endcode\r
+*/\r
+void Lsm303dlhcAccIrq1Config(LSMAIrq1List xLSMAIrq1Config, LSMFunctionalState xNewState)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_CTRL3_REG_ADDR);\r
+\r
+ /* Unmask the selected IRQ */\r
+ if(xNewState)\r
+ tempReg |= (uint8_t)xLSMAIrq1Config;\r
+ else\r
+ tempReg &= ~(uint8_t)xLSMAIrq1Config;\r
+\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL3_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the IRQ2 line to be raised on a specific event.\r
+* @param xLSMAIrq2Config: Interrupt mask to enable.\r
+* This parameter is a @ref LSMAIrq2List .\r
+* @param xNewState: Enable or disable I2.\r
+* This parameter can be LSM_ENABLE or LSM_DISABLE.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccIrq2Config(LSMAIrq2List xLSMAIrq2Config, LSMFunctionalState xNewState)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_CTRL6_REG_ADDR);\r
+\r
+ /* Unmask the selected IRQ */\r
+ if(xNewState)\r
+ tempReg |= (uint8_t)xLSMAIrq2Config;\r
+ else\r
+ tempReg &= ~(uint8_t)xLSMAIrq2Config;\r
+\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL6_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the sensor FIFO.\r
+* @param xNewState: New state for the FIFO use.\r
+* This parameter is a @ref LSMFunctionalState\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccFifo(LSMFunctionalState xNewState)\r
+{\r
+ /* Built the byte to be written */\r
+ uint8_t tempReg;\r
+\r
+ /* Read the value on the CTRL5 register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL5_REG_ADDR);\r
+\r
+ /* Build the value to write */\r
+ if(xNewState == LSM_ENABLE)\r
+ tempReg |= 0x40;\r
+ else\r
+ tempReg &= (~0x40);\r
+\r
+ /* Write the built value on the CTRL5 register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_CTRL5_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the sensor FIFO.\r
+* @param pxLSMAccFifoInit: pointer to the Fifo initialization structure.\r
+* This parameter is a pointer to a @ref LSMAccFifoInit.\r
+* @note This function won't enable the FIFO. Please call the @ref Lsm303dlhcAccFifo in order to enable this mode.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccFifoInit(LSMAccFifoInit* pxLSMAccFifoInit)\r
+{\r
+ /* Built the byte to be written */\r
+ uint8_t tempReg = (pxLSMAccFifoInit->xFifoMode | (pxLSMAccFifoInit->cWtm & 0x1F));\r
+\r
+ /* Select the INT line */\r
+ if(pxLSMAccFifoInit->xTriggerSel == LSM_INT2_LINE)\r
+ tempReg |= 0x20;\r
+\r
+ /* Write the built value on the FIFO_CTRL register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_FIFO_CTRL_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the FIFO status flags and unread data.\r
+* @param pxLSMAccFifoStatus: pointer to the Fifo status structure.\r
+* This parameter is a pointer to a @ref LSMAccFifoStatus\r
+* @retval None\r
+*/\r
+LSMAccFifoStatus Lsm303dlhcAccFifoGetStatus(void)\r
+{\r
+ LSMAccFifoStatus xLSMAccFifoStatus;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead((uint8_t*)&xLSMAccFifoStatus, LSM_A_FIFO_STATUS_REG_ADDR);\r
+\r
+ /* Return its value */\r
+ return xLSMAccFifoStatus;\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the IRQs on Axis.\r
+* @param xIrqCombinations: Combination of events on axis.\r
+* This parameter is a @ref LSMAccIrqOnaxisCombination .\r
+* @param pxAxisEvents: Events on axis structure.\r
+* This parameter is a pointer to a @ref LSMAccAxisEvents .\r
+* @param xIRQLine: IRQ line to be set.\r
+* This parameter is a @ref LSMAIrqLine .\r
+* @param xLatched: specifies if an IRQ is latched.\r
+* This parameter can be LSM_ENABLE or LSM_DISABLE .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccSetAxisIrqs(LSMAccIrqOnaxisCombination xIrqCombinations, LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine, LSMFunctionalState xLatched)\r
+{\r
+\r
+ /* Build the value to build on register */\r
+ uint8_t tempReg = ((uint8_t)xIrqCombinations) | (*(uint8_t*)pxAxisEvents);\r
+ uint8_t tempLatch;\r
+\r
+ /* Read for latch conf */\r
+ Lsm303dlhcAccI2CByteRead(&tempLatch, LSM_A_CTRL5_REG_ADDR);\r
+\r
+ /* Interrupt line selection */\r
+ if(xIRQLine == LSM_INT1_LINE)\r
+ {\r
+ /* Write the built value on the LSM_A_INT1_CFG_REG register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT1_CFG_REG_ADDR);\r
+\r
+ if(xLatched)\r
+ tempLatch |= 0x08;\r
+ else\r
+ tempLatch &= 0xF7;\r
+ }\r
+ else\r
+ {\r
+ /* Write the built value on the LSM_A_INT2_CFG_REG register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT2_CFG_REG_ADDR);\r
+\r
+ if(xLatched)\r
+ tempLatch |= 0x02;\r
+ else\r
+ tempLatch &= 0xFD;\r
+ }\r
+\r
+ /* Write for latch conf */\r
+ Lsm303dlhcAccI2CByteWrite(&tempLatch, LSM_A_CTRL5_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the IRQs on Axis status.\r
+* @param pxAxisEvents: Events on axis structure.\r
+* This parameter is a pointer to a @ref LSMAccAxisEvents .\r
+* @param xIRQLine: IRQ line mask to be get.\r
+* This parameter is a @ref LSMAIrqLine .\r
+* @retval None\r
+*/\r
+LSMFunctionalState Lsm303dlhcAccGetAxisIrqs(LSMAccAxisEvents* pxAxisEvents, LSMAIrqLine xIRQLine)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Interrupt line selection */\r
+ if(xIRQLine == LSM_INT1_LINE)\r
+ {\r
+ /* Read the register for the LINE1 */\r
+ Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_INT1_SRC_REG_ADDR);\r
+ }\r
+ else\r
+ {\r
+ /* Read the register for the LINE2 */\r
+ Lsm303dlhcAccI2CByteRead(&tempReg, LSM_A_INT2_SRC_REG_ADDR);\r
+ }\r
+\r
+ uint8_t tempRet = tempReg & 0x7F;\r
+\r
+ /* Take the MSb to return */\r
+ (*pxAxisEvents)=*(LSMAccAxisEvents*)(&tempRet);\r
+\r
+ return (LSMFunctionalState)(tempRet>>6);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets threshold for acceleration.\r
+* @param nData: Acceleration threshold.\r
+* This parameter is a uint16_t.\r
+* @param xIRQLine: IRQ threshold mask to be set.\r
+* This parameter is a @ref LSMAIrqLine .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccSetThreshold(int16_t nData, LSMAIrqLine xIRQLine)\r
+{\r
+ uint8_t ctrl4, accThs;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead(&ctrl4, LSM_A_CTRL4_REG_ADDR);\r
+\r
+ /* switch the sensitivity value set in the CRTL4*/\r
+ switch(ctrl4 & 0x30)\r
+ {\r
+ case LSM_FS_2G:\r
+ accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_2g);\r
+ break;\r
+ case LSM_FS_4G:\r
+ accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_4g);\r
+ break;\r
+ case LSM_FS_8G:\r
+ accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_8g);\r
+ break;\r
+ case LSM_FS_16G:\r
+ accThs = (uint8_t)((float)(nData/16)*LSM_Acc_Sensitivity_16g);\r
+ break;\r
+ }\r
+\r
+ /* Ensure that the MSb is 0 */\r
+ accThs &= 0x7F;\r
+\r
+ /* Interrupt line selection */\r
+ if(xIRQLine == LSM_INT1_LINE)\r
+ {\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&accThs, LSM_A_INT1_THS_REG_ADDR);\r
+ }\r
+ else\r
+ {\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&accThs, LSM_A_INT2_THS_REG_ADDR);\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Sets the minimum duration of an IRQ to be recognized.\r
+* @param cDuration: Duration expressed in ms.\r
+* This parameter is a uint8_t .\r
+* @param xIRQLine: IRQ duration to be set.\r
+* This parameter is a @ref LSMAIrqLine .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcAccSetIrqDuration(uint8_t cDuration, LSMAIrqLine xIRQLine)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Get datarate for time register value computation */\r
+ uint16_t nDatarate = Lsm303dlhcAccGetDataRate();\r
+\r
+ /* Compute the duration register value */\r
+ tempReg=(uint8_t)((float)cDuration/1000*nDatarate);\r
+\r
+ if(xIRQLine == LSM_INT1_LINE)\r
+ {\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT1_DURATION_REG_ADDR);\r
+ }\r
+ else\r
+ {\r
+ /* Write byte on register */\r
+ Lsm303dlhcAccI2CByteWrite(&tempReg, LSM_A_INT2_DURATION_REG_ADDR);\r
+ }\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the Click or Double click recognition parameters.\r
+* @param xClickInit: Click configuration structure.\r
+* This parameter is a pointer to\r
+* @retval None.\r
+*/\r
+void Lsm303dlhcAccClickInit(LSMAccClickInit* pxClickInit)\r
+{\r
+ uint8_t tempReg[5];\r
+\r
+ /* Get fullscale for threshold register value computation */\r
+ uint8_t cFullscale = Lsm303dlhcAccGetFullScale();\r
+\r
+ /* Get datarate for time register value computation */\r
+ uint16_t nDatarate = Lsm303dlhcAccGetDataRate();\r
+\r
+ /* Read values on register */\r
+ Lsm303dlhcI2CBufferRead(LSM_A_CLICK_SRC_REG_ADDR, tempReg, LSM_A_CTRL4_REG_ADDR, 5);\r
+\r
+ /* Sign setting */\r
+ tempReg[0] &= 0x08;\r
+ tempReg[0] |= (pxClickInit->xNegativeDetection)<<3;\r
+\r
+ /* Threshold value computation */\r
+ tempReg[1] = (uint8_t)((float)pxClickInit->nClickThreshold/1000*(128/cFullscale));\r
+\r
+ /* time limit computation */\r
+ tempReg[2] = (uint8_t)((float)pxClickInit->cClickTimeLimit/1000*nDatarate);\r
+\r
+ /* time latency computation */\r
+ tempReg[3] = (uint8_t)((float)pxClickInit->cDClickTimeLatency/1000*nDatarate);\r
+\r
+ /* time window computation */\r
+ tempReg[4] = (uint8_t)((float)pxClickInit->cDClickTimeWindow/1000*nDatarate);\r
+\r
+ /* Write values on register */\r
+ Lsm303dlhcI2CBufferWrite(LSM_A_CLICK_SRC_REG_ADDR, tempReg, LSM_A_CTRL4_REG_ADDR, 5);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets status for accelerometer data.\r
+* @param None.\r
+* @retval LSMADataStatus: Data status in a LSMADataStatus bitfields structure.\r
+*/\r
+LSMADataStatus Lsm303dlhcAccGetDataStatus(void)\r
+{\r
+ LSMADataStatus xStatus;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead((uint8_t*)&xStatus, LSM_A_STATUS_REG_ADDR);\r
+\r
+ return xStatus;\r
+\r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @addtogroup Magnetometer\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_TypesDefinitions Magnetometer Private TypesDefinitions\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_Defines Magnetometer Private Defines\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_Macros Magnetometer Private Macros\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_Variables Magnetometer Private Variables\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_FunctionPrototypes Magnetometer Private FunctionPrototypes\r
+ * @{\r
+ */\r
+\r
+/**\r
+ *@}\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Magnetometer_Private_Functions Magnetometer Private Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+* @brief Set configuration of Magnetic field measurement of LSM303DLHC.\r
+* @param pxLSMMagInitStruct: pointer to LSMMagInit structure that\r
+* contains the configuration setting for the LSM303DLHC Magnetometer part.\r
+* @retval None.\r
+* @details\r
+* <b>Example:</b>\r
+* @code\r
+* LSMMagInit LSMMagInitStructure;\r
+*\r
+* LSMMagInitStructure.xOutputDataRate = LSM_ODR_30_HZ;\r
+* LSMMagInitStructure.xFullScale = LSM_FS_1_3_GA;\r
+* LSMMagInitStructure.xWorkingMode = LSM_CONTINUOS_CONVERSION;\r
+* LSMMagInitStructure.xTemperatureSensor = LSM_ENABLE;\r
+*\r
+* Lsm303dlhcMagConfig(&LSMMagInitStructure);\r
+* @endcode\r
+*/\r
+void Lsm303dlhcMagConfig(LSMMagInit* pxLSMMagInitStruct)\r
+{\r
+ uint8_t CTRLx[2] = {0x00,0x00};\r
+ uint8_t MODE = 0x00;\r
+\r
+ CTRLx[0] |= (uint8_t) (pxLSMMagInitStruct->xOutputDataRate);\r
+ if(pxLSMMagInitStruct->xTemperatureSensor == LSM_ENABLE)\r
+ CTRLx[0] |= 0x80;\r
+\r
+ CTRLx[1] |= (uint8_t) (pxLSMMagInitStruct->xFullScale);\r
+\r
+ MODE |= (uint8_t) (pxLSMMagInitStruct->xWorkingMode);\r
+\r
+ Lsm303dlhcMagI2CBufferWrite(CTRLx, LSM_M_CRA_REG_ADDR, 2); //CRTL_REGA and B\r
+ Lsm303dlhcMagI2CByteWrite(&MODE, LSM_M_MR_REG_ADDR); //Mode register\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets the general configuration of LSM303DLHC for the magnetometer.\r
+* @param pxLSMMagInitStruct : pointer to a LSMMagInit structure that will\r
+* contain the configuration setting read from the LSM303DLHC registers.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagGetInfo(LSMMagInit* pxLSMMagInitStruct)\r
+{\r
+ uint8_t CTRLx[2];\r
+ uint8_t MODE;\r
+\r
+ Lsm303dlhcMagI2CBufferRead(CTRLx, LSM_M_CRA_REG_ADDR, 2);\r
+ Lsm303dlhcMagI2CByteRead(&MODE, LSM_M_MR_REG_ADDR);\r
+\r
+ /* Get the CTRL[0] info */\r
+ pxLSMMagInitStruct->xOutputDataRate = (MagOutputDataRate)(CTRLx[0] & 0x1C);\r
+\r
+ if(CTRLx[0] & 0x80)\r
+ pxLSMMagInitStruct->xTemperatureSensor = LSM_ENABLE;\r
+ else\r
+ pxLSMMagInitStruct->xTemperatureSensor = LSM_DISABLE;\r
+\r
+ /* Get the CTRL[1] info */\r
+ pxLSMMagInitStruct->xFullScale = (MagFullScale)(CTRLx[1] & 0xE0);\r
+\r
+ /* Get the MODE info */\r
+ pxLSMMagInitStruct->xWorkingMode = (MagWorkingMode)(MODE & 0x03);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Set the full scale of the Magnetic field sensor.\r
+* @param xFullScale: FullScale value.\r
+* This parameter must be a value of @ref MagFullScale .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagSetFullScale(MagFullScale xFullScale)\r
+{\r
+ uint8_t tempReg=(uint8_t) xFullScale;\r
+\r
+ /* Write value on register */\r
+ Lsm303dlhcMagI2CByteWrite(&tempReg, LSM_M_CRB_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Get the full scale of the Magnetic field sensor expressed as a MagFullScale enumerative value.\r
+* @param None\r
+* @retval MagFullScale: full scale value expressed as a value of the enum typdef.\r
+*/\r
+MagFullScale Lsm303dlhcMagGetEnumFullScale(void)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR);\r
+\r
+ /* Mask and return it */\r
+ return((MagFullScale)(tempReg & 0xE0));\r
+\r
+}\r
+\r
+/**\r
+* @brief Get the full scale of the Magnetic field sensor.\r
+* @param None\r
+* @retval float: full scale value expressed in gauss.\r
+*/\r
+float Lsm303dlhcMagGetFullScale(void)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR);\r
+\r
+ switch(tempReg)\r
+ {\r
+ case LSM_FS_1_3_GA:\r
+ return 1.3;\r
+ case LSM_FS_1_9_GA:\r
+ return 1.9;\r
+ case LSM_FS_2_5_GA:\r
+ return 2.5;\r
+ case LSM_FS_4_0_GA:\r
+ return 4.0;\r
+ case LSM_FS_4_7_GA:\r
+ return 4.7;\r
+ case LSM_FS_5_6_GA:\r
+ return 5.6;\r
+ case LSM_FS_8_1_GA:\r
+ return 8.1;\r
+ }\r
+\r
+ return 0.0;\r
+}\r
+\r
+\r
+/**\r
+* @brief Returns the Full Scale of LSM303DLH expressed in LSB/mgauss.\r
+* @param pfSensitivityXYZ: pointer to 3 elements array in which the sensitivity values have to be stored.\r
+* This parameter is a pointer to a float array.\r
+* @retval None.\r
+*/\r
+void Lsm303dlhcMagGetSensitivity(float *pfSensitivityXYZ)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRB_REG_ADDR);\r
+\r
+ switch(tempReg & 0xE0)\r
+ {\r
+ case LSM_FS_1_3_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_1_3Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_1_3Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_1_3Ga;\r
+ break;\r
+ case LSM_FS_1_9_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_1_9Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_1_9Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_1_9Ga;\r
+ break;\r
+ case LSM_FS_2_5_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_2_5Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_2_5Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_2_5Ga;\r
+ break;\r
+ case LSM_FS_4_0_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_4Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_4Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_4Ga;\r
+ break;\r
+ case LSM_FS_4_7_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_4_7Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_4_7Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_4_7Ga;\r
+ break;\r
+ case LSM_FS_5_6_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_5_6Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_5_6Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_5_6Ga;\r
+ break;\r
+ case LSM_FS_8_1_GA:\r
+ pfSensitivityXYZ[0]=LSM_Magn_Sensitivity_XY_8_1Ga;\r
+ pfSensitivityXYZ[1]=LSM_Magn_Sensitivity_XY_8_1Ga;\r
+ pfSensitivityXYZ[2]=LSM_Magn_Sensitivity_Z_8_1Ga;\r
+ break;\r
+ }\r
+}\r
+/**\r
+* @brief Set the data rate of the Magnetic field sensor.\r
+* @param xFullScale: Datarate value.\r
+* This parameter must be a value of @ref MagOutputDataRate .\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagSetDataRate(MagOutputDataRate xDataRate)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR);\r
+\r
+ tempReg &= 0x80;\r
+ tempReg |= (uint8_t)xDataRate;\r
+\r
+ /* Write value on register */\r
+ Lsm303dlhcMagI2CByteWrite(&tempReg, LSM_M_CRA_REG_ADDR);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Get the data rate of the Magnetic field sensor in the MagOutputDataRate enumerative value.\r
+* @param None\r
+* @retval MagOutputDataRate: data rate value expressed as enum value.\r
+*/\r
+MagOutputDataRate Lsm303dlhcMagGetEnumDataRate(void)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR);\r
+\r
+ /* Mask and return it */\r
+ return((MagOutputDataRate)(tempReg & 0x1C));\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Get the data rate of the Magnetic field sensor.\r
+* @param None\r
+* @retval float: data rate value expressed in gauss.\r
+*/\r
+float Lsm303dlhcMagGetDataRate(void)\r
+{\r
+ uint8_t tempReg;\r
+\r
+ /* Read value on register */\r
+ Lsm303dlhcMagI2CByteRead(&tempReg, LSM_M_CRA_REG_ADDR);\r
+\r
+ switch((MagOutputDataRate)(tempReg & 0x1C))\r
+ {\r
+ case LSM_ODR_0_75_HZ:\r
+ return 0.75;\r
+ case LSM_ODR_1_5_HZ:\r
+ return 1.5;\r
+ case LSM_ODR_7_5_HZ:\r
+ return 7.5;\r
+ case LSM_ODR_15_HZ:\r
+ return 15.0;\r
+ case LSM_ODR_30_HZ:\r
+ return 30.0;\r
+ case LSM_ODR_75_HZ:\r
+ return 75.0;\r
+ case LSM_ODR_220_HZ:\r
+ return 220.0;\r
+ }\r
+\r
+ return 0.0;\r
+}\r
+\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLHC output register, and calculate the magnetic field Magn[mGa]=(out_h*256+out_l)*1000/ SENSITIVITY\r
+* @param pnData: pointer to signed 16-bit buffer where to store data\r
+* @note Despite the datasheet indications, the read axis will be stored in the passed\r
+* array in the order X,Y,Z.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagReadMag(float* pfData)\r
+{\r
+ uint8_t buffer[6];\r
+ uint8_t CTRLB;\r
+ uint16_t LSM_Magn_Sensitivity_XY, LSM_Magn_Sensitivity_Z;\r
+ uint8_t aux[2];\r
+\r
+ Lsm303dlhcMagI2CByteRead(&CTRLB, LSM_M_CRB_REG_ADDR);\r
+ Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_OUT_X_H_ADDR, 6);\r
+\r
+ /* excange Z with Y */\r
+ aux[0]=buffer[2];\r
+ aux[1]=buffer[3];\r
+\r
+ buffer[2]=buffer[4];\r
+ buffer[3]=buffer[5];\r
+\r
+ buffer[4]=aux[0];\r
+ buffer[5]=aux[1];\r
+\r
+ /** switch the sensitivity set in the CRTLB*/\r
+ switch(CTRLB & 0xE0)\r
+ {\r
+ case LSM_FS_1_3_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_1_3Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_1_3Ga;\r
+ break;\r
+ case LSM_FS_1_9_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_1_9Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_1_9Ga;\r
+ break;\r
+ case LSM_FS_2_5_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_2_5Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_2_5Ga;\r
+ break;\r
+ case LSM_FS_4_0_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_4Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_4Ga;\r
+ break;\r
+ case LSM_FS_4_7_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_4_7Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_4_7Ga;\r
+ break;\r
+ case LSM_FS_5_6_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_5_6Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_5_6Ga;\r
+ break;\r
+ case LSM_FS_8_1_GA:\r
+ LSM_Magn_Sensitivity_XY = LSM_Magn_Sensitivity_XY_8_1Ga;\r
+ LSM_Magn_Sensitivity_Z = LSM_Magn_Sensitivity_Z_8_1Ga;\r
+ break;\r
+ }\r
+\r
+ for(int i=0; i<2; i++)\r
+ {\r
+ pfData[i]=(float)((int16_t)(((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])*1000)/LSM_Magn_Sensitivity_XY;\r
+ }\r
+ pfData[2]=(float)((int16_t)(((uint16_t)buffer[4] << 8) + buffer[5])*1000)/LSM_Magn_Sensitivity_Z;\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Read LSM303DLH magnetic field output register and compute the int16_t value.\r
+* @param pnRawData: pointer to signed 16-bit buffer where to store data.\r
+* @note Despite the datasheet indications, the read axis will be stored in the passed\r
+* array in the order X,Y,Z.\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagReadRawData(int16_t* pnRawData)\r
+{\r
+ uint8_t buffer[6];\r
+ uint8_t aux[2];\r
+\r
+ Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_OUT_X_H_ADDR, 6);\r
+\r
+ /* excange Z with Y */\r
+ aux[0]=buffer[2];\r
+ aux[1]=buffer[3];\r
+\r
+ buffer[2]=buffer[4];\r
+ buffer[3]=buffer[5];\r
+\r
+ buffer[4]=aux[0];\r
+ buffer[5]=aux[1];\r
+\r
+ for(uint8_t i=0; i<3; i++)\r
+ pnRawData[i]=(int16_t)(((uint16_t)buffer[2*i] << 8) + buffer[2*i+1]);\r
+}\r
+\r
+\r
+/**\r
+* @brief Reads LSM303DLHC temperature output register, and calculate the Temperature=(out_h*256+out_l)*10/16* SENSITIVITY.\r
+* The temperature is expressed in decimal of degC. The sensitivity is 8 LSB/degC\r
+* @param pnData: pointer to a float where to store data.\r
+* @retval None\r
+*/\r
+float Lsm303dlhcMagReadTemp(void)\r
+{\r
+ uint8_t buffer[2];\r
+\r
+ /* Read register */\r
+ Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_TEMP_H_REG_ADDR, 2);\r
+\r
+ /* convert to float */\r
+ return ((float)((int16_t)(((uint16_t)buffer[0]<<8)+buffer[1])/16)/LSM_Temp_Sensitivity);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Reads LSM303DLHC temperature output register and compute the int16_t value\r
+* @param pnRawData: pointer to signed 16-bit buffer where to store data\r
+* @retval None\r
+*/\r
+int16_t Lsm303dlhcMagReadRawDataTemp(void)\r
+{\r
+ uint8_t buffer[2];\r
+\r
+ /* Read register */\r
+ Lsm303dlhcMagI2CBufferRead(buffer, LSM_M_TEMP_H_REG_ADDR, 2);\r
+\r
+ /* Return the int16 value */\r
+ return ((int16_t)(((uint16_t)buffer[0]<<8)+buffer[1])/16);\r
+\r
+}\r
+\r
+\r
+/**\r
+* @brief Gets status for magnetometer data.\r
+* @param None.\r
+* @retval LSMADataStatus: Data status in a LSMADataStatus bitfields structure.\r
+*/\r
+LSMMDataStatus Lsm303dlhcMagGetDataStatus(void)\r
+{\r
+ LSMMDataStatus xStatus;\r
+\r
+ /* Read the register content */\r
+ Lsm303dlhcAccI2CByteRead((uint8_t*)&xStatus, LSM_M_SR_REG_ADDR);\r
+\r
+ return xStatus;\r
+}\r
+\r
+\r
+/**\r
+* @brief Configures the DATA_READY IRQ of the magnetometer.\r
+* @param xNewState: New state for DATA_READY.\r
+* This parameter is a @ref LSMFunctionalState\r
+* @retval None\r
+*/\r
+void Lsm303dlhcMagDataReadyIrqConfig(LSMFunctionalState xFunctionalState)\r
+{\r
+ uint8_t cTempReg;\r
+ \r
+ Lsm303dlhcAccI2CByteRead(&cTempReg, LSM_M_SR_REG_ADDR);\r
+ \r
+ if(xFunctionalState)\r
+ cTempReg |= 0x01;\r
+ else\r
+ cTempReg &= 0xFE;\r
+ \r
+ Lsm303dlhcAccI2CByteWrite(&cTempReg, LSM_M_SR_REG_ADDR);\r
+ \r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/\r
--- /dev/null
+#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
--- /dev/null
+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
--- /dev/null
+#include "i2c.h"
+#include "FreeRTOS.h"
+#include <stm32f10x_gpio.h>
+#include <stm32f10x_rcc.h>
+#include <stm32f10x_i2c.h>
+
+#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<cNumByteToWrite ; i++)
+ {
+ /* Send the byte to be written */
+ I2C_SendData(I2C2, pcBuffer[i]);
+
+ /* Test on EV8 and clear it */
+ while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
+ }
+
+ /* Send STOP condition */
+ I2C_GenerateSTOP(I2C2, ENABLE);
+
+#ifdef FORCE_CRITICAL_SEC
+ __enable_irq();
+#endif
+
+}
--- /dev/null
+
+void iNemoI2CBufferReadDma(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cReadAddr, uint8_t cNumByteToRead);
+void iNemoI2CBufferReadPolling(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cReadAddr, uint8_t cNumByteToRead);
+void iNemoI2CBufferWriteDma(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cWriteAddr, uint8_t cNumByteToWrite);
+void iNemoI2CBufferWritePolling(uint8_t cAddr, uint8_t* pcBuffer, uint8_t cWriteAddr, uint8_t cNumByteToWrite);
--- /dev/null
+#include "spi.h"
+#include "task.h"
+#include <stm32f10x.h>
+#include <stm32f10x_gpio.h>
+#include <stm32f10x_rcc.h>
+#include <stm32f10x_spi.h>
+
+#include <stdio.h>
+
+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++;
+ }
+}
--- /dev/null
+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
--- /dev/null
+#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);
+