zhyinch
2021-01-06 88fead50b413489e979e08dfc53241e40e11515a
Merge branch '定位临近_工卡' into 定位-临近
已重命名2个文件
已添加7个文件
已修改2个文件
4159 ■■■■■ 文件已修改
.gitignore 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Drivers/ExternlDrivers/dps310.c 380 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Drivers/ExternlDrivers/dps310.h 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MDK-ARM/L051/L051.lnp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/ExternalDevices/dps310.c 380 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/ExternalDevices/dps310.h 341 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/ExternalDevices/dps368_test.c 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/ExternalDevices/lis3dh_driver.c 1995 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/ExternalDevices/lis3dh_driver.h 566 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Src/decadriver/dw_driver.c 补丁 | 查看 | 原始文档 | blame | 历史
Src/decadriver/dw_driver.h 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -4,3 +4,6 @@
*.axf
*.d
MDK-ARM/L051/L051.htm
MDK-ARM/JLinkLog.txt
*.txt
*.txt
Drivers/ExternlDrivers/dps310.c
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,380 @@
/*
 * Copyright (c) 2015-2016 Infineon Technologies AG
 *
 * Driver for Infineon DPS310 Digital Barometric Pressure Sensor
 *
 *
 */
#include "dps310.h"
/* Meaningful Default Configuration */
#define     IFX_DPS310_TEMPERATURE_OSR                  OSR_2
#define     IFX_DPS310_PRESSURE_OSR                     OSR_64
#define     IFX_DPS310_TEMPERATURE_MR                   TMP_MR_4
#define     IFX_DPS310_PRESSURE_MR                      PM_MR_8
/**/
static dps310_scaling_coeffs_e
dps310_get_scaling_coef (dps310_osr_e osr)
{
        dps310_scaling_coeffs_e scaling_coeff;
        switch (osr){
              case OSR_1:
                    scaling_coeff = OSR_SF_1;
                    break;
              case OSR_2:
                    scaling_coeff = OSR_SF_2;
                    break;
              case OSR_4:
                    scaling_coeff = OSR_SF_4;
                    break;
              case OSR_8:
                    scaling_coeff = OSR_SF_8;
                    break;
              case OSR_16:
                    scaling_coeff = OSR_SF_16;
                    break;
              case OSR_32:
                    scaling_coeff = OSR_SF_32;
                    break;
              case OSR_64:
                    scaling_coeff = OSR_SF_64;
                    break;
              case OSR_128:
                    scaling_coeff = OSR_SF_128;
                    break;
              default:
                     scaling_coeff = OSR_SF_1;
                     break;
        }
        return scaling_coeff;
}
static int dps310_read_calib_coeffs(struct dps310_state *drv_state)
{
        s32 ret;
        u8 read_buffer[IFX_DPS310_COEF_LEN] = {0};
        if (drv_state == NULL)
            return -EINVAL;
        ret =  drv_state->io->read_block((u8)IFX_DPS310_COEF_REG_ADDR,
                                 (u8)IFX_DPS310_COEF_LEN, read_buffer);
        if ( ret != IFX_DPS310_COEF_LEN )
            return ret;
        drv_state->calib_coeffs.C0 = (read_buffer[0] << 4) + ((read_buffer[1] >>4) & 0x0F);
        if(drv_state->calib_coeffs.C0 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C0 = drv_state->calib_coeffs.C0 - POW_2_12;
        drv_state->calib_coeffs.C1 = (read_buffer[2] + ((read_buffer[1] & 0x0F)<<8));
        if(drv_state->calib_coeffs.C1 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C1 = drv_state->calib_coeffs.C1 - POW_2_12;
        drv_state->calib_coeffs.C00 = ((read_buffer[4]<<4) + (read_buffer[3]<<12)) + ((read_buffer[5]>>4) & 0x0F);
        if(drv_state->calib_coeffs.C00 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C00 = drv_state->calib_coeffs.C00 -POW_2_20;
        drv_state->calib_coeffs.C10 = ((read_buffer[5] & 0x0F)<<16) + read_buffer[7] + (read_buffer[6]<<8);
        if(drv_state->calib_coeffs.C10 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C10 = drv_state->calib_coeffs.C10 - POW_2_20;
        drv_state->calib_coeffs.C01 = (read_buffer[9] + (read_buffer[8]<<8));
        if(drv_state->calib_coeffs.C01 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C01 = drv_state->calib_coeffs.C01 - POW_2_16;
        drv_state->calib_coeffs.C11 = (read_buffer[11] + (read_buffer[10]<<8));
        if(drv_state->calib_coeffs.C11 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C11 = drv_state->calib_coeffs.C11 - POW_2_16;
        drv_state->calib_coeffs.C20 = (read_buffer[13] + (read_buffer[12]<<8));
        if(drv_state->calib_coeffs.C20 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C20 = drv_state->calib_coeffs.C20 - POW_2_16;
        drv_state->calib_coeffs.C21 = (read_buffer[15] + (read_buffer[14]<<8));
        if(drv_state->calib_coeffs.C21 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C21 = drv_state->calib_coeffs.C21 - POW_2_16;
        drv_state->calib_coeffs.C30 = (read_buffer[17] + (read_buffer[16]<<8));
        if(drv_state->calib_coeffs.C30 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C30 = drv_state->calib_coeffs.C30 - POW_2_16;
        /* lets see which temperature diode is used for calibration and update state accordingly*/
        ret = drv_state->io->read_byte(IFX_DPS310_TMP_COEF_SRCE_REG_ADDR);
        if (ret < 0){
                return -EIO;
        }
        if ((ret >> IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK) & 1 ){
                drv_state->tmp_ext = TMP_EXT_MEMS;
        }
        else{
                drv_state->tmp_ext = TMP_EXT_ASIC;
        }
        return 0;
}
int dps310_resume(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
            return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                        (u8)DPS310_MODE_BACKGROUND_ALL);
        if (ret < 0)
                return -EIO;
        drv_state->dev_mode = DPS310_MODE_BACKGROUND_ALL;
        return 0;
}
int dps310_standby(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
          return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                       (u8)DPS310_MODE_IDLE);
        if (ret < 0)
                return -EIO;
        drv_state->dev_mode = DPS310_MODE_IDLE;
        return 0;
}
int dps310_config(struct dps310_state *drv_state,
                            dps310_osr_e osr_temp,
                            dps310_tmp_rate_e mr_temp,
                            dps310_osr_e osr_press,
                            dps310_pm_rate_e mr_press,
                            dps310_temperature_src_e temp_src)
{
        s32 ret;
        u8  config;
        if (drv_state == NULL)
            return -EINVAL;
       /* configure temperature measurements first*/
       /*Prepare a configuration word for TMP_CFG register*/
        config = (u8) temp_src;
        /*First Set the TMP_RATE[2:0] -> 6:4 */
        config |= ((u8)mr_temp);
       /*Set the TMP_PRC[3:0] -> 2:0 */
        config |= ((u8)osr_temp);
        ret = drv_state->io->write_byte(IFX_DPS310_TMP_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
        /*Prepare a configuration word for PRS_CFG register*/
        /*First Set the PM_RATE[2:0] -> 6:4 */
        config = (u8) ( 0x00 ) | ((u8)mr_press);
        /*Set the PM_PRC[3:0] -> 3:0 */
        config |= ((u8)osr_press);
        ret = drv_state->io->write_byte(IFX_DPS310_PRS_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
        /* always take configuration word from state*/
        config = drv_state->cfg_word;
        /*If oversampling rate for temperature is greater than 8 times, then set TMP_SHIFT bit in CFG_REG */
        if ((u8)osr_temp > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL;
        }
        /*If oversampling rate for pressure is greater than 8 times, then set P_SHIFT bit in CFG_REG */
        if ((u8)osr_press > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL;
        }
        /* write CFG_REG */
        ret =  drv_state->io->write_byte(IFX_DPS310_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
       /*Update state accordingly with proper scaling factors based on oversampling rates*/
        drv_state->tmp_osr_scale_coeff = dps310_get_scaling_coef(osr_temp);
        drv_state->prs_osr_scale_coeff = dps310_get_scaling_coef(osr_press);
        drv_state->press_mr = mr_press;
        drv_state->temp_mr  = mr_temp;
        drv_state->temp_osr = osr_temp;
        drv_state->press_osr = osr_press;
        drv_state->tmp_ext  = temp_src;
        return 0;
}
int dps310_get_processed_data (struct dps310_state *drv_state,
                                      f64 *pressure,
                                      f64 *temperature)
{
        s32    ret;
        u8     read_buffer[IFX_DPS310_PSR_TMP_READ_LEN] = {0};
        f64    press_raw;
        f64    temp_raw;
        f64 temp_scaled;
        f64 temp_final;
        f64 press_scaled;
        f64 press_final;
        if (drv_state == NULL)
            return -EINVAL;
        ret = drv_state->io->read_block(IFX_DPS310_PSR_TMP_READ_REG_ADDR,
                              IFX_DPS310_PSR_TMP_READ_LEN,
                              read_buffer);
        if (ret < IFX_DPS310_PSR_TMP_READ_LEN)
            return -EINVAL;
        press_raw = (read_buffer[2]) + (read_buffer[1]<<8) + (read_buffer[0] <<16);
        temp_raw  = (read_buffer[5]) + (read_buffer[4]<<8) + (read_buffer[3] <<16);
        if(temp_raw > POW_2_23_MINUS_1){
            temp_raw = temp_raw - POW_2_24;
        }
        if(press_raw > POW_2_23_MINUS_1){
            press_raw = press_raw - POW_2_24;
        }
        temp_scaled = (double)temp_raw / (double) (drv_state->tmp_osr_scale_coeff);
        temp_final =  (drv_state->calib_coeffs.C0 /2.0f) + drv_state->calib_coeffs.C1 * temp_scaled ;
        press_scaled = (double) press_raw / drv_state->prs_osr_scale_coeff;
        press_final = drv_state->calib_coeffs.C00 +
                      press_scaled *  (  drv_state->calib_coeffs.C10 + press_scaled *
                      ( drv_state->calib_coeffs.C20 + press_scaled * drv_state->calib_coeffs.C30 )  ) +
                      temp_scaled * drv_state->calib_coeffs.C01 +
                      temp_scaled * press_scaled * ( drv_state->calib_coeffs.C11 +
                                                      press_scaled * drv_state->calib_coeffs.C21 );
        press_final = press_final * 0.01f;    //to convert it into mBar
        *temperature = temp_final;
        *pressure    = press_final;  //press_final;
        return 0;
}
int dps310_init(struct dps310_state *drv_state, dps310_bus_connection *io)
{
        s32 ret;
        if (!drv_state){
            return -EINVAL;
        }
        if (!io){
            return -EINVAL;
        }
        drv_state->cfg_word = 0;
        drv_state->enable = 0;
        /*first verify chip by reading product and rev id*/
        ret = io->read_byte(IFX_DPS310_PROD_REV_ID_REG_ADDR);
        if (ret < 0){
            ret = -EIO;
                goto err_handler_iio;
        }
        if (ret != IFX_DSPS310_PROD_REV_ID_VAL){
            ret = -EINVAL;
            goto err_handler_iio;
        }
        /* attach bus connection instance to state*/
        drv_state->io = io;
        /* from here wait for about 40ms till calibration coefficients become available*/
        if (drv_state->io->delayms != NULL)
            drv_state->io->delayms(40);
        /* read now the calibration coeffs, temperature coef source and store in driver state*/
        ret = dps310_read_calib_coeffs(drv_state);
        if (ret < 0){
                goto err_handler_iio;
        }
        /* Now apply ADC Temperature gain settings*/
        /* First write valid signature on 0x0e and 0x0f
         * to unlock address 0x62 */
        drv_state->io->write_byte((u8)0x0e,(u8)0xa5);
        drv_state->io->write_byte((u8)0x0f,(u8)0x96);
        /*Then update high gain value for Temperature*/
        drv_state->io->write_byte((u8)0x62,(u8)0x02);
        /*Finally lock back the location 0x62*/
        drv_state->io->write_byte((u8)0x0e,(u8)0x00);
        drv_state->io->write_byte((u8)0x0f,(u8)0x00);
        /* configure sensor for default ODR settings*/
        ret = dps310_config(drv_state,
                            IFX_DPS310_TEMPERATURE_OSR,
                            IFX_DPS310_TEMPERATURE_MR,
                            IFX_DPS310_PRESSURE_OSR,
                            IFX_DPS310_PRESSURE_MR,
                            drv_state->tmp_ext);
        if (ret < 0){
            goto err_handler_iio;
        }
        /* activate sensor*/
        ret = dps310_resume(drv_state);
        if (ret < 0){
            goto err_handler_iio;
        }
        return 0;
err_handler_iio:
        return ret;
}
Drivers/ExternlDrivers/dps310.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,343 @@
/*
 * Copyright (c) 2015-2016 Infineon Technologies AG
 *
 * Driver for Infineon DPS310 Digital Barometric Pressure Sensor
 *
 *
 */
#ifndef DPS310_H_INCLUDED
#define DPS310_H_INCLUDED
/* Attributes: Product identification and version */
#define     VENDOR_NAME                                 "Infineon"
#define     DRIVER_NAME                                 "IFXDD"
#define     DEVICE_NAME                                 "Digital Barometric Pressure Sensor"
#define     DEVICE_MODEL_NAME                           "DPS310"
#define     DEVICE_HW_VERSION                           1.0
#define     DRIVER_VERSION                              1.0
#define     DEVICE_PROD_REV_ID                          0x10
/* Attributes: Device performance :Pressure Sensing */
#define     IFX_DPS310_PROD_REV_ID_REG_ADDR             0x0D
#define     IFX_DPS310_PROD_REV_ID_LEN                  1
#define     IFX_DSPS310_PROD_REV_ID_VAL                 DEVICE_PROD_REV_ID
#define     IFX_DPS310_SOFT_RESET_REG_ADDR              0x0C
#define     IFX_DPS310_SOFT_RESET_REG_DATA              0x09
#define     IFX_DPS310_SOFT_RESET_REG_LEN               1
#define     IFX_DPS310_SOFT_RESET_VERIFY_REG_ADDR       0x06
#define     IFX_DPS310_COEF_REG_ADDR                    0x10
#define     IFX_DPS310_COEF_LEN                         18    // Length in bytes
#define     IFX_DPS310_TMP_COEF_SRCE_REG_ADDR           0x28
#define     IFX_DPS310_TMP_COEF_SRCE_REG_LEN            1    // Length in bytes
#define     IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK       7    // Length in bytes
#define     IFX_DPS310_PSR_TMP_READ_REG_ADDR            0x00
#define     IFX_DPS310_PSR_TMP_READ_LEN                 6
#define     IFX_DPS310_PRS_CFG_REG_ADDR                 0x06
#define     IFX_DPS310_PRS_CFG_REG_LEN                  1
#define     IFX_DPS310_TMP_CFG_REG_ADDR                 0x07
#define     IFX_DPS310_TMP_CFG_REG_LEN                  1
#define     IFX_DPS310_MEAS_CFG_REG_ADDR                0x08
#define     IFX_DPS310_MEAS_CFG_REG_LEN                 1
#define     IFX_DPS310_CFG_REG_ADDR                     0x09
#define     IFX_DPS310_CFG_REG_LEN                      1
#define     IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL         0x08
#define     IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL         0x04
#define     IFX_DPS310_FIFO_READ_REG_ADDR               0x00
#define     IFX_DPS310_FIFO_REG_READ_LEN                3
#define     IFX_DPS310_FIFO_BYTES_PER_ENTRY             3
#define     IFX_DPS310_FIFO_FLUSH_REG_ADDR              0x0C
#define     IFX_DPS310_FIFO_FLUSH_REG_VAL               0b1000000U
#define     IFX_DPS310_CFG_SPI_MODE_POS                 0
#define     IFX_DPS310_CFG_SPI_MODE_3_WIRE_VAL          1
#define     IFX_DPS310_CFG_SPI_MODE_4_WIRE_VAL          0
#define     IFX_DPS310_CFG_FIFO_ENABLE_POS              1
#define     IFX_DPS310_CFG_FIFO_ENABLE_VAL              1
#define     IFX_DPS310_CFG_FIFO_DISABLE_VAL             0
#define     IFX_DPS310_CFG_INTR_PRS_ENABLE_POS          4
#define     IFX_DPS310_CFG_INTR_PRS_ENABLE_VAL          1U
#define     IFX_DPS310_CFG_INTR_PRS_DISABLE_VAL         0U
#define     IFX_DPS310_CFG_INTR_TEMP_ENABLE_POS         5
#define     IFX_DPS310_CFG_INTR_TEMP_ENABLE_VAL         1U
#define     IFX_DPS310_CFG_INTR_TEMP_DISABLE_VAL        0U
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_ENABLE_POS    6
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_ENABLE_VAL    1U
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_DISABLE_VAL   0U
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_SEL_POS       7
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_ACTIVE_H      1U
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_ACTIVE_L      0U
#define     IFX_DPS310_INTR_SOURCE_PRESSURE             0
#define     IFX_DPS310_INTR_SOURCE_TEMPERATURE          1
#define     IFX_DPS310_INTR_SOURCE_BOTH                 2
#define     IFX_DPS310_INTR_STATUS_REG_ADDR             0x0A
#define     IFX_DPS310_INTR_STATUS_REG_LEN              1
#define     IFX_DPS310_INTR_DISABLE_ALL                (uint8_t)0b10001111
#define     EINVAL                                      1
#define     EIO                                         2
#ifndef NULL
#define     NULL                                        ((void*)0)
#endif // NULL
/* _______________________________________________________ */
#define POW_2_23_MINUS_1    0x7FFFFF   //implies 2^23-1
#define POW_2_24            0x1000000
#define POW_2_15_MINUS_1    0x7FFF
#define POW_2_16            0x10000
#define POW_2_11_MINUS_1    0x7FF
#define POW_2_12            0x1000
#define POW_2_20            0x100000
#define POW_2_19_MINUS_1    524287
/* _______________________________________________________ */
/*Some aliases*/
typedef unsigned char       u8;
typedef char                s8;
typedef unsigned short      u16;
typedef short               s16;
typedef long                s32;
typedef    long long           s64;
typedef    unsigned long       u32;
typedef    unsigned long long  u64;
typedef float               f32;
typedef double              f64;
typedef u8                  bool;
#define false               0
#define true                1
/* Struct to hold calibration coefficients read from device*/
typedef struct
{
  /* calibration registers */
  s16     C0;    // 12bit
  s16     C1;    // 12bit
  s32    C00;    // 20bit
  s32   C10;    // 20bit
  s16     C01;    // 16bit
  s16    C11;    // 16bit
  s16    C20;    // 16bit
  s16    C21;    // 16bit
  s16    C30;    // 16bit
}dps310_cal_coeff_regs_s;
/* enum for seeting/getting device operating mode*/
typedef enum
{
  DPS310_MODE_IDLE                   =  0b00000000,
  DPS310_MODE_COMMAND_PRESSURE       =  0b00000001,
  DPS310_MODE_COMMAND_TEMPERATURE    =  0b00000010,
  DPS310_MODE_BACKGROUND_PRESSURE    =  0b00000101,
  DPS310_MODE_BACKGROUND_TEMPERATURE =  0b00000110,
  DPS310_MODE_BACKGROUND_ALL         =  0b00000111,
}dps310_operating_modes_e;
/* enum of scaling coefficients either Kp or Kt*/
typedef enum
{
    OSR_SF_1   = 524288,
    OSR_SF_2   = 1572864,
    OSR_SF_4   = 3670016,
    OSR_SF_8   = 7864320,
    OSR_SF_16  = 253952,
    OSR_SF_32  = 516096,
    OSR_SF_64  = 1040384,
    OSR_SF_128 = 2088960,
} dps310_scaling_coeffs_e;
/* enum of oversampling rates for pressure and temperature*/
typedef enum
{
    OSR_1   = 0b00000000,
    OSR_2   = 0b00000001,
    OSR_4   = 0b00000010,
    OSR_8   = 0b00000011,
    OSR_16  = 0b00000100,
    OSR_32  = 0b00000101,
    OSR_64  = 0b00000110,
    OSR_128 = 0b00000111,
} dps310_osr_e;
/* enum of measurement rates for pressure*/
typedef enum
{
    PM_MR_1   = 0b00000000,
    PM_MR_2   = 0b00010000,
    PM_MR_4   = 0b00100000,
    PM_MR_8   = 0b00110000,
    PM_MR_16  = 0b01000000,
    PM_MR_32  = 0b01010000,
    PM_MR_64  = 0b01100000,
    PM_MR_128 = 0b01110000,
} dps310_pm_rate_e;
/* enum of measurement rates for temperature*/
typedef enum
{
    TMP_MR_1   = 0b00000000,
    TMP_MR_2   = 0b00010000,
    TMP_MR_4   = 0b00100000,
    TMP_MR_8   = 0b00110000,
    TMP_MR_16  = 0b01000000,
    TMP_MR_32  = 0b01010000,
    TMP_MR_64  = 0b01100000,
    TMP_MR_128 = 0b01110000,
} dps310_tmp_rate_e;
/* enum of oversampling and measurement rates*/
typedef enum
{
    TMP_EXT_ASIC = 0x00,
    TMP_EXT_MEMS = 0x80,
}dps310_temperature_src_e;
/*Please update callbacks for bus communication
* callbacks are protocol agnostic/abstract so
* as to wrap around I2C or SPI low level protocols
*/
typedef struct {
        /*Provide a wrapper for single byte read/write and multi byte read
        * all callbacks return negative values to indicate error
        * however, read_byte must return the content in case of successful read
        * and read_block shall return number of bytes read successfully
        * For write_byte non zero return value shall indicate successful write
        */
        s16 (*read_byte)(u8 address);
        s16 (*read_block)(u8 address, u8 length, u8 *read_buffer);
        s16 (*write_byte)(u8 address, u8 data);
        /*It is expected to provide a wrapper for incorporating delay
        * the delay shall be in milliseconds. This is required as
        * after powering up the sensor, it takes 40ms until fused
        * calibration coefficients are ready to read.
        * in case this delay is handled appropriately by caller by other mechanism
        * please set this callback to NULL
        */
        void (*delayms)(u8 duration);
}dps310_bus_connection;
struct dps310_state {
        dps310_scaling_coeffs_e   tmp_osr_scale_coeff;                    /* Temperature scaling coefficient*/
        dps310_scaling_coeffs_e   prs_osr_scale_coeff;                    /* Pressure scaling coefficient*/
        dps310_cal_coeff_regs_s   calib_coeffs;                           /* Calibration coefficients index */
        dps310_operating_modes_e  dev_mode;                               /* Current operating mode of device */
        dps310_pm_rate_e          press_mr;                  /* Current measurement readout rate (ODR) for pressure */
        dps310_tmp_rate_e         temp_mr;                  /* Current measurement readout rate (ODR) for temperature */
        dps310_osr_e              temp_osr;                  /* Current oversampling rate (OSR) for temperature */
        dps310_osr_e              press_osr;                  /* Current oversampling rate (OSR) for pressure */
        dps310_temperature_src_e  tmp_ext;                                /* Temperature ASIC or MEMS. Should always be set MEMS*/
        u8                        cfg_word;                               /* Keep the contents of CFG register as it gets configured
                                                                            to avoid excessive bus transactions */
    bool                           enable;
    dps310_bus_connection         *io;                                    /*To access bus communication call backs */
};
/* public function prototypes */
int
dps310_init
(
 struct dps310_state *drv_state,
 dps310_bus_connection *io
);
int dps310_get_processed_data
(
 struct dps310_state *drv_state,
 f64 *pressure,
 f64 *temperature
 );
int
dps310_config
(
 struct dps310_state *drv_state,
 dps310_osr_e osr_temp,
 dps310_tmp_rate_e mr_temp,
 dps310_osr_e osr_press,
 dps310_pm_rate_e mr_press,
 dps310_temperature_src_e temp_src
 );
int
dps310_standby
(
 struct dps310_state *drv_state
);
int
dps310_resume
(
 struct dps310_state *drv_state
);
#endif // DPS310_H_INCLUDED
MDK-ARM/L051/L051.lnp
@@ -1,10 +1,12 @@
--cpu Cortex-M0+
"l051\startup_stm32l051xx.o"
"l051\lis3dh_driver.o"
"l051\deca_device.o"
"l051\deca_params_init.o"
"l051\deca_range_tables.o"
"l051\dw_driver.o"
"l051\lis3dh_driver.o"
"l051\dps310.o"
"l051\dps368_test.o"
"l051\spi.o"
"l051\adc.o"
"l051\usart.o"
Src/ExternalDevices/dps310.c
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,380 @@
/*
 * Copyright (c) 2015-2016 Infineon Technologies AG
 *
 * Driver for Infineon DPS310 Digital Barometric Pressure Sensor
 *
 *
 */
#include "dps310.h"
/* Meaningful Default Configuration */
#define     IFX_DPS310_TEMPERATURE_OSR                  OSR_2
#define     IFX_DPS310_PRESSURE_OSR                     OSR_64
#define     IFX_DPS310_TEMPERATURE_MR                   TMP_MR_4
#define     IFX_DPS310_PRESSURE_MR                      PM_MR_8
/**/
static dps310_scaling_coeffs_e
dps310_get_scaling_coef (dps310_osr_e osr)
{
        dps310_scaling_coeffs_e scaling_coeff;
        switch (osr){
              case OSR_1:
                    scaling_coeff = OSR_SF_1;
                    break;
              case OSR_2:
                    scaling_coeff = OSR_SF_2;
                    break;
              case OSR_4:
                    scaling_coeff = OSR_SF_4;
                    break;
              case OSR_8:
                    scaling_coeff = OSR_SF_8;
                    break;
              case OSR_16:
                    scaling_coeff = OSR_SF_16;
                    break;
              case OSR_32:
                    scaling_coeff = OSR_SF_32;
                    break;
              case OSR_64:
                    scaling_coeff = OSR_SF_64;
                    break;
              case OSR_128:
                    scaling_coeff = OSR_SF_128;
                    break;
              default:
                     scaling_coeff = OSR_SF_1;
                     break;
        }
        return scaling_coeff;
}
static int dps310_read_calib_coeffs(struct dps310_state *drv_state)
{
        s32 ret;
        u8 read_buffer[IFX_DPS310_COEF_LEN] = {0};
        if (drv_state == NULL)
            return -EINVAL;
        ret =  drv_state->io->read_block((u8)IFX_DPS310_COEF_REG_ADDR,
                                 (u8)IFX_DPS310_COEF_LEN, read_buffer);
        if ( ret != IFX_DPS310_COEF_LEN )
            return ret;
        drv_state->calib_coeffs.C0 = (read_buffer[0] << 4) + ((read_buffer[1] >>4) & 0x0F);
        if(drv_state->calib_coeffs.C0 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C0 = drv_state->calib_coeffs.C0 - POW_2_12;
        drv_state->calib_coeffs.C1 = (read_buffer[2] + ((read_buffer[1] & 0x0F)<<8));
        if(drv_state->calib_coeffs.C1 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C1 = drv_state->calib_coeffs.C1 - POW_2_12;
        drv_state->calib_coeffs.C00 = ((read_buffer[4]<<4) + (read_buffer[3]<<12)) + ((read_buffer[5]>>4) & 0x0F);
        if(drv_state->calib_coeffs.C00 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C00 = drv_state->calib_coeffs.C00 -POW_2_20;
        drv_state->calib_coeffs.C10 = ((read_buffer[5] & 0x0F)<<16) + read_buffer[7] + (read_buffer[6]<<8);
        if(drv_state->calib_coeffs.C10 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C10 = drv_state->calib_coeffs.C10 - POW_2_20;
        drv_state->calib_coeffs.C01 = (read_buffer[9] + (read_buffer[8]<<8));
        if(drv_state->calib_coeffs.C01 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C01 = drv_state->calib_coeffs.C01 - POW_2_16;
        drv_state->calib_coeffs.C11 = (read_buffer[11] + (read_buffer[10]<<8));
        if(drv_state->calib_coeffs.C11 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C11 = drv_state->calib_coeffs.C11 - POW_2_16;
        drv_state->calib_coeffs.C20 = (read_buffer[13] + (read_buffer[12]<<8));
        if(drv_state->calib_coeffs.C20 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C20 = drv_state->calib_coeffs.C20 - POW_2_16;
        drv_state->calib_coeffs.C21 = (read_buffer[15] + (read_buffer[14]<<8));
        if(drv_state->calib_coeffs.C21 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C21 = drv_state->calib_coeffs.C21 - POW_2_16;
        drv_state->calib_coeffs.C30 = (read_buffer[17] + (read_buffer[16]<<8));
        if(drv_state->calib_coeffs.C30 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C30 = drv_state->calib_coeffs.C30 - POW_2_16;
        /* lets see which temperature diode is used for calibration and update state accordingly*/
        ret = drv_state->io->read_byte(IFX_DPS310_TMP_COEF_SRCE_REG_ADDR);
        if (ret < 0){
                return -EIO;
        }
        if ((ret >> IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK) & 1 ){
                drv_state->tmp_ext = TMP_EXT_MEMS;
        }
        else{
                drv_state->tmp_ext = TMP_EXT_ASIC;
        }
        return 0;
}
int dps310_resume(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
            return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                        (u8)DPS310_MODE_BACKGROUND_ALL);
        if (ret < 0)
                return -EIO;
        drv_state->dev_mode = DPS310_MODE_BACKGROUND_ALL;
        return 0;
}
int dps310_standby(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
          return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                       (u8)DPS310_MODE_IDLE);
        if (ret < 0)
                return -EIO;
        drv_state->dev_mode = DPS310_MODE_IDLE;
        return 0;
}
int dps310_config(struct dps310_state *drv_state,
                            dps310_osr_e osr_temp,
                            dps310_tmp_rate_e mr_temp,
                            dps310_osr_e osr_press,
                            dps310_pm_rate_e mr_press,
                            dps310_temperature_src_e temp_src)
{
        s32 ret;
        u8  config;
        if (drv_state == NULL)
            return -EINVAL;
       /* configure temperature measurements first*/
       /*Prepare a configuration word for TMP_CFG register*/
        config = (u8) temp_src;
        /*First Set the TMP_RATE[2:0] -> 6:4 */
        config |= ((u8)mr_temp);
       /*Set the TMP_PRC[3:0] -> 2:0 */
        config |= ((u8)osr_temp);
        ret = drv_state->io->write_byte(IFX_DPS310_TMP_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
        /*Prepare a configuration word for PRS_CFG register*/
        /*First Set the PM_RATE[2:0] -> 6:4 */
        config = (u8) ( 0x00 ) | ((u8)mr_press);
        /*Set the PM_PRC[3:0] -> 3:0 */
        config |= ((u8)osr_press);
        ret = drv_state->io->write_byte(IFX_DPS310_PRS_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
        /* always take configuration word from state*/
        config = drv_state->cfg_word;
        /*If oversampling rate for temperature is greater than 8 times, then set TMP_SHIFT bit in CFG_REG */
        if ((u8)osr_temp > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL;
        }
        /*If oversampling rate for pressure is greater than 8 times, then set P_SHIFT bit in CFG_REG */
        if ((u8)osr_press > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL;
        }
        /* write CFG_REG */
        ret =  drv_state->io->write_byte(IFX_DPS310_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
       /*Update state accordingly with proper scaling factors based on oversampling rates*/
        drv_state->tmp_osr_scale_coeff = dps310_get_scaling_coef(osr_temp);
        drv_state->prs_osr_scale_coeff = dps310_get_scaling_coef(osr_press);
        drv_state->press_mr = mr_press;
        drv_state->temp_mr  = mr_temp;
        drv_state->temp_osr = osr_temp;
        drv_state->press_osr = osr_press;
        drv_state->tmp_ext  = temp_src;
        return 0;
}
int dps310_get_processed_data (struct dps310_state *drv_state,
                                      f64 *pressure,
                                      f64 *temperature)
{
        s32    ret;
        u8     read_buffer[IFX_DPS310_PSR_TMP_READ_LEN] = {0};
        f64    press_raw;
        f64    temp_raw;
        f64 temp_scaled;
        f64 temp_final;
        f64 press_scaled;
        f64 press_final;
        if (drv_state == NULL)
            return -EINVAL;
        ret = drv_state->io->read_block(IFX_DPS310_PSR_TMP_READ_REG_ADDR,
                              IFX_DPS310_PSR_TMP_READ_LEN,
                              read_buffer);
        if (ret < IFX_DPS310_PSR_TMP_READ_LEN)
            return -EINVAL;
        press_raw = (read_buffer[2]) + (read_buffer[1]<<8) + (read_buffer[0] <<16);
        temp_raw  = (read_buffer[5]) + (read_buffer[4]<<8) + (read_buffer[3] <<16);
        if(temp_raw > POW_2_23_MINUS_1){
            temp_raw = temp_raw - POW_2_24;
        }
        if(press_raw > POW_2_23_MINUS_1){
            press_raw = press_raw - POW_2_24;
        }
        temp_scaled = (double)temp_raw / (double) (drv_state->tmp_osr_scale_coeff);
        temp_final =  (drv_state->calib_coeffs.C0 /2.0f) + drv_state->calib_coeffs.C1 * temp_scaled ;
        press_scaled = (double) press_raw / drv_state->prs_osr_scale_coeff;
        press_final = drv_state->calib_coeffs.C00 +
                      press_scaled *  (  drv_state->calib_coeffs.C10 + press_scaled *
                      ( drv_state->calib_coeffs.C20 + press_scaled * drv_state->calib_coeffs.C30 )  ) +
                      temp_scaled * drv_state->calib_coeffs.C01 +
                      temp_scaled * press_scaled * ( drv_state->calib_coeffs.C11 +
                                                      press_scaled * drv_state->calib_coeffs.C21 );
        press_final = press_final * 0.01f;    //to convert it into mBar
        *temperature = temp_final;
        *pressure    = press_final;  //press_final;
        return 0;
}
int dps310_init(struct dps310_state *drv_state, dps310_bus_connection *io)
{
        s32 ret;
        if (!drv_state){
            return -EINVAL;
        }
        if (!io){
            return -EINVAL;
        }
        drv_state->cfg_word = 0;
        drv_state->enable = 0;
        /*first verify chip by reading product and rev id*/
        ret = io->read_byte(IFX_DPS310_PROD_REV_ID_REG_ADDR);
        if (ret < 0){
            ret = -EIO;
                goto err_handler_iio;
        }
        if (ret != IFX_DSPS310_PROD_REV_ID_VAL){
            ret = -EINVAL;
            goto err_handler_iio;
        }
        /* attach bus connection instance to state*/
        drv_state->io = io;
        /* from here wait for about 40ms till calibration coefficients become available*/
        if (drv_state->io->delayms != NULL)
            drv_state->io->delayms(40);
        /* read now the calibration coeffs, temperature coef source and store in driver state*/
        ret = dps310_read_calib_coeffs(drv_state);
        if (ret < 0){
                goto err_handler_iio;
        }
        /* Now apply ADC Temperature gain settings*/
        /* First write valid signature on 0x0e and 0x0f
         * to unlock address 0x62 */
        drv_state->io->write_byte((u8)0x0e,(u8)0xa5);
        drv_state->io->write_byte((u8)0x0f,(u8)0x96);
        /*Then update high gain value for Temperature*/
        drv_state->io->write_byte((u8)0x62,(u8)0x02);
        /*Finally lock back the location 0x62*/
        drv_state->io->write_byte((u8)0x0e,(u8)0x00);
        drv_state->io->write_byte((u8)0x0f,(u8)0x00);
        /* configure sensor for default ODR settings*/
        ret = dps310_config(drv_state,
                            IFX_DPS310_TEMPERATURE_OSR,
                            IFX_DPS310_TEMPERATURE_MR,
                            IFX_DPS310_PRESSURE_OSR,
                            IFX_DPS310_PRESSURE_MR,
                            drv_state->tmp_ext);
        if (ret < 0){
            goto err_handler_iio;
        }
        /* activate sensor*/
        ret = dps310_resume(drv_state);
        if (ret < 0){
            goto err_handler_iio;
        }
        return 0;
err_handler_iio:
        return ret;
}
Src/ExternalDevices/dps310.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,341 @@
/*
 * Copyright (c) 2015-2016 Infineon Technologies AG
 *
 * Driver for Infineon DPS310 Digital Barometric Pressure Sensor
 *
 *
 */
#ifndef DPS310_H_INCLUDED
#define DPS310_H_INCLUDED
/* Attributes: Product identification and version */
#define     VENDOR_NAME                                 "Infineon"
#define     DRIVER_NAME                                 "IFXDD"
#define     DEVICE_NAME                                 "Digital Barometric Pressure Sensor"
#define     DEVICE_MODEL_NAME                           "DPS310"
#define     DEVICE_HW_VERSION                           1.0
#define     DRIVER_VERSION                              1.0
#define     DEVICE_PROD_REV_ID                          0x10
/* Attributes: Device performance :Pressure Sensing */
#define     IFX_DPS310_PROD_REV_ID_REG_ADDR             0x0D
#define     IFX_DPS310_PROD_REV_ID_LEN                  1
#define     IFX_DSPS310_PROD_REV_ID_VAL                 DEVICE_PROD_REV_ID
#define     IFX_DPS310_SOFT_RESET_REG_ADDR              0x0C
#define     IFX_DPS310_SOFT_RESET_REG_DATA              0x09
#define     IFX_DPS310_SOFT_RESET_REG_LEN               1
#define     IFX_DPS310_SOFT_RESET_VERIFY_REG_ADDR       0x06
#define     IFX_DPS310_COEF_REG_ADDR                    0x10
#define     IFX_DPS310_COEF_LEN                         18    // Length in bytes
#define     IFX_DPS310_TMP_COEF_SRCE_REG_ADDR           0x28
#define     IFX_DPS310_TMP_COEF_SRCE_REG_LEN            1    // Length in bytes
#define     IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK       7    // Length in bytes
#define     IFX_DPS310_PSR_TMP_READ_REG_ADDR            0x00
#define     IFX_DPS310_PSR_TMP_READ_LEN                 6
#define     IFX_DPS310_PRS_CFG_REG_ADDR                 0x06
#define     IFX_DPS310_PRS_CFG_REG_LEN                  1
#define     IFX_DPS310_TMP_CFG_REG_ADDR                 0x07
#define     IFX_DPS310_TMP_CFG_REG_LEN                  1
#define     IFX_DPS310_MEAS_CFG_REG_ADDR                0x08
#define     IFX_DPS310_MEAS_CFG_REG_LEN                 1
#define     IFX_DPS310_CFG_REG_ADDR                     0x09
#define     IFX_DPS310_CFG_REG_LEN                      1
#define     IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL         0x08
#define     IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL         0x04
#define     IFX_DPS310_FIFO_READ_REG_ADDR               0x00
#define     IFX_DPS310_FIFO_REG_READ_LEN                3
#define     IFX_DPS310_FIFO_BYTES_PER_ENTRY             3
#define     IFX_DPS310_FIFO_FLUSH_REG_ADDR              0x0C
#define     IFX_DPS310_FIFO_FLUSH_REG_VAL               0b1000000U
#define     IFX_DPS310_CFG_SPI_MODE_POS                 0
#define     IFX_DPS310_CFG_SPI_MODE_3_WIRE_VAL          1
#define     IFX_DPS310_CFG_SPI_MODE_4_WIRE_VAL          0
#define     IFX_DPS310_CFG_FIFO_ENABLE_POS              1
#define     IFX_DPS310_CFG_FIFO_ENABLE_VAL              1
#define     IFX_DPS310_CFG_FIFO_DISABLE_VAL             0
#define     IFX_DPS310_CFG_INTR_PRS_ENABLE_POS          4
#define     IFX_DPS310_CFG_INTR_PRS_ENABLE_VAL          1U
#define     IFX_DPS310_CFG_INTR_PRS_DISABLE_VAL         0U
#define     IFX_DPS310_CFG_INTR_TEMP_ENABLE_POS         5
#define     IFX_DPS310_CFG_INTR_TEMP_ENABLE_VAL         1U
#define     IFX_DPS310_CFG_INTR_TEMP_DISABLE_VAL        0U
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_ENABLE_POS    6
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_ENABLE_VAL    1U
#define     IFX_DPS310_CFG_INTR_FIFO_FULL_DISABLE_VAL   0U
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_SEL_POS       7
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_ACTIVE_H      1U
#define     IFX_DPS310_CFG_INTR_LEVEL_TYP_ACTIVE_L      0U
#define     IFX_DPS310_INTR_SOURCE_PRESSURE             0
#define     IFX_DPS310_INTR_SOURCE_TEMPERATURE          1
#define     IFX_DPS310_INTR_SOURCE_BOTH                 2
#define     IFX_DPS310_INTR_STATUS_REG_ADDR             0x0A
#define     IFX_DPS310_INTR_STATUS_REG_LEN              1
#define     IFX_DPS310_INTR_DISABLE_ALL                (uint8_t)0b10001111
#define     EINVAL                                      1
#define     EIO                                         2
#ifndef NULL
#define     NULL                                        ((void*)0)
#endif // NULL
/* _______________________________________________________ */
#define POW_2_23_MINUS_1    0x7FFFFF   //implies 2^23-1
#define POW_2_24            0x1000000
#define POW_2_15_MINUS_1    0x7FFF
#define POW_2_16            0x10000
#define POW_2_11_MINUS_1    0x7FF
#define POW_2_12            0x1000
#define POW_2_20            0x100000
#define POW_2_19_MINUS_1    524287
/* _______________________________________________________ */
/*Some aliases*/
typedef unsigned char       u8;
typedef char                s8;
typedef unsigned short      u16;
typedef short               s16;
typedef long                s32;
typedef    long long           s64;
//typedef    unsigned long       u32;
typedef    unsigned long long  u64;
typedef float               f32;
typedef double              f64;
typedef u8                  bool;
#define false               0
#define true                1
/* Struct to hold calibration coefficients read from device*/
typedef struct
{
  /* calibration registers */
  s16     C0;    // 12bit
  s16     C1;    // 12bit
  s32    C00;    // 20bit
  s32   C10;    // 20bit
  s16     C01;    // 16bit
  s16    C11;    // 16bit
  s16    C20;    // 16bit
  s16    C21;    // 16bit
  s16    C30;    // 16bit
}dps310_cal_coeff_regs_s;
/* enum for seeting/getting device operating mode*/
typedef enum
    {DPS310_MODE_IDLE = 0,
  DPS310_MODE_COMMAND_PRESSURE       =  1,
  DPS310_MODE_COMMAND_TEMPERATURE    =  2,
  DPS310_MODE_BACKGROUND_PRESSURE    =  5,
  DPS310_MODE_BACKGROUND_TEMPERATURE =  6,
  DPS310_MODE_BACKGROUND_ALL         =  7
}dps310_operating_modes_e;
/* enum of scaling coefficients either Kp or Kt*/
typedef enum
{
    OSR_SF_1   = 524288,
    OSR_SF_2   = 1572864,
    OSR_SF_4   = 3670016,
    OSR_SF_8   = 7864320,
    OSR_SF_16  = 253952,
    OSR_SF_32  = 516096,
    OSR_SF_64  = 1040384,
    OSR_SF_128 = 2088960
} dps310_scaling_coeffs_e;
/* enum of oversampling rates for pressure and temperature*/
typedef enum
{
    OSR_1   = 0,
    OSR_2   = 1,
    OSR_4   = 2,
    OSR_8   = 3,
    OSR_16  = 4,
    OSR_32  = 5,
    OSR_64  = 6,
    OSR_128 = 7
} dps310_osr_e;
/* enum of measurement rates for pressure*/
typedef enum
{
    PM_MR_1   = 0,
    PM_MR_2   = 0x10,
    PM_MR_4   = 0x20,
    PM_MR_8   = 0x30,
    PM_MR_16  = 0x40,
    PM_MR_32  = 0x50,
    PM_MR_64  = 0x60,
    PM_MR_128 = 0x70
} dps310_pm_rate_e;
/* enum of measurement rates for temperature*/
typedef enum
{
    TMP_MR_1   = 0,
    TMP_MR_2   = 0x10,
    TMP_MR_4   = 0x20,
    TMP_MR_8   = 0x30,
    TMP_MR_16  = 0x40,
    TMP_MR_32  = 0x50,
    TMP_MR_64  = 0x60,
    TMP_MR_128 = 0x70
} dps310_tmp_rate_e;
/* enum of oversampling and measurement rates*/
typedef enum
{
    TMP_EXT_ASIC = 0x00,
    TMP_EXT_MEMS = 0x80,
}dps310_temperature_src_e;
/*Please update callbacks for bus communication
* callbacks are protocol agnostic/abstract so
* as to wrap around I2C or SPI low level protocols
*/
typedef struct {
        /*Provide a wrapper for single byte read/write and multi byte read
        * all callbacks return negative values to indicate error
        * however, read_byte must return the content in case of successful read
        * and read_block shall return number of bytes read successfully
        * For write_byte non zero return value shall indicate successful write
        */
        s16 (*read_byte)(u8 address);
        s16 (*read_block)(u8 address, u8 length, u8 *read_buffer);
        s16 (*write_byte)(u8 address, u8 data);
        /*It is expected to provide a wrapper for incorporating delay
        * the delay shall be in milliseconds. This is required as
        * after powering up the sensor, it takes 40ms until fused
        * calibration coefficients are ready to read.
        * in case this delay is handled appropriately by caller by other mechanism
        * please set this callback to NULL
        */
        void (*delayms)(u8 duration);
}dps310_bus_connection;
struct dps310_state {
        dps310_scaling_coeffs_e   tmp_osr_scale_coeff;                    /* Temperature scaling coefficient*/
        dps310_scaling_coeffs_e   prs_osr_scale_coeff;                    /* Pressure scaling coefficient*/
        dps310_cal_coeff_regs_s   calib_coeffs;                           /* Calibration coefficients index */
        dps310_operating_modes_e  dev_mode;                               /* Current operating mode of device */
        dps310_pm_rate_e          press_mr;                  /* Current measurement readout rate (ODR) for pressure */
        dps310_tmp_rate_e         temp_mr;                  /* Current measurement readout rate (ODR) for temperature */
        dps310_osr_e              temp_osr;                  /* Current oversampling rate (OSR) for temperature */
        dps310_osr_e              press_osr;                  /* Current oversampling rate (OSR) for pressure */
        dps310_temperature_src_e  tmp_ext;                                /* Temperature ASIC or MEMS. Should always be set MEMS*/
        u8                        cfg_word;                               /* Keep the contents of CFG register as it gets configured
                                                                            to avoid excessive bus transactions */
    bool                           enable;
    dps310_bus_connection         *io;                                    /*To access bus communication call backs */
};
/* public function prototypes */
int
dps310_init
(
 struct dps310_state *drv_state,
 dps310_bus_connection *io
);
int dps310_get_processed_data
(
 struct dps310_state *drv_state,
 f64 *pressure,
 f64 *temperature
 );
int
dps310_config
(
 struct dps310_state *drv_state,
 dps310_osr_e osr_temp,
 dps310_tmp_rate_e mr_temp,
 dps310_osr_e osr_press,
 dps310_pm_rate_e mr_press,
 dps310_temperature_src_e temp_src
 );
int
dps310_standby
(
 struct dps310_state *drv_state
);
int
dps310_resume
(
 struct dps310_state *drv_state
);
#endif // DPS310_H_INCLUDED
Src/ExternalDevices/dps368_test.c
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,147 @@
/*
 * Copyright (c) 2015-2016 Infineon Technologies AG
 *
 * Driver for Infineon DPS310 Digital Barometric Pressure Sensor
 *
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include "dps310.h"
#include "main.h"
#include "lis3dh_driver.h"
/*bus communication protocol stubs
* Please wrap around platform specific implementation
* for low level bus handling (I2C or SPI), that matches
* prototypes provided by dps310_bus_connection structure
* in dps310.h
*/
void delay_us(uint32_t nTimer);
/* Should return -1 in case of failure otherwise valid contents*/
s16 test_read_byte(u8 ReadAddr)
{
  uint8_t temp=0;
    IIC2_Start();
    IIC2_Send_Byte(0xee);         //发送写命令
    IIC2_Wait_Ack();
    IIC2_Send_Byte(ReadAddr);   //发送读地址
    IIC2_Wait_Ack();
    IIC2_Start();
    IIC2_Send_Byte(0xef);       //发送读命令,进入接收模式
    IIC2_Wait_Ack();
    temp=IIC2_Read_Byte(0);
    IIC2_Stop();                                //产生一个停止条件
    return temp;
}
/* Should return -1 or negative value in case of failure otherwise length of
* read contents in read_buffer
* and shall place read contents in read_buffer
*/
s16 test_read_block(u8 ReadAddr, u8 Len, u8 *read_buffer)
{
       uint8_t t;
    uint32_t temp=0;
    for(t=0;t<Len;t++)
    {
        *read_buffer=test_read_byte(ReadAddr+t);
         read_buffer++;
    }
    //return temp;
    return Len;
}
/* Should return -1 in case of failure otherwise non negative number*/
s16 test_write_byte(u8 WriteAddr, u8 DataToWrite)
{
    IIC2_Start();
    IIC2_Send_Byte(0xee);        //发送写命令
    IIC2_Wait_Ack();
    IIC2_Send_Byte(WriteAddr);                    //发送地址
    IIC2_Wait_Ack();
    IIC2_Send_Byte(DataToWrite);     //发送字节
    IIC2_Wait_Ack();
    IIC2_Stop();//产生一个停止条件
    delay_us(10);
}
/* Shall implement delay in milliseconds*/
void test_wait_ms(u8 delay)
{
     printf("Waiting for %dms\n",delay);
}
struct dps310_state drv_state;
f64 pressure,temperature;
int BarInit(void)
{
    /*Instantiate driver state*/
    /*Instantiate bus connection callback holder*/
    dps310_bus_connection cnn;
   /* Assign/register platform specific bus handlers*/
    cnn.read_byte=&test_read_byte;
    cnn.read_block=&test_read_block;
    cnn.write_byte=&test_write_byte;
   /*If platform doesn't support delay or sleep
    *please assign NULL to this callback i.e cnn.delayms = NULL
    */
    cnn.delayms = &test_wait_ms;
    /*First call _init
     * this function verifies chip with appropriate id and
     * reads and stores calibration data, configures the sensor
     * to meet default configuration set in dps310.h.
     * This also puts the sensor in background mode
     * making it measure both pressure and temperature continuously
     */
    int ret = dps310_init(&drv_state,&cnn);
    printf("init ret val = %d\n",ret);
    /* once sensor is put into background mode
     * pressure and temperature values are available and can be read
     * Here get_processed_data synchrounuously reads 6 bytes of raw data
     * and returns computed double precision pressure and temperature value
     */
    ret = dps310_get_processed_data(&drv_state,&pressure,&temperature);
    printf("get_processed_data ret val = %d, pressure = %lf, temp = %lf\n",ret,pressure,temperature);
   /*To change configuration we first need to put sensor in
    *idle mode by calling _standby
    */
//    ret = dps310_standby(&drv_state);
//    printf("standby ret val = %d\n",ret);
//    /* Now lets call _config to meet different output data rate (ODR)
//     * and oversampling rate (OSR) based on scenario and usecase
//     * For valid combinations please refer to Page 25 of datasheet
//     */
//    ret = dps310_config(&drv_state,
//                       OSR_2,
//                       TMP_MR_2,
//                       OSR_8,
//                       PM_MR_64,
//                       drv_state.tmp_ext);
//    printf("config ret val = %d\n",ret);
//
//    /*Resume the sensor in background mode again*/
//    ret = dps310_resume(&drv_state);
//    printf("resume ret val = %d\n",ret);
    return 0;
}
void GetPressAndTemp(void)
{  u8 ret;
    /*Instantiate driver state*/
    ret = dps310_get_processed_data(&drv_state,&pressure,&temperature);
   }
Src/ExternalDevices/lis3dh_driver.c
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1995 @@
/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
* File Name          : LIS3DH_driver.c
* Author             : MSH Application Team
* Author             : Fabio Tota
* Version            : $Revision:$
* Date               : $Date:$
* Description        : LIS3DH driver file
*
* HISTORY:
* Date               |    Modification                    |    Author
* 24/06/2011         |    Initial Revision                |    Fabio Tota
* 11/06/2012         |    Support for multiple drivers in the same program |    Abhishek Anand
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
*
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "lis3dh_driver.h"
#include "stdlib.h"
#include "math.h"
#include "main.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
//int main(void)
//{
//    delay_init();             //延时函数初始化
//    uart_init(115200);         //串口初始化为115200
//    IIC2_Init();
//    delay_ms(100);
//    while(1)
//    {
//        LIS3DH_Data_Init();
//        delay_ms(1000);
//    }
//
//}
void delay_us(uint32_t nTimer)
{
    uint32_t i=0;
    for(i=0;i<nTimer;i++){
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();
    }
}
AxesRaw_t lis2dhdata;
//OLED初始化IIC
void IIC2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure= {0};
 __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStructure.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD ;   //推挽输出
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2|GPIO_PIN_3,GPIO_PIN_SET);     //PB6,PB7 è¾“出高
}
void LIS3DH_Data_Init()
{
    //uint8_t buffer[26];
    uint8_t lisid,response;
    uint8_t lisidtemp;
    LIS3DH_WriteReg(LIS3DH_CTRL_REG1, 0x37);    /* CTRL_REG1(20h): ??sensor,???????? ODR 25HZ */
    LIS3DH_WriteReg(LIS3DH_CTRL_REG2, 0x03);    /* CTRL_REG2(21h): IA1?IA2 ?????? bc */
    LIS3DH_WriteReg(LIS3DH_CTRL_REG3, 0x40);    /* CTRL_REG3(22h): 0x80 ???????INT_1 INT_2 */
    LIS3DH_WriteReg(LIS3DH_CTRL_REG4, 0x08);  /* CTRL_REG4(23h): ???,????,???+/-2G,?????? */
    LIS3DH_WriteReg(LIS3DH_INT1_CFG, 0xaa);  /* INT1_CFG(30h): ??,6D X/Y/Z???????? */
    g_com_map[IMU_THRES]=2;
    LIS3DH_WriteReg(LIS3DH_INT1_THS, (uint8_t)g_com_map[IMU_THRES]);      /* INT1_THS(32h): ?????? 0x10: 16*2(FS)  0x20: 32*16(FS) */
 LIS3DH_WriteReg(LIS3DH_INT1_DURATION, 0x01);      /* INT1_DURATION(33h): 1LSB=1/ODR  ??ODR=100HZ  ??1LSB=10ms ???? 1s,??100->0x64 */
    /* Start sensor */
    LIS3DH_WriteReg(0x20, 0x5f);  /* CTRL_REG1(20h): Start sensor at ODR 100Hz Low-power mode */
    // Read ID
    LIS3DH_GetWHO_AM_I(&lisidtemp);
//    lisid=(uint16_t)lisidtemp;
//    printf("LIS3DH ID: %x \r\n",lisid);
    //get Acceleration Raw data
//    response=LIS3DH_GetAccAxesRaw(&data);
    //print data values
    delay_us(10);
//    if(response==1)
//    {
//
//        printf("传感器原始值:x=%d, y=%d, z=%d\r\n", lis2dhdata.AXIS_X, lis2dhdata.AXIS_Y, lis2dhdata.AXIS_Z);
//        printf( "处理后的加速度值Accel:[x]%dmg,[y]%dmg,[z]%dmg\r\n",
//                                                                (int16_t)((float)lis2dhdata.AXIS_X*4/65536*1000),
//                                                                (int16_t)((float)lis2dhdata.AXIS_Y*4/65536*1000),
//                                                                (int16_t)((float)lis2dhdata.AXIS_Z*4/65536*1000));
//
//    }
}
void LIS3DH_ENTER_STY_Init()
{
    //uint8_t buffer[26];
    uint8_t lisid,response;
    uint8_t lisidtemp;
    //set ODR (turn ON device)
    LIS3DH_SetODR(LIS3DH_ODR_10Hz);
    //set PowerMode
    LIS3DH_SetMode(LIS3DH_POWER_DOWN);
    //set Fullscale
    LIS3DH_SetFullScale(LIS3DH_FULLSCALE_2);
    LIS3DH_SetInt2Pin(LIS3DH_I1_INT2_ON_PIN_INT1_ENABLE);
//LIS3DH_SetTriggerInt(LIS3DH_TRIG_INT2);
//    LIS3DH_WriteReg(0x34,0xff);
//    LIS3DH_WriteReg(0x35,0x7f);
//    LIS3DH_WriteReg(0x36,0x20);
    //set axis Enable
    LIS3DH_SetAxis(LIS3DH_X_DISABLE | LIS3DH_Y_DISABLE | LIS3DH_Y_DISABLE);
    // Read ID
    //LIS3DH_GetWHO_AM_I(&lisidtemp);
//    lisid=(uint16_t)lisidtemp;
//    printf("LIS3DH ID: %x \r\n",lisid);
    //get Acceleration Raw data
//    response=LIS3DH_GetAccAxesRaw(&data);
    //print data values
    HAL_Delay(100);
//    if(response==1)
//    {
//
//        printf("传感器原始值:x=%d, y=%d, z=%d\r\n", lis2dhdata.AXIS_X, lis2dhdata.AXIS_Y, lis2dhdata.AXIS_Z);
//        printf( "处理后的加速度值Accel:[x]%dmg,[y]%dmg,[z]%dmg\r\n",
//                                                                (int16_t)((float)lis2dhdata.AXIS_X*4/65536*1000),
//                                                                (int16_t)((float)lis2dhdata.AXIS_Y*4/65536*1000),
//                                                                (int16_t)((float)lis2dhdata.AXIS_Z*4/65536*1000));
//
//    }
}
//获取数据
float drv_lis2dh12_get_angle(void)
{
    float acc_x, acc_y, acc_z, acc_g;
    float angle_x, angle_y, angle_z, angle_xyz;
    int8_t data[6];
    uint8_t i;
    uint8_t lisid,response;
    uint8_t lisidtemp;
    //set ODR (turn ON device)
    LIS3DH_SetODR(LIS3DH_ODR_100Hz);
    //set PowerMode
    LIS3DH_SetMode(LIS3DH_NORMAL);
    //set Fullscale
    LIS3DH_SetFullScale(LIS3DH_FULLSCALE_2);
    //set axis Enable
    LIS3DH_SetAxis(LIS3DH_X_ENABLE | LIS3DH_Y_ENABLE | LIS3DH_Z_ENABLE);
    // Read ID
    LIS3DH_GetWHO_AM_I(&lisidtemp);
    lisid=(uint16_t)lisidtemp;
//    printf("LIS3DH ID: %x \r\n",lisid);
    //get Acceleration Raw data
    response=LIS3DH_GetAccAxesRaw(&lis2dhdata);
    //print data values
    delay_us(10);
//    LIS3DH_GetAccAxesRaw(&lis2dhdata);
//    for (i=0; i<6; i++)
//        drv_lis2dh12_iic_read_byte(0x28 + i, data+i);
    if(response==1)
    {
    /* x, y, z ???? */
    acc_x = abs(lis2dhdata.AXIS_X);
    acc_y = abs(lis2dhdata.AXIS_Y);
    acc_z = abs(lis2dhdata.AXIS_Z);
    /* ????? */
    acc_g = sqrt(pow(acc_x, 2) + pow(acc_y, 2) + pow(acc_z, 2));
    if (acc_z > acc_g)
        acc_z = acc_g;
    /* angle_z/90 = asin(acc_z/acc_g)/p/2 */
    angle_z = asin(acc_z/acc_g) * 2 / 3.14 * 90;
    angle_z = 90 - angle_z;
    if(angle_z < 0)
        angle_z = 0;
    }
    return acc_g;
}
//产生IIC起始信号
void IIC2_Start(void)
{
//        IIC2_SDA_OUT();     //sda线输出
        SDA_1;
//        delay_us(10);
        SCL_1;
//        delay_us(10);
        SDA_0;//START:when CLK is high,DATA change form high to low
        delay_us(10);
        SCL_0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC2_Stop(void)
{
//        IIC2_SDA_OUT();//sda线输出
        SCL_0;
//        delay_us(10);
        SDA_0;//STOP:when CLK is high DATA change form low to high
         delay_us(10);
        SCL_1;
//        delay_us(10);
        SDA_1;//发送I2C总线结束信号
        delay_us(10);
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t IIC2_Wait_Ack(void)
{
    uint8_t ucErrTime=0;
//  IIC2_SDA_IN();      //SDA设置为输入
     SDA_1;
    delay_us(6);
    SCL_1;
    delay_us(6);
    while(IIC2_READ_SDA)
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            IIC2_Stop();
            return 1;
        }
    }
    SCL_0;//时钟输出0
    return 0;
}
//产生ACK应答
void IIC2_Ack(void)
{
    SCL_0;
//    IIC2_SDA_OUT();
    SDA_0;
    delay_us(10);
    SCL_1;
    delay_us(10);
    SCL_0;
}
//不产生ACK应答
void IIC2_NAck(void)
{
    SCL_0;
//    IIC2_SDA_OUT();
    SDA_1;
    delay_us(10);
    SCL_1;
    delay_us(10);
    SCL_0;
}
//IIC发送一个字节,WRITE
//返回从机有无应答
//1,有应答
//0,无应答
void IIC2_Send_Byte(uint8_t txd)
{
    uint8_t t;
//        IIC2_SDA_OUT();
        SCL_0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {
            if((txd&0x80)>>7)
            {
                SDA_1;
            }
            else
            {
                SDA_0;
            }
        txd <<= 1;
        delay_us(10);
        SCL_1;
        delay_us(10);
        SCL_0;
        delay_us(10);
    }
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t IIC2_Read_Byte(unsigned char ack)
{
    unsigned char i,receive=0;
//    IIC2_SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
    {
    SCL_0;
    delay_us(10);
        SCL_1;
    receive<<=1;
    if(IIC2_READ_SDA)receive++;
        delay_us(5);
    }
    if (!ack)
        IIC2_NAck();//发送nACK
    else
        IIC2_Ack(); //发送ACK
    return receive;
}
//在LIS3DH里面的指定地址开始读一字节数据
//ReadAddr   :读出的地址
//返回值     :读出的数据
uint8_t LIS3DH_ReadOneByte(uint16_t ReadAddr)
{
    uint8_t temp=0;
    IIC2_Start();
    IIC2_Send_Byte(0X32);         //发送写命令
    IIC2_Wait_Ack();
    IIC2_Send_Byte(ReadAddr);   //发送读地址
    IIC2_Wait_Ack();
    IIC2_Start();
    IIC2_Send_Byte(0X33);       //发送读命令,进入接收模式
    IIC2_Wait_Ack();
    temp=IIC2_Read_Byte(0);
    IIC2_Stop();                                //产生一个停止条件
    return temp;
}
//在LIS3DH指定地址写入一个数据
//WriteAddr  :写入数据的目的地址
//DataToWrite:要写入的数据
void LIS3DH_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite)
{
    IIC2_Start();
    IIC2_Send_Byte(0X32);        //发送写命令
    IIC2_Wait_Ack();
    IIC2_Send_Byte(WriteAddr);                    //发送地址
    IIC2_Wait_Ack();
    IIC2_Send_Byte(DataToWrite);     //发送字节
    IIC2_Wait_Ack();
    IIC2_Stop();//产生一个停止条件
    delay_us(10);
}
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr  :开始写入的地址
//DataToWrite:数据数组首地址
//Len        :要写入数据的长度2,4
void LIS3DH_WriteLenByte(uint16_t WriteAddr,uint32_t DataToWrite,uint8_t Len)
{
    uint8_t t;
    for(t=0;t<Len;t++)
    {
        LIS3DH_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
    }
}
//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr   :开始读出的地址
//返回值     :数据
//Len        :要读出数据的长度2,4
uint32_t LIS3DH_ReadLenByte(uint16_t ReadAddr,uint8_t Len)
{
    uint8_t t;
    uint32_t temp=0;
    for(t=0;t<Len;t++)
    {
        temp<<=8;
        temp+=LIS3DH_ReadOneByte(ReadAddr+Len-t-1);
    }
    return temp;
}
/*******************************************************************************
* Function Name        : LIS3DH_ReadReg
* Description        : Generic Reading function. It must be fullfilled with either
*            : I2C or SPI reading functions
* Input            : Register Address
* Output        : Data REad
* Return        : None
*******************************************************************************/
uint8_t LIS3DH_ReadReg(uint8_t Reg, uint8_t* Data) {
    //To be completed with either I2c or SPI reading function
    //i.e. *Data = SPI_Mems_Read_Reg( Reg );
    *Data = LIS3DH_ReadOneByte(Reg);
    return 1;
}
/*******************************************************************************
* Function Name        : LIS3DH_WriteReg
* Description        : Generic Writing function. It must be fullfilled with either
*            : I2C or SPI writing function
* Input            : Register Address, Data to be written
* Output        : None
* Return        : None
*******************************************************************************/
uint8_t LIS3DH_WriteReg(uint8_t WriteAddr, uint8_t Data) {
    //To be completed with either I2c or SPI writing function
    //i.e. SPI_Mems_Write_Reg(WriteAddr, Data);
        LIS3DH_WriteOneByte(WriteAddr,Data);
    return 1;
}
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name  : LIS3DH_GetWHO_AM_I
* Description    : Read identification code by WHO_AM_I register
* Input          : Char to empty by Device identification Value
* Output         : None
* Return         : Status [value of FSS]
*******************************************************************************/
status_t LIS3DH_GetWHO_AM_I(uint8_t* val){
    if( !LIS3DH_ReadReg(LIS3DH_WHO_AM_I, val) )
    return MEMS_ERROR;
    return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetStatusAUX
* Description    : Read the AUX status register
* Input          : Char to empty by status register buffer
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetStatusAUX(uint8_t* val) {
  if( !LIS3DH_ReadReg(LIS3DH_STATUS_AUX, val) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetStatusAUXBIT
* Description    : Read the AUX status register BIT
* Input          : LIS3DH_STATUS_AUX_321OR, LIS3DH_STATUS_AUX_3OR, LIS3DH_STATUS_AUX_2OR, LIS3DH_STATUS_AUX_1OR,
                   LIS3DH_STATUS_AUX_321DA, LIS3DH_STATUS_AUX_3DA, LIS3DH_STATUS_AUX_2DA, LIS3DH_STATUS_AUX_1DA
* Output         : None
* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetStatusAUXBit(uint8_t statusBIT, uint8_t* val) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_STATUS_AUX, &value) )
    return MEMS_ERROR;
  if(statusBIT == LIS3DH_STATUS_AUX_321OR){
    if(value &= LIS3DH_STATUS_AUX_321OR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_3OR){
    if(value &= LIS3DH_STATUS_AUX_3OR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_2OR){
    if(value &= LIS3DH_STATUS_AUX_2OR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_1OR){
    if(value &= LIS3DH_STATUS_AUX_1OR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_321DA){
    if(value &= LIS3DH_STATUS_AUX_321DA) {
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_3DA){
    if(value &= LIS3DH_STATUS_AUX_3DA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_2DA){
    if(value &= LIS3DH_STATUS_AUX_2DA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_STATUS_AUX_1DA){
    if(value &= LIS3DH_STATUS_AUX_1DA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  return MEMS_ERROR;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetODR
* Description    : Sets LIS3DH Output Data Rate
* Input          : Output Data Rate
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetODR(LIS3DH_ODR_t ov){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
    return MEMS_ERROR;
  value &= 0x0f;
  value |= ov<<LIS3DH_ODR_BIT;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetTemperature
* Description    : Sets LIS3DH Output Temperature
* Input          : MEMS_ENABLE, MEMS_DISABLE
* Output         : None
* Note           : For Read Temperature by LIS3DH_OUT_AUX_3, LIS3DH_SetADCAux and LIS3DH_SetBDU
                   functions must be ENABLE
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetTemperature(State_t state){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_TEMP_CFG_REG, &value) )
    return MEMS_ERROR;
  value &= 0xBF;
  value |= state<<LIS3DH_TEMP_EN;
  if( !LIS3DH_WriteReg(LIS3DH_TEMP_CFG_REG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetADCAux
* Description    : Sets LIS3DH Output ADC
* Input          : MEMS_ENABLE, MEMS_DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetADCAux(State_t state){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_TEMP_CFG_REG, &value) )
    return MEMS_ERROR;
  value &= 0x7F;
  value |= state<<LIS3DH_ADC_PD;
  if( !LIS3DH_WriteReg(LIS3DH_TEMP_CFG_REG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetAuxRaw
* Description    : Read the Aux Values Output Registers
* Input          : Buffer to empty
* Output         : Aux Values Registers buffer
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetAuxRaw(LIS3DH_Aux123Raw_t* buff) {
  uint8_t valueL;
  uint8_t valueH;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_1_L, &valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_1_H, &valueH) )
    return MEMS_ERROR;
  buff->AUX_1 = (uint16_t)( (valueH << 8) | valueL )/16;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_2_L, &valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_2_H, &valueH) )
    return MEMS_ERROR;
  buff->AUX_2 = (uint16_t)( (valueH << 8) | valueL )/16;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_L, &valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_H, &valueH) )
    return MEMS_ERROR;
  buff->AUX_3 = (uint16_t)( (valueH << 8) | valueL )/16;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetTempRaw
* Description    : Read the Temperature Values by AUX Output Registers OUT_3_H
* Input          : Buffer to empty
* Output         : Temperature Values Registers buffer
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetTempRaw(int8_t* buff) {
  uint8_t valueL;
  uint8_t valueH;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_L, &valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_H, &valueH) )
    return MEMS_ERROR;
  *buff = (int8_t)( valueH );
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetMode
* Description    : Sets LIS3DH Operating Mode
* Input          : Modality (LIS3DH_NORMAL, LIS3DH_LOW_POWER, LIS3DH_POWER_DOWN)
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetMode(LIS3DH_Mode_t md) {
  uint8_t value;
  uint8_t value2;
  static   uint8_t ODR_old_value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value2) )
    return MEMS_ERROR;
  if((value & 0xF0)==0)
    value = value | (ODR_old_value & 0xF0); //if it comes from POWERDOWN
  switch(md) {
  case LIS3DH_POWER_DOWN:
    ODR_old_value = value;
    value &= 0x0F;
    break;
  case LIS3DH_NORMAL:
    value &= 0xF7;
    value |= (MEMS_RESET<<LIS3DH_LPEN);
    value2 &= 0xF7;
    value2 |= (MEMS_SET<<LIS3DH_HR);   //set HighResolution_BIT
    break;
  case LIS3DH_LOW_POWER:
    value &= 0xF7;
    value |=  (MEMS_SET<<LIS3DH_LPEN);
    value2 &= 0xF7;
    value2 |= (MEMS_RESET<<LIS3DH_HR); //reset HighResolution_BIT
    break;
  default:
    return MEMS_ERROR;
  }
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value2) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetAxis
* Description    : Enable/Disable LIS3DH Axis
* Input          : LIS3DH_X_ENABLE/DISABLE | LIS3DH_Y_ENABLE/DISABLE | LIS3DH_Z_ENABLE/DISABLE
* Output         : None
* Note           : You MUST use all input variable in the argument, as example
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetAxis(LIS3DH_Axis_t axis) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
    return MEMS_ERROR;
  value &= 0xF8;
  value |= (0x07 & axis);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetFullScale
* Description    : Sets the LIS3DH FullScale
* Input          : LIS3DH_FULLSCALE_2/LIS3DH_FULLSCALE_4/LIS3DH_FULLSCALE_8/LIS3DH_FULLSCALE_16
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetFullScale(LIS3DH_Fullscale_t fs) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
    return MEMS_ERROR;
  value &= 0xCF;
  value |= (fs<<LIS3DH_FS);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetBDU
* Description    : Enable/Disable Block Data Update Functionality
* Input          : ENABLE/DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetBDU(State_t bdu) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
    return MEMS_ERROR;
  value &= 0x7F;
  value |= (bdu<<LIS3DH_BDU);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetBLE
* Description    : Set Endianess (MSB/LSB)
* Input          : BLE_LSB / BLE_MSB
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetBLE(LIS3DH_Endianess_t ble) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
    return MEMS_ERROR;
  value &= 0xBF;
  value |= (ble<<LIS3DH_BLE);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetSelfTest
* Description    : Set Self Test Modality
* Input          : LIS3DH_SELF_TEST_DISABLE/ST_0/ST_1
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetSelfTest(LIS3DH_SelfTest_t st) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
    return MEMS_ERROR;
  value &= 0xF9;
  value |= (st<<LIS3DH_ST);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_HPFClick
* Description    : Enable/Disable High Pass Filter for click
* Input          : MEMS_ENABLE/MEMS_DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_HPFClickEnable(State_t hpfe) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0xFB;
  value |= (hpfe<<LIS3DH_HPCLICK);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_HPFAOI1
* Description    : Enable/Disable High Pass Filter for AOI on INT_1
* Input          : MEMS_ENABLE/MEMS_DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_HPFAOI1Enable(State_t hpfe) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0xFE;
  value |= (hpfe<<LIS3DH_HPIS1);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_HPFAOI2
* Description    : Enable/Disable High Pass Filter for AOI on INT_2
* Input          : MEMS_ENABLE/MEMS_DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_HPFAOI2Enable(State_t hpfe) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0xFD;
  value |= (hpfe<<LIS3DH_HPIS2);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetHPFMode
* Description    : Set High Pass Filter Modality
* Input          : LIS3DH_HPM_NORMAL_MODE_RES/LIS3DH_HPM_REF_SIGNAL/
                   LIS3DH_HPM_NORMAL_MODE/LIS3DH_HPM_AUTORESET_INT
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetHPFMode(LIS3DH_HPFMode_t hpm) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0x3F;
  value |= (hpm<<LIS3DH_HPM);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetHPFCutOFF
* Description    : Set High Pass CUT OFF Freq
* Input          : HPFCF [0,3]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetHPFCutOFF(LIS3DH_HPFCutOffFreq_t hpf) {
  uint8_t value;
  if (hpf > 3)
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0xCF;
  value |= (hpf<<LIS3DH_HPCF);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetFilterDataSel
* Description    : Set Filter Data Selection bypassed or sent to FIFO OUT register
* Input          : MEMS_SET, MEMS_RESET
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetFilterDataSel(State_t state) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
    return MEMS_ERROR;
  value &= 0xF7;
  value |= (state<<LIS3DH_FDS);
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetInt1Pin
* Description    : Set Interrupt1 pin Function
* Input          :  LIS3DH_CLICK_ON_PIN_INT1_ENABLE/DISABLE    | LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE/DISABLE |
                    LIS3DH_I1_INT2_ON_PIN_INT1_ENABLE/DISABLE  | LIS3DH_I1_DRDY1_ON_INT1_ENABLE/DISABLE    |
                    LIS3DH_I1_DRDY2_ON_INT1_ENABLE/DISABLE     | LIS3DH_WTM_ON_INT1_ENABLE/DISABLE         |
                    LIS3DH_INT1_OVERRUN_ENABLE/DISABLE
* example        : SetInt1Pin(LIS3DH_CLICK_ON_PIN_INT1_ENABLE | LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE |
                    LIS3DH_I1_INT2_ON_PIN_INT1_DISABLE | LIS3DH_I1_DRDY1_ON_INT1_ENABLE | LIS3DH_I1_DRDY2_ON_INT1_ENABLE |
                    LIS3DH_WTM_ON_INT1_DISABLE | LIS3DH_INT1_OVERRUN_DISABLE   )
* Note           : To enable Interrupt signals on INT1 Pad (You MUST use all input variable in the argument, as example)
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetInt1Pin(LIS3DH_IntPinConf_t pinConf) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG3, &value) )
    return MEMS_ERROR;
  value &= 0x00;
  value |= pinConf;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG3, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetInt2Pin
* Description    : Set Interrupt2 pin Function
* Input          : LIS3DH_CLICK_ON_PIN_INT2_ENABLE/DISABLE   | LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE/DISABLE |
                   LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_BOOT_ON_INT2_ENABLE/DISABLE |
                   LIS3DH_INT_ACTIVE_HIGH/LOW
* example        : LIS3DH_SetInt2Pin(LIS3DH_CLICK_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE/DISABLE |
                   LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_BOOT_ON_INT2_ENABLE/DISABLE |
                   LIS3DH_INT_ACTIVE_HIGH/LOW)
* Note           : To enable Interrupt signals on INT2 Pad (You MUST use all input variable in the argument, as example)
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetInt2Pin(LIS3DH_IntPinConf_t pinConf) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG6, &value) )
    return MEMS_ERROR;
  value &= 0x00;
  value |= pinConf;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG6, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetClickCFG
* Description    : Set Click Interrupt config Function
* Input          : LIS3DH_ZD_ENABLE/DISABLE | LIS3DH_ZS_ENABLE/DISABLE  | LIS3DH_YD_ENABLE/DISABLE  |
                   LIS3DH_YS_ENABLE/DISABLE | LIS3DH_XD_ENABLE/DISABLE  | LIS3DH_XS_ENABLE/DISABLE
* example        : LIS3DH_SetClickCFG( LIS3DH_ZD_ENABLE | LIS3DH_ZS_DISABLE | LIS3DH_YD_ENABLE |
                               LIS3DH_YS_DISABLE | LIS3DH_XD_ENABLE | LIS3DH_XS_ENABLE)
* Note           : You MUST use all input variable in the argument, as example
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetClickCFG(uint8_t status) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CLICK_CFG, &value) )
    return MEMS_ERROR;
  value &= 0xC0;
  value |= status;
  if( !LIS3DH_WriteReg(LIS3DH_CLICK_CFG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetClickTHS
* Description    : Set Click Interrupt threshold
* Input          : Click-click Threshold value [0-127]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetClickTHS(uint8_t ths) {
  if(ths>127)
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_CLICK_THS, ths) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetClickLIMIT
* Description    : Set Click Interrupt Time Limit
* Input          : Click-click Time Limit value [0-127]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetClickLIMIT(uint8_t t_limit) {
  if(t_limit>127)
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_TIME_LIMIT, t_limit) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetClickLATENCY
* Description    : Set Click Interrupt Time Latency
* Input          : Click-click Time Latency value [0-255]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetClickLATENCY(uint8_t t_latency) {
  if( !LIS3DH_WriteReg(LIS3DH_TIME_LATENCY, t_latency) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetClickWINDOW
* Description    : Set Click Interrupt Time Window
* Input          : Click-click Time Window value [0-255]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetClickWINDOW(uint8_t t_window) {
  if( !LIS3DH_WriteReg(LIS3DH_TIME_WINDOW, t_window) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetClickResponse
* Description    : Get Click Interrupt Response by CLICK_SRC REGISTER
* Input          : char to empty by Click Response Typedef
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetClickResponse(uint8_t* res) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CLICK_SRC, &value) )
    return MEMS_ERROR;
  value &= 0x7F;
  if((value & LIS3DH_IA)==0) {
    *res = LIS3DH_NO_CLICK;
    return MEMS_SUCCESS;
  }
  else {
    if (value & LIS3DH_DCLICK){
      if (value & LIS3DH_CLICK_SIGN){
        if (value & LIS3DH_CLICK_Z) {
          *res = LIS3DH_DCLICK_Z_N;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_Y) {
          *res = LIS3DH_DCLICK_Y_N;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_X) {
          *res = LIS3DH_DCLICK_X_N;
          return MEMS_SUCCESS;
        }
      }
      else{
        if (value & LIS3DH_CLICK_Z) {
          *res = LIS3DH_DCLICK_Z_P;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_Y) {
          *res = LIS3DH_DCLICK_Y_P;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_X) {
          *res = LIS3DH_DCLICK_X_P;
          return MEMS_SUCCESS;
        }
      }
    }
    else{
      if (value & LIS3DH_CLICK_SIGN){
        if (value & LIS3DH_CLICK_Z) {
          *res = LIS3DH_SCLICK_Z_N;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_Y) {
          *res = LIS3DH_SCLICK_Y_N;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_X) {
          *res = LIS3DH_SCLICK_X_N;
          return MEMS_SUCCESS;
        }
      }
      else{
        if (value & LIS3DH_CLICK_Z) {
          *res = LIS3DH_SCLICK_Z_P;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_Y) {
          *res = LIS3DH_SCLICK_Y_P;
          return MEMS_SUCCESS;
        }
        if (value & LIS3DH_CLICK_X) {
          *res = LIS3DH_SCLICK_X_P;
          return MEMS_SUCCESS;
        }
      }
    }
  }
  return MEMS_ERROR;
}
/*******************************************************************************
* Function Name  : LIS3DH_Int1LatchEnable
* Description    : Enable Interrupt 1 Latching function
* Input          : ENABLE/DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_Int1LatchEnable(State_t latch) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
    return MEMS_ERROR;
  value &= 0xF7;
  value |= latch<<LIS3DH_LIR_INT1;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_ResetInt1Latch
* Description    : Reset Interrupt 1 Latching function
* Input          : None
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_ResetInt1Latch(void) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetIntConfiguration
* Description    : Interrupt 1 Configuration (without LIS3DH_6D_INT)
* Input          : LIS3DH_INT1_AND/OR | LIS3DH_INT1_ZHIE_ENABLE/DISABLE | LIS3DH_INT1_ZLIE_ENABLE/DISABLE...
* Output         : None
* Note           : You MUST use all input variable in the argument, as example
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetIntConfiguration(LIS3DH_Int1Conf_t ic) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
    return MEMS_ERROR;
  value &= 0x40;
  value |= ic;
  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetIntMode
* Description    : Interrupt 1 Configuration mode (OR, 6D Movement, AND, 6D Position)
* Input          : LIS3DH_INT_MODE_OR, LIS3DH_INT_MODE_6D_MOVEMENT, LIS3DH_INT_MODE_AND,
                   LIS3DH_INT_MODE_6D_POSITION
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetIntMode(LIS3DH_Int1Mode_t int_mode) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
    return MEMS_ERROR;
  value &= 0x3F;
  value |= (int_mode<<LIS3DH_INT_6D);
  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetInt6D4DConfiguration
* Description    : 6D, 4D Interrupt Configuration
* Input          : LIS3DH_INT1_6D_ENABLE, LIS3DH_INT1_4D_ENABLE, LIS3DH_INT1_6D_4D_DISABLE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetInt6D4DConfiguration(LIS3DH_INT_6D_4D_t ic) {
  uint8_t value;
  uint8_t value2;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value2) )
    return MEMS_ERROR;
  if(ic == LIS3DH_INT1_6D_ENABLE){
    value &= 0xBF;
    value |= (MEMS_ENABLE<<LIS3DH_INT_6D);
    value2 &= 0xFB;
    value2 |= (MEMS_DISABLE<<LIS3DH_D4D_INT1);
  }
  if(ic == LIS3DH_INT1_4D_ENABLE){
    value &= 0xBF;
    value |= (MEMS_ENABLE<<LIS3DH_INT_6D);
    value2 &= 0xFB;
    value2 |= (MEMS_ENABLE<<LIS3DH_D4D_INT1);
  }
  if(ic == LIS3DH_INT1_6D_4D_DISABLE){
    value &= 0xBF;
    value |= (MEMS_DISABLE<<LIS3DH_INT_6D);
    value2 &= 0xFB;
    value2 |= (MEMS_DISABLE<<LIS3DH_D4D_INT1);
  }
  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value2) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_Get6DPosition
* Description    : 6D, 4D Interrupt Position Detect
* Input          : Byte to empty by POSITION_6D_t Typedef
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_Get6DPosition(uint8_t* val){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
    return MEMS_ERROR;
  value &= 0x7F;
  switch (value){
  case LIS3DH_UP_SX:
    *val = LIS3DH_UP_SX;
    break;
  case LIS3DH_UP_DX:
    *val = LIS3DH_UP_DX;
    break;
  case LIS3DH_DW_SX:
    *val = LIS3DH_DW_SX;
    break;
  case LIS3DH_DW_DX:
    *val = LIS3DH_DW_DX;
    break;
  case LIS3DH_TOP:
    *val = LIS3DH_TOP;
    break;
  case LIS3DH_BOTTOM:
    *val = LIS3DH_BOTTOM;
    break;
  }
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetInt1Threshold
* Description    : Sets Interrupt 1 Threshold
* Input          : Threshold = [0,31]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetInt1Threshold(uint8_t ths) {
  if (ths > 127)
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_INT1_THS, ths) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetInt1Duration
* Description    : Sets Interrupt 1 Duration
* Input          : Duration value
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetInt1Duration(LIS3DH_Int1Conf_t id) {
  if (id > 127)
    return MEMS_ERROR;
  if( !LIS3DH_WriteReg(LIS3DH_INT1_DURATION, id) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_FIFOModeEnable
* Description    : Sets Fifo Modality
* Input          : LIS3DH_FIFO_DISABLE, LIS3DH_FIFO_BYPASS_MODE, LIS3DH_FIFO_MODE,
                   LIS3DH_FIFO_STREAM_MODE, LIS3DH_FIFO_TRIGGER_MODE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_FIFOModeEnable(LIS3DH_FifoMode_t fm) {
  uint8_t value;
  if(fm == LIS3DH_FIFO_DISABLE) {
    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
      return MEMS_ERROR;
    value &= 0x1F;
    value |= (LIS3DH_FIFO_BYPASS_MODE<<LIS3DH_FM);
    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )           //fifo mode bypass
      return MEMS_ERROR;
    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
      return MEMS_ERROR;
    value &= 0xBF;
    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo disable
      return MEMS_ERROR;
  }
  if(fm == LIS3DH_FIFO_BYPASS_MODE)   {
    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
      return MEMS_ERROR;
    value &= 0xBF;
    value |= MEMS_SET<<LIS3DH_FIFO_EN;
    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
      return MEMS_ERROR;
    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
      return MEMS_ERROR;
    value &= 0x1f;
    value |= (fm<<LIS3DH_FM);                     //fifo mode configuration
    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
      return MEMS_ERROR;
  }
  if(fm == LIS3DH_FIFO_MODE)   {
    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
      return MEMS_ERROR;
    value &= 0xBF;
    value |= MEMS_SET<<LIS3DH_FIFO_EN;
    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
      return MEMS_ERROR;
    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
      return MEMS_ERROR;
    value &= 0x1f;
    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
      return MEMS_ERROR;
  }
  if(fm == LIS3DH_FIFO_STREAM_MODE)   {
    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
      return MEMS_ERROR;
    value &= 0xBF;
    value |= MEMS_SET<<LIS3DH_FIFO_EN;
    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
      return MEMS_ERROR;
    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
      return MEMS_ERROR;
    value &= 0x1f;
    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
      return MEMS_ERROR;
  }
  if(fm == LIS3DH_FIFO_TRIGGER_MODE)   {
    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
      return MEMS_ERROR;
    value &= 0xBF;
    value |= MEMS_SET<<LIS3DH_FIFO_EN;
    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
      return MEMS_ERROR;
    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
      return MEMS_ERROR;
    value &= 0x1f;
    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
      return MEMS_ERROR;
  }
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetTriggerInt
* Description    : Trigger event liked to trigger signal INT1/INT2
* Input          : LIS3DH_TRIG_INT1/LIS3DH_TRIG_INT2
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetTriggerInt(LIS3DH_TrigInt_t tr) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
    return MEMS_ERROR;
  value &= 0xDF;
  value |= (tr<<LIS3DH_TR);
  if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetWaterMark
* Description    : Sets Watermark Value
* Input          : Watermark = [0,31]
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetWaterMark(uint8_t wtm) {
  uint8_t value;
  if(wtm > 31)
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
    return MEMS_ERROR;
  value &= 0xE0;
  value |= wtm;
  if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetStatusReg
* Description    : Read the status register
* Input          : char to empty by Status Reg Value
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetStatusReg(uint8_t* val) {
  if( !LIS3DH_ReadReg(LIS3DH_STATUS_REG, val) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetStatusBIT
* Description    : Read the status register BIT
* Input          : LIS3DH_STATUS_REG_ZYXOR, LIS3DH_STATUS_REG_ZOR, LIS3DH_STATUS_REG_YOR, LIS3DH_STATUS_REG_XOR,
                   LIS3DH_STATUS_REG_ZYXDA, LIS3DH_STATUS_REG_ZDA, LIS3DH_STATUS_REG_YDA, LIS3DH_STATUS_REG_XDA,
                   LIS3DH_DATAREADY_BIT
                   val: Byte to be filled with the status bit
* Output         : status register BIT
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetStatusBit(uint8_t statusBIT, uint8_t* val) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_STATUS_REG, &value) )
    return MEMS_ERROR;
  switch (statusBIT){
  case LIS3DH_STATUS_REG_ZYXOR:
    if(value &= LIS3DH_STATUS_REG_ZYXOR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_ZOR:
    if(value &= LIS3DH_STATUS_REG_ZOR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_YOR:
    if(value &= LIS3DH_STATUS_REG_YOR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_XOR:
    if(value &= LIS3DH_STATUS_REG_XOR){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_ZYXDA:
    if(value &= LIS3DH_STATUS_REG_ZYXDA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_ZDA:
    if(value &= LIS3DH_STATUS_REG_ZDA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_YDA:
    if(value &= LIS3DH_STATUS_REG_YDA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  case LIS3DH_STATUS_REG_XDA:
    if(value &= LIS3DH_STATUS_REG_XDA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  return MEMS_ERROR;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetAccAxesRaw
* Description    : Read the Acceleration Values Output Registers
* Input          : buffer to empity by AxesRaw_t Typedef
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetAccAxesRaw(AxesRaw_t* buff) {
  int16_t value;
  uint8_t *valueL = (uint8_t *)(&value);
  uint8_t *valueH = ((uint8_t *)(&value)+1);
  if( !LIS3DH_ReadReg(LIS3DH_OUT_X_L, valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_X_H, valueH) )
    return MEMS_ERROR;
  buff->AXIS_X = value;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_Y_L, valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_Y_H, valueH) )
    return MEMS_ERROR;
  buff->AXIS_Y = value;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_Z_L, valueL) )
    return MEMS_ERROR;
  if( !LIS3DH_ReadReg(LIS3DH_OUT_Z_H, valueH) )
    return MEMS_ERROR;
  buff->AXIS_Z = value;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetInt1Src
* Description    : Reset Interrupt 1 Latching function
* Input          : Char to empty by Int1 source value
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetInt1Src(uint8_t* val) {
  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, val) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetInt1SrcBit
* Description    : Reset Interrupt 1 Latching function
* Input          : statusBIT: LIS3DH_INT_SRC_IA, LIS3DH_INT_SRC_ZH, LIS3DH_INT_SRC_ZL.....
*                  val: Byte to be filled with the status bit
* Output         : None
* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetInt1SrcBit(uint8_t statusBIT, uint8_t* val) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
      return MEMS_ERROR;
  if(statusBIT == LIS3DH_INT1_SRC_IA){
    if(value &= LIS3DH_INT1_SRC_IA){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_ZH){
    if(value &= LIS3DH_INT1_SRC_ZH){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_ZL){
    if(value &= LIS3DH_INT1_SRC_ZL){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_YH){
    if(value &= LIS3DH_INT1_SRC_YH){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_YL){
    if(value &= LIS3DH_INT1_SRC_YL){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_XH){
    if(value &= LIS3DH_INT1_SRC_XH){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_INT1_SRC_XL){
    if(value &= LIS3DH_INT1_SRC_XL){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  return MEMS_ERROR;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetFifoSourceReg
* Description    : Read Fifo source Register
* Input          : Byte to empty by FIFO source register value
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetFifoSourceReg(uint8_t* val) {
  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, val) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetFifoSourceBit
* Description    : Read Fifo WaterMark source bit
* Input          : statusBIT: LIS3DH_FIFO_SRC_WTM, LIS3DH_FIFO_SRC_OVRUN, LIS3DH_FIFO_SRC_EMPTY
*                   val: Byte to fill  with the bit value
* Output         : None
* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_GetFifoSourceBit(uint8_t statusBIT,  uint8_t* val){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, &value) )
    return MEMS_ERROR;
  if(statusBIT == LIS3DH_FIFO_SRC_WTM){
    if(value &= LIS3DH_FIFO_SRC_WTM){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_FIFO_SRC_OVRUN){
    if(value &= LIS3DH_FIFO_SRC_OVRUN){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  if(statusBIT == LIS3DH_FIFO_SRC_EMPTY){
    if(value &= statusBIT == LIS3DH_FIFO_SRC_EMPTY){
      *val = MEMS_SET;
      return MEMS_SUCCESS;
    }
    else{
      *val = MEMS_RESET;
      return MEMS_SUCCESS;
    }
  }
  return MEMS_ERROR;
}
/*******************************************************************************
* Function Name  : LIS3DH_GetFifoSourceFSS
* Description    : Read current number of unread samples stored in FIFO
* Input          : Byte to empty by FIFO unread sample value
* Output         : None
* Return         : Status [value of FSS]
*******************************************************************************/
status_t LIS3DH_GetFifoSourceFSS(uint8_t* val){
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, &value) )
    return MEMS_ERROR;
  value &= 0x1F;
  *val = value;
  return MEMS_SUCCESS;
}
/*******************************************************************************
* Function Name  : LIS3DH_SetSPIInterface
* Description    : Set SPI mode: 3 Wire Interface OR 4 Wire Interface
* Input          : LIS3DH_SPI_3_WIRE, LIS3DH_SPI_4_WIRE
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t LIS3DH_SetSPIInterface(LIS3DH_SPIMode_t spi) {
  uint8_t value;
  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
    return MEMS_ERROR;
  value &= 0xFE;
  value |= spi<<LIS3DH_SIM;
  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
    return MEMS_ERROR;
  return MEMS_SUCCESS;
}
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/
Src/ExternalDevices/lis3dh_driver.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,566 @@
/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
* File Name          : lis3dh_driver.h
* Author             : MSH Application Team
* Author             : Abhishek Anand, Fabio Tota
* Version            : $Revision:$
* Date               : $Date:$
* Description        : Descriptor Header for lis3dh_driver.c driver file
*
* HISTORY:
* Date        | Modification                                | Author
* 24/06/2011  | Initial Revision                            | Fabio Tota
* 07/06/2012  | Support for multiple drivers in the same program | Abhishek Anand
*
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
*
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LIS3DH_DRIVER__H
#define __LIS3DH_DRIVER__H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
#include "math.h"
#include "stdint.h"
#include "main.h"
//#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
//#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
//#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//#define GPIOA_ODR_Addr    (GPIOA_BASE+0x14) //0x4001080C
//#define GPIOA_IDR_Addr    (GPIOA_BASE+0x10) //0x40010808
//#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
//#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入
////IO操作函数
//#define IIC2_SCL    PAout(2) //SCL
//#define IIC2_SDA    PAout(3) //SDA
//#define IIC2_READ_SDA   PAin(3)  //输入SDA
#define IIC2_READ_SDA HAL_GPIO_ReadPin(GPIOA, SDA_Pin)
#define SDA_1 HAL_GPIO_WritePin(GPIOA, SDA_Pin, GPIO_PIN_SET)
#define SCL_1    HAL_GPIO_WritePin(GPIOA, SCL_Pin, GPIO_PIN_SET)
#define SDA_0 HAL_GPIO_WritePin(GPIOA, SDA_Pin, GPIO_PIN_RESET)
#define SCL_0    HAL_GPIO_WritePin(GPIOA, SCL_Pin, GPIO_PIN_RESET)
//IIC所有操作函数
void IIC2_Init(void);                    //初始化IIC的IO口
uint8_t LIS3DH_WriteReg(uint8_t WriteAddr, uint8_t Data);
void IIC2_Start(void);                //发送IIC开始信号
void IIC2_Stop(void);                  //发送IIC停止信号
void IIC2_Send_Byte(uint8_t txd);            //IIC发送一个字节
uint8_t IIC2_Read_Byte(unsigned char ack);//IIC读取一个字节
uint8_t IIC2_Wait_Ack(void);                 //IIC等待ACK信号
void IIC2_Ack(void);                    //IIC发送ACK信号
void IIC2_NAck(void);                //IIC不发送ACK信号
float drv_lis2dh12_get_angle(void);
//these could change accordingly with the architecture
void LIS3DH_Data_Init(void);
void LIS3DH_ENTER_STY_Init();
        //初始化,并操作
#ifndef __ARCHDEP__TYPES
#define __ARCHDEP__TYPES
//为兼容HAL_Cube库,使用统一命名
//typedef unsigned char uint8_t;
//typedef unsigned short int uint16_t;
//typedef short int int16_t;
//typedef signed char int8_t;
#endif /*__ARCHDEP__TYPES*/
typedef uint8_t LIS3DH_IntPinConf_t;
typedef uint8_t LIS3DH_Axis_t;
typedef uint8_t LIS3DH_Int1Conf_t;
//define structure
#ifndef __SHARED__TYPES
#define __SHARED__TYPES
typedef enum {
  MEMS_SUCCESS                =        0x01,
  MEMS_ERROR                =        0x00
} status_t;
typedef enum {
  MEMS_ENABLE                =        0x01,
  MEMS_DISABLE                =        0x00
} State_t;
typedef struct {
  int16_t AXIS_X;
  int16_t AXIS_Y;
  int16_t AXIS_Z;
} AxesRaw_t;
#endif /*__SHARED__TYPES*/
typedef enum {
  LIS3DH_ODR_1Hz                =        0x01,
  LIS3DH_ODR_10Hz                      =        0x02,
  LIS3DH_ODR_25Hz                =        0x03,
  LIS3DH_ODR_50Hz                =        0x04,
  LIS3DH_ODR_100Hz                =        0x05,
  LIS3DH_ODR_200Hz                =        0x06,
  LIS3DH_ODR_400Hz                =        0x07,
  LIS3DH_ODR_1620Hz_LP                =        0x08,
  LIS3DH_ODR_1344Hz_NP_5367HZ_LP       =        0x09
} LIS3DH_ODR_t;
typedef enum {
  LIS3DH_POWER_DOWN                    =        0x00,
  LIS3DH_LOW_POWER             =        0x01,
  LIS3DH_NORMAL            =        0x02
} LIS3DH_Mode_t;
typedef enum {
  LIS3DH_HPM_NORMAL_MODE_RES           =               0x00,
  LIS3DH_HPM_REF_SIGNAL                =               0x01,
  LIS3DH_HPM_NORMAL_MODE               =               0x02,
  LIS3DH_HPM_AUTORESET_INT             =               0x03
} LIS3DH_HPFMode_t;
typedef enum {
  LIS3DH_HPFCF_0                       =               0x00,
  LIS3DH_HPFCF_1                       =               0x01,
  LIS3DH_HPFCF_2                       =         0x02,
  LIS3DH_HPFCF_3                       =               0x03
} LIS3DH_HPFCutOffFreq_t;
typedef struct {
  uint16_t AUX_1;
  uint16_t AUX_2;
  uint16_t AUX_3;
} LIS3DH_Aux123Raw_t;
typedef enum {
  LIS3DH_FULLSCALE_2                   =               0x00,
  LIS3DH_FULLSCALE_4                   =               0x01,
  LIS3DH_FULLSCALE_8                   =               0x02,
  LIS3DH_FULLSCALE_16                  =               0x03
} LIS3DH_Fullscale_t;
typedef enum {
  LIS3DH_BLE_LSB            =        0x00,
  LIS3DH_BLE_MSB            =        0x01
} LIS3DH_Endianess_t;
typedef enum {
  LIS3DH_SELF_TEST_DISABLE             =               0x00,
  LIS3DH_SELF_TEST_0                   =               0x01,
  LIS3DH_SELF_TEST_1                   =               0x02
} LIS3DH_SelfTest_t;
typedef enum {
  LIS3DH_FIFO_BYPASS_MODE              =               0x00,
  LIS3DH_FIFO_MODE                     =               0x01,
  LIS3DH_FIFO_STREAM_MODE              =               0x02,
  LIS3DH_FIFO_TRIGGER_MODE             =               0x03,
  LIS3DH_FIFO_DISABLE                  =               0x04
} LIS3DH_FifoMode_t;
typedef enum {
  LIS3DH_TRIG_INT1                     =        0x00,
  LIS3DH_TRIG_INT2             =        0x01
} LIS3DH_TrigInt_t;
typedef enum {
  LIS3DH_SPI_4_WIRE                    =               0x00,
  LIS3DH_SPI_3_WIRE                    =               0x01
} LIS3DH_SPIMode_t;
typedef enum {
  LIS3DH_X_ENABLE                      =               0x01,
  LIS3DH_X_DISABLE                     =               0x00,
  LIS3DH_Y_ENABLE                      =               0x02,
  LIS3DH_Y_DISABLE                     =               0x00,
  LIS3DH_Z_ENABLE                      =               0x04,
  LIS3DH_Z_DISABLE                     =               0x00
} LIS3DH_AXISenable_t;
typedef enum {
  LIS3DH_INT1_6D_4D_DISABLE            =               0x00,
  LIS3DH_INT1_6D_ENABLE                =               0x01,
  LIS3DH_INT1_4D_ENABLE                =               0x02
} LIS3DH_INT_6D_4D_t;
typedef enum {
  LIS3DH_UP_SX                         =               0x44,
  LIS3DH_UP_DX                         =               0x42,
  LIS3DH_DW_SX                         =               0x41,
  LIS3DH_DW_DX                         =               0x48,
  LIS3DH_TOP                           =               0x60,
  LIS3DH_BOTTOM                        =               0x50
} LIS3DH_POSITION_6D_t;
typedef enum {
  LIS3DH_INT_MODE_OR                   =               0x00,
  LIS3DH_INT_MODE_6D_MOVEMENT          =               0x01,
  LIS3DH_INT_MODE_AND                  =               0x02,
  LIS3DH_INT_MODE_6D_POSITION          =               0x03
} LIS3DH_Int1Mode_t;
//interrupt click response
//  b7 = don't care   b6 = IA  b5 = DClick  b4 = Sclick  b3 = Sign
//  b2 = z      b1 = y     b0 = x
typedef enum {
LIS3DH_DCLICK_Z_P                      =               0x24,
LIS3DH_DCLICK_Z_N                      =               0x2C,
LIS3DH_SCLICK_Z_P                      =               0x14,
LIS3DH_SCLICK_Z_N                      =               0x1C,
LIS3DH_DCLICK_Y_P                      =               0x22,
LIS3DH_DCLICK_Y_N                      =               0x2A,
LIS3DH_SCLICK_Y_P                      =               0x12,
LIS3DH_SCLICK_Y_N            =        0x1A,
LIS3DH_DCLICK_X_P                      =               0x21,
LIS3DH_DCLICK_X_N                      =               0x29,
LIS3DH_SCLICK_X_P                      =               0x11,
LIS3DH_SCLICK_X_N                      =               0x19,
LIS3DH_NO_CLICK                        =               0x00
} LIS3DH_Click_Response;
//TODO: start from here and manage the shared macros etc before this
/* Exported constants --------------------------------------------------------*/
#ifndef __SHARED__CONSTANTS
#define __SHARED__CONSTANTS
#define MEMS_SET                                        0x01
#define MEMS_RESET                                      0x00
#endif /*__SHARED__CONSTANTS*/
//Register Definition
#define LIS3DH_WHO_AM_I                0x0F  // device identification register
// CONTROL REGISTER 1
#define LIS3DH_CTRL_REG1                0x20
#define LIS3DH_ODR_BIT                        BIT(4)
#define LIS3DH_LPEN                    BIT(3)
#define LIS3DH_ZEN                    BIT(2)
#define LIS3DH_YEN                    BIT(1)
#define LIS3DH_XEN                    BIT(0)
//CONTROL REGISTER 2
#define LIS3DH_CTRL_REG2                0x21
#define LIS3DH_HPM                     BIT(6)
#define LIS3DH_HPCF                    BIT(4)
#define LIS3DH_FDS                    BIT(3)
#define LIS3DH_HPCLICK                    BIT(2)
#define LIS3DH_HPIS2                    BIT(1)
#define LIS3DH_HPIS1                    BIT(0)
//CONTROL REGISTER 3
#define LIS3DH_CTRL_REG3                0x22
#define LIS3DH_I1_CLICK                BIT(7)
#define LIS3DH_I1_AOI1                    BIT(6)
#define LIS3DH_I1_AOI2                        BIT(5)
#define LIS3DH_I1_DRDY1                BIT(4)
#define LIS3DH_I1_DRDY2                BIT(3)
#define LIS3DH_I1_WTM                    BIT(2)
#define LIS3DH_I1_ORUN                    BIT(1)
//CONTROL REGISTER 6
#define LIS3DH_CTRL_REG6                0x25
#define LIS3DH_I2_CLICK                BIT(7)
#define LIS3DH_I2_INT1                    BIT(6)
#define LIS3DH_I2_BOOT                     BIT(4)
#define LIS3DH_H_LACTIVE                BIT(1)
//TEMPERATURE CONFIG REGISTER
#define LIS3DH_TEMP_CFG_REG                0x1F
#define LIS3DH_ADC_PD                        BIT(7)
#define LIS3DH_TEMP_EN                    BIT(6)
//CONTROL REGISTER 4
#define LIS3DH_CTRL_REG4                0x23
#define LIS3DH_BDU                    BIT(7)
#define LIS3DH_BLE                    BIT(6)
#define LIS3DH_FS                    BIT(4)
#define LIS3DH_HR                    BIT(3)
#define LIS3DH_ST                       BIT(1)
#define LIS3DH_SIM                    BIT(0)
//CONTROL REGISTER 5
#define LIS3DH_CTRL_REG5                0x24
#define LIS3DH_BOOT                                    BIT(7)
#define LIS3DH_FIFO_EN                                 BIT(6)
#define LIS3DH_LIR_INT1                                BIT(3)
#define LIS3DH_D4D_INT1                                BIT(2)
//REFERENCE/DATA_CAPTURE
#define LIS3DH_REFERENCE_REG                        0x26
#define LIS3DH_REF                            BIT(0)
//STATUS_REG_AXIES
#define LIS3DH_STATUS_REG                0x27
#define LIS3DH_ZYXOR                                   BIT(7)
#define LIS3DH_ZOR                                     BIT(6)
#define LIS3DH_YOR                                     BIT(5)
#define LIS3DH_XOR                                     BIT(4)
#define LIS3DH_ZYXDA                                   BIT(3)
#define LIS3DH_ZDA                                     BIT(2)
#define LIS3DH_YDA                                     BIT(1)
#define LIS3DH_XDA                                     BIT(0)
//STATUS_REG_AUX
#define LIS3DH_STATUS_AUX                0x07
//INTERRUPT 1 CONFIGURATION
#define LIS3DH_INT1_CFG                0x30
#define LIS3DH_ANDOR                                   BIT(7)
#define LIS3DH_INT_6D                                  BIT(6)
#define LIS3DH_ZHIE                                    BIT(5)
#define LIS3DH_ZLIE                                    BIT(4)
#define LIS3DH_YHIE                                    BIT(3)
#define LIS3DH_YLIE                                    BIT(2)
#define LIS3DH_XHIE                                    BIT(1)
#define LIS3DH_XLIE                                    BIT(0)
//FIFO CONTROL REGISTER
#define LIS3DH_FIFO_CTRL_REG                           0x2E
#define LIS3DH_FM                                      BIT(6)
#define LIS3DH_TR                                      BIT(5)
#define LIS3DH_FTH                                     BIT(0)
//CONTROL REG3 bit mask
#define LIS3DH_CLICK_ON_PIN_INT1_ENABLE                0x80
#define LIS3DH_CLICK_ON_PIN_INT1_DISABLE               0x00
#define LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE              0x40
#define LIS3DH_I1_INT1_ON_PIN_INT1_DISABLE             0x00
#define LIS3DH_I1_INT2_ON_PIN_INT1_ENABLE              0x20
#define LIS3DH_I1_INT2_ON_PIN_INT1_DISABLE             0x00
#define LIS3DH_I1_DRDY1_ON_INT1_ENABLE                 0x10
#define LIS3DH_I1_DRDY1_ON_INT1_DISABLE                0x00
#define LIS3DH_I1_DRDY2_ON_INT1_ENABLE                 0x08
#define LIS3DH_I1_DRDY2_ON_INT1_DISABLE                0x00
#define LIS3DH_WTM_ON_INT1_ENABLE                      0x04
#define LIS3DH_WTM_ON_INT1_DISABLE                     0x00
#define LIS3DH_INT1_OVERRUN_ENABLE                     0x02
#define LIS3DH_INT1_OVERRUN_DISABLE                    0x00
//CONTROL REG6 bit mask
#define LIS3DH_CLICK_ON_PIN_INT2_ENABLE                0x80
#define LIS3DH_CLICK_ON_PIN_INT2_DISABLE               0x00
#define LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE              0x40
#define LIS3DH_I2_INT1_ON_PIN_INT2_DISABLE             0x00
#define LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE              0x20
#define LIS3DH_I2_INT2_ON_PIN_INT2_DISABLE             0x00
#define LIS3DH_I2_BOOT_ON_INT2_ENABLE                  0x10
#define LIS3DH_I2_BOOT_ON_INT2_DISABLE                 0x00
#define LIS3DH_INT_ACTIVE_HIGH                         0x00
#define LIS3DH_INT_ACTIVE_LOW                          0x02
//INT1_CFG bit mask
#define LIS3DH_INT1_AND                                0x80
#define LIS3DH_INT1_OR                                 0x00
#define LIS3DH_INT1_ZHIE_ENABLE                        0x20
#define LIS3DH_INT1_ZHIE_DISABLE                       0x00
#define LIS3DH_INT1_ZLIE_ENABLE                        0x10
#define LIS3DH_INT1_ZLIE_DISABLE                       0x00
#define LIS3DH_INT1_YHIE_ENABLE                        0x08
#define LIS3DH_INT1_YHIE_DISABLE                       0x00
#define LIS3DH_INT1_YLIE_ENABLE                        0x04
#define LIS3DH_INT1_YLIE_DISABLE                       0x00
#define LIS3DH_INT1_XHIE_ENABLE                        0x02
#define LIS3DH_INT1_XHIE_DISABLE                       0x00
#define LIS3DH_INT1_XLIE_ENABLE                        0x01
#define LIS3DH_INT1_XLIE_DISABLE                       0x00
//INT1_SRC bit mask
#define LIS3DH_INT1_SRC_IA                             0x40
#define LIS3DH_INT1_SRC_ZH                             0x20
#define LIS3DH_INT1_SRC_ZL                             0x10
#define LIS3DH_INT1_SRC_YH                             0x08
#define LIS3DH_INT1_SRC_YL                             0x04
#define LIS3DH_INT1_SRC_XH                             0x02
#define LIS3DH_INT1_SRC_XL                             0x01
//INT1 REGISTERS
#define LIS3DH_INT1_THS                                0x32
#define LIS3DH_INT1_DURATION                           0x33
//INTERRUPT 1 SOURCE REGISTER
#define LIS3DH_INT1_SRC                0x31
//FIFO Source Register bit Mask
#define LIS3DH_FIFO_SRC_WTM                            0x80
#define LIS3DH_FIFO_SRC_OVRUN                          0x40
#define LIS3DH_FIFO_SRC_EMPTY                          0x20
//INTERRUPT CLICK REGISTER
#define LIS3DH_CLICK_CFG                0x38
//INTERRUPT CLICK CONFIGURATION bit mask
#define LIS3DH_ZD_ENABLE                               0x20
#define LIS3DH_ZD_DISABLE                              0x00
#define LIS3DH_ZS_ENABLE                               0x10
#define LIS3DH_ZS_DISABLE                              0x00
#define LIS3DH_YD_ENABLE                               0x08
#define LIS3DH_YD_DISABLE                              0x00
#define LIS3DH_YS_ENABLE                               0x04
#define LIS3DH_YS_DISABLE                              0x00
#define LIS3DH_XD_ENABLE                               0x02
#define LIS3DH_XD_DISABLE                              0x00
#define LIS3DH_XS_ENABLE                               0x01
#define LIS3DH_XS_DISABLE                              0x00
//INTERRUPT CLICK SOURCE REGISTER
#define LIS3DH_CLICK_SRC                               0x39
//INTERRUPT CLICK SOURCE REGISTER bit mask
#define LIS3DH_IA                                      0x40
#define LIS3DH_DCLICK                                  0x20
#define LIS3DH_SCLICK                                  0x10
#define LIS3DH_CLICK_SIGN                              0x08
#define LIS3DH_CLICK_Z                                 0x04
#define LIS3DH_CLICK_Y                                 0x02
#define LIS3DH_CLICK_X                                 0x01
//Click-click Register
#define LIS3DH_CLICK_THS                               0x3A
#define LIS3DH_TIME_LIMIT                              0x3B
#define LIS3DH_TIME_LATENCY                            0x3C
#define LIS3DH_TIME_WINDOW                             0x3D
//OUTPUT REGISTER
#define LIS3DH_OUT_X_L                    0x28
#define LIS3DH_OUT_X_H                    0x29
#define LIS3DH_OUT_Y_L                    0x2A
#define LIS3DH_OUT_Y_H                    0x2B
#define LIS3DH_OUT_Z_L                    0x2C
#define LIS3DH_OUT_Z_H                    0x2D
//AUX REGISTER
#define LIS3DH_OUT_1_L                    0x08
#define LIS3DH_OUT_1_H                    0x09
#define LIS3DH_OUT_2_L                    0x0A
#define LIS3DH_OUT_2_H                    0x0B
#define LIS3DH_OUT_3_L                    0x0C
#define LIS3DH_OUT_3_H                    0x0D
//STATUS REGISTER bit mask
#define LIS3DH_STATUS_REG_ZYXOR                        0x80    // 1    :    new data set has over written the previous one
                            // 0    :    no overrun has occurred (default)
#define LIS3DH_STATUS_REG_ZOR                          0x40    // 0    :    no overrun has occurred (default)
                            // 1    :    new Z-axis data has over written the previous one
#define LIS3DH_STATUS_REG_YOR                          0x20    // 0    :    no overrun has occurred (default)
                            // 1    :    new Y-axis data has over written the previous one
#define LIS3DH_STATUS_REG_XOR                          0x10    // 0    :    no overrun has occurred (default)
                            // 1    :    new X-axis data has over written the previous one
#define LIS3DH_STATUS_REG_ZYXDA                        0x08    // 0    :    a new set of data is not yet avvious one
                                                        // 1    :    a new set of data is available
#define LIS3DH_STATUS_REG_ZDA                          0x04    // 0    :    a new data for the Z-Axis is not availvious one
                                                        // 1    :    a new data for the Z-Axis is available
#define LIS3DH_STATUS_REG_YDA                          0x02    // 0    :    a new data for the Y-Axis is not available
                                                        // 1    :    a new data for the Y-Axis is available
#define LIS3DH_STATUS_REG_XDA                          0x01    // 0    :    a new data for the X-Axis is not available
#define LIS3DH_DATAREADY_BIT                           LIS3DH_STATUS_REG_ZYXDA
//STATUS AUX REGISTER bit mask
#define LIS3DH_STATUS_AUX_321OR                         0x80
#define LIS3DH_STATUS_AUX_3OR                           0x40
#define LIS3DH_STATUS_AUX_2OR                           0x20
#define LIS3DH_STATUS_AUX_1OR                           0x10
#define LIS3DH_STATUS_AUX_321DA                         0x08
#define LIS3DH_STATUS_AUX_3DA                           0x04
#define LIS3DH_STATUS_AUX_2DA                           0x02
#define LIS3DH_STATUS_AUX_1DA                           0x01
#define LIS3DH_MEMS_I2C_ADDRESS                    0x33
//FIFO REGISTERS
#define LIS3DH_FIFO_CTRL_REG                    0x2E
#define LIS3DH_FIFO_SRC_REG                    0x2F
/* Exported macro ------------------------------------------------------------*/
#ifndef __SHARED__MACROS
#define __SHARED__MACROS
#define ValBit(VAR,Place)         (VAR & (1<<Place))
#define BIT(x) ( (x) )
#endif /*__SHARED__MACROS*/
/* Exported functions --------------------------------------------------------*/
//Sensor Configuration Functions
status_t LIS3DH_SetODR(LIS3DH_ODR_t ov);
status_t LIS3DH_SetMode(LIS3DH_Mode_t md);
status_t LIS3DH_SetAxis(LIS3DH_Axis_t axis);
status_t LIS3DH_SetFullScale(LIS3DH_Fullscale_t fs);
status_t LIS3DH_SetBDU(State_t bdu);
status_t LIS3DH_SetBLE(LIS3DH_Endianess_t ble);
status_t LIS3DH_SetSelfTest(LIS3DH_SelfTest_t st);
status_t LIS3DH_SetTemperature(State_t state);
status_t LIS3DH_SetADCAux(State_t state);
//Filtering Functions
status_t LIS3DH_HPFClickEnable(State_t hpfe);
status_t LIS3DH_HPFAOI1Enable(State_t hpfe);
status_t LIS3DH_HPFAOI2Enable(State_t hpfe);
status_t LIS3DH_SetHPFMode(LIS3DH_HPFMode_t hpf);
status_t LIS3DH_SetHPFCutOFF(LIS3DH_HPFCutOffFreq_t hpf);
status_t LIS3DH_SetFilterDataSel(State_t state);
//Interrupt Functions
status_t LIS3DH_SetInt1Pin(LIS3DH_IntPinConf_t pinConf);
status_t LIS3DH_SetInt2Pin(LIS3DH_IntPinConf_t pinConf);
status_t LIS3DH_Int1LatchEnable(State_t latch);
status_t LIS3DH_ResetInt1Latch(void);
status_t LIS3DH_SetIntConfiguration(LIS3DH_Int1Conf_t ic);
status_t LIS3DH_SetInt1Threshold(uint8_t ths);
status_t LIS3DH_SetInt1Duration(LIS3DH_Int1Conf_t id);
status_t LIS3DH_SetIntMode(LIS3DH_Int1Mode_t ic);
status_t LIS3DH_SetClickCFG(uint8_t status);
status_t LIS3DH_SetInt6D4DConfiguration(LIS3DH_INT_6D_4D_t ic);
status_t LIS3DH_GetInt1Src(uint8_t* val);
status_t LIS3DH_GetInt1SrcBit(uint8_t statusBIT, uint8_t* val);
//FIFO Functions
status_t LIS3DH_FIFOModeEnable(LIS3DH_FifoMode_t fm);
status_t LIS3DH_SetWaterMark(uint8_t wtm);
status_t LIS3DH_SetTriggerInt(LIS3DH_TrigInt_t tr);
status_t LIS3DH_GetFifoSourceReg(uint8_t* val);
status_t LIS3DH_GetFifoSourceBit(uint8_t statusBIT, uint8_t* val);
status_t LIS3DH_GetFifoSourceFSS(uint8_t* val);
//Other Reading Functions
status_t LIS3DH_GetStatusReg(uint8_t* val);
status_t LIS3DH_GetStatusBit(uint8_t statusBIT, uint8_t* val);
status_t LIS3DH_GetStatusAUXBit(uint8_t statusBIT, uint8_t* val);
status_t LIS3DH_GetStatusAUX(uint8_t* val);
status_t LIS3DH_GetAccAxesRaw(AxesRaw_t* buff);
status_t LIS3DH_GetAuxRaw(LIS3DH_Aux123Raw_t* buff);
status_t LIS3DH_GetClickResponse(uint8_t* val);
status_t LIS3DH_GetTempRaw(int8_t* val);
status_t LIS3DH_GetWHO_AM_I(uint8_t* val);
status_t LIS3DH_Get6DPosition(uint8_t* val);
//Generic
// i.e. uint8_t LIS3DH_ReadReg(uint8_t Reg, uint8_t* Data);
// i.e. uint8_t LIS3DH_WriteReg(uint8_t Reg, uint8_t Data);
#endif /* __LIS3DH_H */
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/
Src/decadriver/dw_driver.c
Src/decadriver/dw_driver.h