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