From 88fead50b413489e979e08dfc53241e40e11515a Mon Sep 17 00:00:00 2001 From: zhyinch <zhyinch@gmail.com> Date: 星期三, 06 一月 2021 10:40:01 +0800 Subject: [PATCH] Merge branch '定位临近_工卡' into 定位-临近 --- Src/ExternalDevices/lis3dh_driver.h | 566 ++++++++ Src/decadriver/dw_driver.c | 0 .gitignore | 3 Drivers/ExternlDrivers/dps310.h | 343 ++++ Src/ExternalDevices/dps368_test.c | 147 ++ Drivers/ExternlDrivers/dps310.c | 380 +++++ MDK-ARM/L051/L051.lnp | 4 Src/ExternalDevices/lis3dh_driver.c | 1995 ++++++++++++++++++++++++++++ Src/ExternalDevices/dps310.c | 380 +++++ Src/decadriver/dw_driver.h | 0 Src/ExternalDevices/dps310.h | 341 ++++ 11 files changed, 4,158 insertions(+), 1 deletions(-) diff --git a/.gitignore b/.gitignore index b961c09..fb11c53 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ *.axf *.d MDK-ARM/L051/L051.htm +MDK-ARM/JLinkLog.txt +*.txt +*.txt diff --git a/Drivers/ExternlDrivers/dps310.c b/Drivers/ExternlDrivers/dps310.c new file mode 100644 index 0000000..18224f1 --- /dev/null +++ b/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; + +} diff --git a/Drivers/ExternlDrivers/dps310.h b/Drivers/ExternlDrivers/dps310.h new file mode 100644 index 0000000..4692111 --- /dev/null +++ b/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 diff --git a/MDK-ARM/L051/L051.lnp b/MDK-ARM/L051/L051.lnp index 8d53228..1076272 100644 --- a/MDK-ARM/L051/L051.lnp +++ b/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" diff --git a/Src/ExternalDevices/dps310.c b/Src/ExternalDevices/dps310.c new file mode 100644 index 0000000..18224f1 --- /dev/null +++ b/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; + +} diff --git a/Src/ExternalDevices/dps310.h b/Src/ExternalDevices/dps310.h new file mode 100644 index 0000000..343374a --- /dev/null +++ b/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 diff --git a/Src/ExternalDevices/dps368_test.c b/Src/ExternalDevices/dps368_test.c new file mode 100644 index 0000000..523374a --- /dev/null +++ b/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); + } \ No newline at end of file diff --git a/Src/ExternalDevices/lis3dh_driver.c b/Src/ExternalDevices/lis3dh_driver.c new file mode 100644 index 0000000..7f92a91 --- /dev/null +++ b/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****/ + diff --git a/Src/ExternalDevices/lis3dh_driver.h b/Src/ExternalDevices/lis3dh_driver.h new file mode 100644 index 0000000..ffd4de5 --- /dev/null +++ b/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****/ + + + diff --git a/Src/ExternalDevices/dw_driver.c b/Src/decadriver/dw_driver.c similarity index 100% rename from Src/ExternalDevices/dw_driver.c rename to Src/decadriver/dw_driver.c diff --git a/Src/ExternalDevices/dw_driver.h b/Src/decadriver/dw_driver.h similarity index 100% rename from Src/ExternalDevices/dw_driver.h rename to Src/decadriver/dw_driver.h -- Gitblit v1.9.3