h3 imported to make Bob work
Revision 0:a9de25fd7c41, committed 2015-10-23
- Comitter:
- daveheitzman
- Date:
- Fri Oct 23 18:26:28 2015 +0000
- Commit message:
- publishing mDot_Bob
Changed in this revision
H3LIS331DL.cpp | Show annotated file Show diff for this revision Revisions of this file |
H3LIS331DL.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/H3LIS331DL.cpp Fri Oct 23 18:26:28 2015 +0000 @@ -0,0 +1,1307 @@ +/* + * H3LIS331DL.cpp + * A library for 3-Axis Digital Accelerometer(±400g) + * + * Copyright (c) 2014 seeed technology inc. + * Website : www.seeed.cc + * Author : lawliet zou + * Create Time: April 2014 + * Change Log : + * + * The MIT License (MIT) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "H3LIS331DL.h" + +void H3LIS331DL::init(H3LIS331DL_ODR_t odr,H3LIS331DL_Mode_t mode,H3LIS331DL_Fullscale_t fullScale) +{ + //set output data rate + setODR(odr); + //set PowerMode + setMode( mode); + //set Fullscale + setFullScale( fullScale); + //set axis Enable + setAxis( H3LIS331DL_X_ENABLE | H3LIS331DL_Y_ENABLE | H3LIS331DL_Z_ENABLE); +} + +void H3LIS331DL::importPara(int16_t val_x, int16_t val_y, int16_t val_z) +{ + _adjVal[0] = val_x; + _adjVal[1] = val_y; + _adjVal[2] = val_z; +} +void H3LIS331DL::readXYZ(int16_t* x, int16_t* y, int16_t* z) +{ + //get Acceleration Raw data + AxesRaw_t data; + status_t response = getAccAxesRaw(&data); + if(MEMS_SUCCESS == response){ + *x = (data.AXIS_X - _adjVal[0]); + *y = (data.AXIS_Y - _adjVal[1]); + *z = (data.AXIS_Z - _adjVal[2]); + } +} + +void H3LIS331DL::getAcceleration(float* xyz) +{ + AxesRaw_t data; + double gains = 0.003; + getAccAxesRaw(&data); + + xyz[0] = (data.AXIS_X - _adjVal[0]) * gains; + xyz[1] = (data.AXIS_Y - _adjVal[1]) * gains; + xyz[2] = (data.AXIS_Z - _adjVal[2]) * gains; +} + + +/******************************************************************************* +* Function Name : getWHO_AM_I +* Description : Read identification code from H3LIS331DL::WHO_AM_I register +* Input : char to be filled with the Device identification Value +* Output : None +* Return : Status [value of FSS] +*******************************************************************************/ +status_t H3LIS331DL::getWHO_AM_I(uint8_t* val){ + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_WHO_AM_I, val) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setODR +* Description : Sets H3LIS331DL Accelerometer Output Data Rate +* Input : Output Data Rate +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setODR(H3LIS331DL_ODR_t dr){ + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, &value) ) + return MEMS_ERROR; + + value &= 0xE7; + value |= dr<<H3LIS331DL_DR; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setMode +* Description : Sets H3LIS331DLH Accelerometer Operating Mode +* Input : Modality (H3LIS331DL_LOW_POWER, H3LIS331DL_NORMAL, H3LIS331DL_POWER_DOWN...) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setMode(H3LIS331DL_Mode_t pm) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, &value) ) + return MEMS_ERROR; + + value &= 0x1F; + value |= (pm<<H3LIS331DL_PM); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + +/******************************************************************************* +* Function Name : setAxis +* Description : Enable/Disable LIS331DLH Axis +* Input : H3LIS331DL_X_ENABLE/H3LIS331DL_X_DISABLE | H3LIS331DL_Y_ENABLE/H3LIS331DL_Y_DISABLE + | H3LIS331DL_Z_ENABLE/H3LIS331DL_Z_DISABLE +* Output : None +* Note : You MUST use all input variable in the argument, as example +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setAxis(H3LIS331DL_Axis_t axis) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, &value) ) + return MEMS_ERROR; + + value &= 0xF8; + value |= (0x07 & axis); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setFullScale +* Description : Sets the LIS331DLH FullScale +* Input : H3LIS331DL_FULLSCALE_2/H3LIS331DL_FULLSCALE_4/H3LIS331DL_FULLSCALE_8 +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setFullScale(H3LIS331DL_Fullscale_t fs) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0xCF; + value |= (fs<<H3LIS331DL_FS); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setBDU +* Description : Enable/Disable Block Data Update Functionality +* Input : MEMS_ENABLE/MEMS_DISABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setBDU(State_t bdu) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0x7F; + value |= (bdu<<H3LIS331DL_BDU); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setBLE +* Description : Set Endianess (MSB/LSB) +* Input : H3LIS331DL_BLE_LSB / H3LIS331DL_BLE_MSB +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setBLE(H3LIS331DL_Endianess_t ble) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0xBF; + value |= (ble<<H3LIS331DL_BLE); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setFDS +* Description : Set Filter Data Selection +* Input : MEMS_ENABLE/MEMS_DISABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setFDS(State_t fds) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0xEF; + value |= (fds<<H3LIS331DL_FDS); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setBOOT +* Description : Rebot memory content +* Input : MEMS_ENABLE/MEMS_DISABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setBOOT(State_t boot) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0x7F; + value |= (boot<<H3LIS331DL_BOOT); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setSelfTest +* Description : Set Self Test Modality +* Input : MEMS_DISABLE/MEMS_ENABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setSelfTest(State_t st) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0xFD; + value |= (st<<H3LIS331DL_ST); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setSelfTestSign +* Description : Set Self Test Sign (Disable = st_plus, Enable = st_minus) +* Input : MEMS_DISABLE/MEMS_ENABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setSelfTestSign(State_t st_sign) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0xF7; + value |= (st_sign<<H3LIS331DL_ST_SIGN); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setIntHighLow +* Description : Set Interrupt active state (Disable = active high, Enable = active low) +* Input : MEMS_DISABLE/MEMS_ENABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setIntHighLow(State_t ihl) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0x7F; + value |= (ihl<<H3LIS331DL_IHL); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setIntPPOD +* Description : Set Interrupt Push-Pull/OpenDrain Pad (Disable = Push-Pull, Enable = OpenDrain) +* Input : MEMS_DISABLE/MEMS_ENABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setIntPPOD(State_t pp_od) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0xBF; + value |= (pp_od<<H3LIS331DL_PP_OD); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1DataSign +* Description : Set Data signal Interrupt 1 pad +* Input : Modality by H3LIS331DL_INT_Conf_t Typedef + (H3LIS331DL_INT_SOURCE, H3LIS331DL_INT_1OR2_SOURCE, H3LIS331DL_DATA_READY, H3LIS331DL_BOOT_RUNNING) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1DataSign(H3LIS331DL_INT_Conf_t i_cfg) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0xFC; + value |= (i_cfg<<H3LIS331DL_I1_CFG); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt2DataSign +* Description : Set Data signal Interrupt 2 pad +* Input : Modality by H3LIS331DL_INT_Conf_t Typedef + (H3LIS331DL_INT_SOURCE, H3LIS331DL_INT_1OR2_SOURCE, H3LIS331DL_DATA_READY, H3LIS331DL_BOOT_RUNNING) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt2DataSign(H3LIS331DL_INT_Conf_t i_cfg) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0xE7; + value |= (i_cfg<<H3LIS331DL_I2_CFG); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setSPI34Wire +* Description : Set SPI mode +* Input : Modality by H3LIS331DL_SPIMode_t Typedef (H3LIS331DL_SPI_4_WIRE, H3LIS331DL_SPI_3_WIRE) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setSPI34Wire(H3LIS331DL_SPIMode_t sim) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, &value) ) + return MEMS_ERROR; + + value &= 0xFE; + value |= (sim<<H3LIS331DL_SIM); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG4, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : turnONEnable +* Description : TurnON Mode selection for sleep to wake function +* Input : H3LIS331DL_SLEEP_TO_WAKE_DIS/H3LIS331DL_SLEEP_TO_WAKE_ENA +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::turnONEnable(H3LIS331DL_Sleep_To_Wake_Conf_t stw) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG5, &value) ) + return MEMS_ERROR; + + value &= 0x00; + value |= (stw<<H3LIS331DL_TURN_ON); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG5, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + +#if 0 +/******************************************************************************* +* Function Name : HPFilterReset +* Description : Reading register for reset the content of internal HP filter +* Input : None +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::HPFilterReset(void) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_HP_FILTER_RESET, &value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} +#endif + +/******************************************************************************* +* Function Name : setReference +* Description : Sets Reference register acceleration value as a reference for HP filter +* Input : Value of reference acceleration value (0-255) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setReference(int8_t ref) { + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_REFERENCE_REG, ref) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setHPFMode +* Description : Set High Pass Filter Modality +* Input : H3LIS331DL_HPM_NORMAL_MODE_RES/H3LIS331DL_HPM_REF_SIGNAL/H3LIS331DL_HPM_NORMAL_MODE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setHPFMode(H3LIS331DL_HPFMode_t hpm) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0x9F; + value |= (hpm<<H3LIS331DL_HPM); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setHPFCutOFF +* Description : Set High Pass CUT OFF Freq +* Input : H3LIS331DL_HPFCF [0,3] +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setHPFCutOFF(H3LIS331DL_HPFCutOffFreq_t hpf) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0xFC; + value |= (hpf<<H3LIS331DL_HPCF); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; + +} + + +/******************************************************************************* +* Function Name : setInt2HPEnable +* Description : Set Interrupt2 hp filter enable/disable +* Input : MEMS_ENABLE/MEMS_DISABLE +* example : H3LIS331DL_SetInt2HPEnable(MEMS_ENABLE) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt2HPEnable(State_t stat) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0xF7; + value |= stat<<H3LIS331DL_HPEN2 ; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1HPEnable +* Description : Set Interrupt1 hp filter enable/disable +* Input : MEMS_ENABLE/MEMS_DISABLE +* example : H3LIS331DL_SetInt1HPEnable(MEMS_ENABLE) +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1HPEnable(State_t stat) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, &value) ) + return MEMS_ERROR; + + value &= 0xFB; + value |= stat<<H3LIS331DL_HPEN1 ; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG2, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : int1LatchEnable +* Description : Enable Interrupt 1 Latching function +* Input : ENABLE/DISABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::int1LatchEnable(State_t latch) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0xFB; + value |= latch<<H3LIS331DL_LIR1; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : int2LatchEnable +* Description : Enable Interrupt 2 Latching function +* Input : ENABLE/DISABLE +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::int2LatchEnable(State_t latch) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, &value) ) + return MEMS_ERROR; + + value &= 0xDF; + value |= latch<<H3LIS331DL_LIR2; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG3, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : resetInt1Latch +* Description : Reset Interrupt 1 Latching function +* Input : None +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::resetInt1Latch(void) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, &value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : resetInt2Latch +* Description : Reset Interrupt 2 Latching function +* Input : None +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::resetInt2Latch(void) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, &value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1Configuration +* Description : Interrupt 1 Configuration (without 6D_INT) +* Input : H3LIS331DL_INT_AND/OR | H3LIS331DL_INT_ZHIE_ENABLE/DISABLE | H3LIS331DL_INT_ZLIE_ENABLE/DISABLE... +* Output : None +* Note : You MUST use ALL input variable in the argument, as in example above +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1Configuration(H3LIS331DL_IntConf_t ic) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_CFG, &value) ) + return MEMS_ERROR; + + value &= 0x40; + value |= ic; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_CFG, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt2Configuration +* Description : Interrupt 2 Configuration (without 6D_INT) +* Input : H3LIS331DL_INT_AND/OR | H3LIS331DL_INT_ZHIE_ENABLE/DISABLE | H3LIS331DL_INT_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 H3LIS331DL::setInt2Configuration(H3LIS331DL_IntConf_t ic) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_CFG, &value) ) + return MEMS_ERROR; + + value &= 0x40; + value |= ic; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_CFG, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1Mode +* Description : Interrupt 1 Configuration mode (OR, 6D Movement, AND, 6D Position) +* Input : H3LIS331DL_INT_MODE_OR, H3LIS331DL_INT_MODE_6D_MOVEMENT, H3LIS331DL_INT_MODE_AND, H3LIS331DL_INT_MODE_6D_POSITION +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1Mode(H3LIS331DL_IntMode_t int_mode) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_CFG, &value) ) + return MEMS_ERROR; + + value &= 0x3F; + value |= (int_mode<<H3LIS331DL_INT_6D); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_CFG, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt2Mode +* Description : Interrupt 2 Configuration mode (OR, 6D Movement, AND, 6D Position) +* Input : H3LIS331DL_INT_MODE_OR, H3LIS331DL_INT_MODE_6D_MOVEMENT, H3LIS331DL_INT_MODE_AND, H3LIS331DL_INT_MODE_6D_POSITION +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt2Mode(H3LIS331DL_IntMode_t int_mode) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_CFG, &value) ) + return MEMS_ERROR; + + value &= 0x3F; + value |= (int_mode<<H3LIS331DL_INT_6D); + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_CFG, value) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : get6DPositionInt1 +* Description : 6D Interrupt 1 Position Detect +* Input : uint8_t to be filled with H3LIS331DL_POSITION_6D_t Typedef +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::get6DPositionInt1(uint8_t* val){ + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, &value) ) + return MEMS_ERROR; + + value &= 0x7F; + + switch (value){ + case H3LIS331DL_UP_SX: + *val = H3LIS331DL_UP_SX; + break; + case H3LIS331DL_UP_DX: + *val = H3LIS331DL_UP_DX; + break; + case H3LIS331DL_DW_SX: + *val = H3LIS331DL_DW_SX; + break; + case H3LIS331DL_DW_DX: + *val = H3LIS331DL_DW_DX; + break; + case H3LIS331DL_TOP: + *val = H3LIS331DL_TOP; + break; + case H3LIS331DL_BOTTOM: + *val = H3LIS331DL_BOTTOM; + break; + } + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : get6DPositionInt2 +* Description : 6D Interrupt 2 Position Detect +* Input : Byte to be filled with H3LIS331DL_POSITION_6D_t Typedef +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::get6DPositionInt2(uint8_t* val){ + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, &value) ) + return MEMS_ERROR; + + value &= 0x7F; + + switch (value){ + case H3LIS331DL_UP_SX: + *val = H3LIS331DL_UP_SX; + break; + case H3LIS331DL_UP_DX: + *val = H3LIS331DL_UP_DX; + break; + case H3LIS331DL_DW_SX: + *val = H3LIS331DL_DW_SX; + break; + case H3LIS331DL_DW_DX: + *val = H3LIS331DL_DW_DX; + break; + case H3LIS331DL_TOP: + *val = H3LIS331DL_TOP; + break; + case H3LIS331DL_BOTTOM: + *val = H3LIS331DL_BOTTOM; + break; + } + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1Threshold +* Description : Sets Interrupt 1 Threshold +* Input : Threshold = [0,127] +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1Threshold(uint8_t ths) { + if (ths > 127) + return MEMS_ERROR; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_THS, ths) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt1Duration +* Description : Sets Interrupt 1 Duration +* Input : Duration = [0,127] +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt1Duration(uint8_t id) { + if (id > 127) + return MEMS_ERROR; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_DURATION, id) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt2Threshold +* Description : Sets Interrupt 2 Threshold +* Input : Threshold = [0,127] +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt2Threshold(uint8_t ths) { + if (ths > 127) + return MEMS_ERROR; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_THS, ths) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : setInt2Duration +* Description : Sets Interrupt 2 Duration +* Input : Duration = [0,127] +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::setInt2Duration(uint8_t id) { + if (id > 127) + return MEMS_ERROR; + + if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_DURATION, id) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : getStatusReg +* Description : Read the status register +* Input : char to empty by Status Reg Value +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getStatusReg(uint8_t* val) { + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_STATUS_REG, val) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + +/******************************************************************************* +* Function Name : getStatusBIT +* Description : Read the status register BIT +* Input : H3LIS331DL_STATUS_REG_ZYXOR, H3LIS331DL_STATUS_REG_ZOR, H3LIS331DL_STATUS_REG_YOR, H3LIS331DL_STATUS_REG_XOR, + H3LIS331DL_STATUS_REG_ZYXDA, H3LIS331DL_STATUS_REG_ZDA, H3LIS331DL_STATUS_REG_YDA, H3LIS331DL_STATUS_REG_XDA, + H3LIS331DL_DATAREADY_BIT +* Output : status register BIT +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getStatusBit(uint8_t statusBIT, uint8_t *val) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_STATUS_REG, &value) ) + return MEMS_ERROR; + + switch (statusBIT){ + case H3LIS331DL_STATUS_REG_ZYXOR: + if(value &= H3LIS331DL_STATUS_REG_ZYXOR){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_ZOR: + if(value &= H3LIS331DL_STATUS_REG_ZOR){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_YOR: + if(value &= H3LIS331DL_STATUS_REG_YOR){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_XOR: + if(value &= H3LIS331DL_STATUS_REG_XOR){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_ZYXDA: + if(value &= H3LIS331DL_STATUS_REG_ZYXDA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_ZDA: + if(value &= H3LIS331DL_STATUS_REG_ZDA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_YDA: + if(value &= H3LIS331DL_STATUS_REG_YDA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + case H3LIS331DL_STATUS_REG_XDA: + if(value &= H3LIS331DL_STATUS_REG_XDA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + return MEMS_ERROR; +} + + +/******************************************************************************* +* Function Name : getAccAxesRaw +* Description : Read the Acceleration Values Output Registers +* Input : buffer to empty by AccAxesRaw_t Typedef +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getAccAxesRaw(AxesRaw_t* buff) { + uint8_t valueL = 0,valueH = 0; + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_X_L, &valueL); + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_X_H, &valueH); + buff->AXIS_X = (valueH<<8)|valueL; + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Y_L, &valueL); + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Y_H, &valueH); + buff->AXIS_Y = (valueH<<8)|valueL; + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Z_L, &valueL); + readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_OUT_Z_H, &valueH); + buff->AXIS_Z = (valueH<<8)|valueL; + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : getInt1Src +* Description : Reset Interrupt 1 Latching function +* Input : buffer to empty by Int1 Source Value +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getInt1Src(uint8_t* val) { + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, val) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : getInt2Src +* Description : Reset Interrupt 2 Latching function +* Input : buffer to empty by Int2 Source Value +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getInt2Src(uint8_t* val) { + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, val) ) + return MEMS_ERROR; + + return MEMS_SUCCESS; +} + + +/******************************************************************************* +* Function Name : getInt1SrcBit +* Description : Reset Interrupt 1 Latching function +* Input : H3LIS331DL_INT1_SRC_IA, H3LIS331DL_INT1_SRC_ZH, H3LIS331DL_INT1_SRC_ZL ..... +* Output : None +* Return : Status of BIT [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getInt1SrcBit(uint8_t statusBIT, uint8_t *val) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT1_SRC, &value) ) + return MEMS_ERROR; + + if(statusBIT == H3LIS331DL_INT_SRC_IA){ + if(value &= H3LIS331DL_INT_SRC_IA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_ZH){ + if(value &= H3LIS331DL_INT_SRC_ZH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_ZL){ + if(value &= H3LIS331DL_INT_SRC_ZL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_YH){ + if(value &= H3LIS331DL_INT_SRC_YH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_YL){ + if(value &= H3LIS331DL_INT_SRC_YL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_XH){ + if(value &= H3LIS331DL_INT_SRC_XH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_XL){ + if(value &= H3LIS331DL_INT_SRC_XL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + return MEMS_ERROR; +} + + +/******************************************************************************* +* Function Name : getInt2SrcBit +* Description : Reset Interrupt 2 Latching function +* Input : H3LIS331DL_INT_SRC_IA, H3LIS331DL_INT_SRC_ZH, H3LIS331DL_INT_SRC_ZL ..... +* Output : None +* Return : Status of BIT [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +status_t H3LIS331DL::getInt2SrcBit(uint8_t statusBIT, uint8_t *val) { + uint8_t value; + + if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_INT2_SRC, &value) ) + return MEMS_ERROR; + + if(statusBIT == H3LIS331DL_INT_SRC_IA){ + if(value &= H3LIS331DL_INT_SRC_IA){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_ZH){ + if(value &= H3LIS331DL_INT_SRC_ZH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_ZL){ + if(value &= H3LIS331DL_INT_SRC_ZL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_YH){ + if(value &= H3LIS331DL_INT_SRC_YH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_YL){ + if(value &= H3LIS331DL_INT_SRC_YL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_XH){ + if(value &= H3LIS331DL_INT_SRC_XH){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + + if(statusBIT == H3LIS331DL_INT_SRC_XL){ + if(value &= H3LIS331DL_INT_SRC_XL){ + *val = MEMS_SET; + return MEMS_SUCCESS; + } + else{ + *val = MEMS_RESET; + return MEMS_SUCCESS; + } + } + return MEMS_ERROR; +} + +/******************************************************************************* +* Function Name : readReg +* Description : Generic Reading function. It must be full filled with either +* : I2C or SPI reading functions +* Input : Register Address +* Output : Data Read +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +uint8_t H3LIS331DL::readReg(uint8_t deviceAddr, uint8_t Reg, uint8_t* Data) { + uint8_t result; + + result = i2c->write((deviceAddr << 1), (char *)&Reg, 1, true); + result |= i2c->read((deviceAddr << 1), (char *)Data, 2); + + if (result) { + return MEMS_ERROR; + } + else { + return MEMS_SUCCESS; + } +} + +/******************************************************************************* +* Function Name : writeReg +* Description : Generic Writing function. It must be full filled with either +* : I2C or SPI writing function +* Input : Register Address, Data to be written +* Output : None +* Return : Status [MEMS_ERROR, MEMS_SUCCESS] +*******************************************************************************/ +uint8_t H3LIS331DL::writeReg(uint8_t deviceAddress, uint8_t WriteAddr, uint8_t Data) { + uint8_t buf[2]; + uint8_t result; + + buf[0] = WriteAddr; + buf[1] = Data; + result = i2c->write((deviceAddress << 1), (char *)buf, 2); + + if (result) { + return MEMS_ERROR; + } + else { + return MEMS_SUCCESS; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/H3LIS331DL.h Fri Oct 23 18:26:28 2015 +0000 @@ -0,0 +1,349 @@ +/* + * H3LIS331DL.h + * A library for 3-Axis Digital Accelerometer(±400g) + * + * Copyright (c) 2014 seeed technology inc. + * Website : www.seeed.cc + * Author : lawliet zou + * Create Time: April 2014 + * Change Log : + * + * The MIT License (MIT) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "mbed.h" + +#ifndef H3LIS331DL_H +#define H3LIS331DL_H + +#define MEMS_SET 0x01 +#define MEMS_RESET 0x00 + +#define H3LIS331DL_MEMS_I2C_ADDRESS 0x18//0x32 + +//Register and define +#define H3LIS331DL_WHO_AM_I 0x0F // device identification register + +// CONTROL REGISTER 1 +#define H3LIS331DL_CTRL_REG1 0x20 +#define H3LIS331DL_PM BIT(5) //PowerMode selection: 000 - power down / 001 - normal mode / other - low power +#define H3LIS331DL_DR BIT(3) //output data rate: 00 - 50hz / 01 - 100hz / 10 - 400hz / 11 - 1000hz +#define H3LIS331DL_ZEN BIT(2) //Z-axis enable: 0 - disable / 1 - enable +#define H3LIS331DL_YEN BIT(1) //Y-axis enable: 0 - disable / 1 - enable +#define H3LIS331DL_XEN BIT(0) //Y-axis enable: 0 - disable / 1 - enable + +//CONTROL REGISTER 2 +#define H3LIS331DL_CTRL_REG2 0x21 +#define H3LIS331DL_BOOT BIT(7) //reboot memory content, default is 0 +#define H3LIS331DL_HPM BIT(5) //High-pass-filter mode selection, default is 00 +#define H3LIS331DL_FDS BIT(4) //Filter data selection, default is 0 +#define H3LIS331DL_HPEN2 BIT(3) //High-pass filter enabled for interrupt 2 source, default is 0 +#define H3LIS331DL_HPEN1 BIT(2) //High-pass filter enabled for interrupt 1 source, default is 0 +#define H3LIS331DL_HPCF BIT(0) //High-pass filter cutoff frequency configuration, default is 00 + +//CONTROL REGISTER 3 +#define H3LIS331DL_CTRL_REG3 0x22 +#define H3LIS331DL_IHL BIT(7) //Interrupt active high,low. default is 0 +#define H3LIS331DL_PP_OD BIT(6) //Push-pull/open drain selection on interrupt pad. default is 0 +#define H3LIS331DL_LIR2 BIT(5) //Latch interrupt request on INT2_SRC register, with INT2_SRC register cleared by read INT2_SRC itself. default is 0 +#define H3LIS331DL_I2_CFG BIT(3) //Data signal on INT2 pad control bits, default is 00 +#define H3LIS331DL_LIR1 BIT(2) //Latch interrupt request on the INT1_SRC register, with the INT1_SRC register cleared by reading the INT1_SRC register. +#define H3LIS331DL_I1_CFG BIT(0) //Data signal on INT1 pad control bits, default is 00 + +//CONTROL REGISTER 4 +#define H3LIS331DL_CTRL_REG4 0x23 +#define H3LIS331DL_BDU BIT(7) //Block data update, default is 0 +#define H3LIS331DL_BLE BIT(6) //Big/little endian data selection, default is 0 +#define H3LIS331DL_FS BIT(4) //Full scale selection, default is 00(00:100g;01:200g;11:400g) +#define H3LIS331DL_ST_SIGN BIT(3) // +#define H3LIS331DL_ST BIT(1) // +#define H3LIS331DL_SIM BIT(0) // SPI serial interface mode selection, default is 0 + +//CONTROL REGISTER 5 +#define H3LIS331DL_CTRL_REG5 0x24 +#define H3LIS331DL_TURN_ON BIT(0) // Turn-on mode selection selection for sleep to wake function. default is 00 + +#define H3LIS331DL_HP_FILTER_RESET 0x25 // + +//REFERENCE/DATA_CAPTURE +#define H3LIS331DL_REFERENCE_REG 0x26 // +#define H3LIS331DL_REF BIT(0) // + +//STATUS_REG_AXIES +#define H3LIS331DL_STATUS_REG 0x27 // + +//OUTPUT REGISTER +#define H3LIS331DL_OUT_X_L 0x28 //x-axis acceleration data +#define H3LIS331DL_OUT_X_H 0x29 +#define H3LIS331DL_OUT_Y_L 0x2A //y-axis acceleration data +#define H3LIS331DL_OUT_Y_H 0x2B +#define H3LIS331DL_OUT_Z_L 0x2C //z-axis acceleration data +#define H3LIS331DL_OUT_Z_H 0x2D + + +//INTERRUPT 1 CONFIGURATION +#define H3LIS331DL_INT1_CFG 0x30 + +//INTERRUPT 2 CONFIGURATION +#define H3LIS331DL_INT2_CFG 0x34 +#define H3LIS331DL_ANDOR BIT(7) +#define H3LIS331DL_INT_6D BIT(6) + +//INT REGISTERS +#define H3LIS331DL_INT1_THS 0x32 +#define H3LIS331DL_INT1_DURATION 0x33 +#define H3LIS331DL_INT2_THS 0x36 +#define H3LIS331DL_INT2_DURATION 0x37 + +//INTERRUPT 1 SOURCE REGISTER +#define H3LIS331DL_INT1_SRC 0x31 +#define H3LIS331DL_INT2_SRC 0x35 + +//INT_CFG bit mask +#define H3LIS331DL_INT_AND 0x80 +#define H3LIS331DL_INT_OR 0x00 +#define H3LIS331DL_INT_ZHIE_ENABLE 0x20 +#define H3LIS331DL_INT_ZHIE_DISABLE 0x00 +#define H3LIS331DL_INT_ZLIE_ENABLE 0x10 +#define H3LIS331DL_INT_ZLIE_DISABLE 0x00 +#define H3LIS331DL_INT_YHIE_ENABLE 0x08 +#define H3LIS331DL_INT_YHIE_DISABLE 0x00 +#define H3LIS331DL_INT_YLIE_ENABLE 0x04 +#define H3LIS331DL_INT_YLIE_DISABLE 0x00 +#define H3LIS331DL_INT_XHIE_ENABLE 0x02 +#define H3LIS331DL_INT_XHIE_DISABLE 0x00 +#define H3LIS331DL_INT_XLIE_ENABLE 0x01 +#define H3LIS331DL_INT_XLIE_DISABLE 0x00 + +//INT_SRC bit mask +#define H3LIS331DL_INT_SRC_IA 0x40 +#define H3LIS331DL_INT_SRC_ZH 0x20 +#define H3LIS331DL_INT_SRC_ZL 0x10 +#define H3LIS331DL_INT_SRC_YH 0x08 +#define H3LIS331DL_INT_SRC_YL 0x04 +#define H3LIS331DL_INT_SRC_XH 0x02 +#define H3LIS331DL_INT_SRC_XL 0x01 + +//STATUS REGISTER bit mask +#define H3LIS331DL_STATUS_REG_ZYXOR 0x80 // 1:new data set has over written the previous one + // 0:no overrun has occurred (default) +#define H3LIS331DL_STATUS_REG_ZOR 0x40 // 0:no overrun has occurred (default) + // 1:new Z-axis data has over written the previous one +#define H3LIS331DL_STATUS_REG_YOR 0x20 // 0:no overrun has occurred (default) + // 1:new Y-axis data has over written the previous one +#define H3LIS331DL_STATUS_REG_XOR 0x10 // 0:no overrun has occurred (default) + // 1:new X-axis data has over written the previous one +#define H3LIS331DL_STATUS_REG_ZYXDA 0x08 // 0:a new set of data is not yet avvious one + // 1:a new set of data is available +#define H3LIS331DL_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 H3LIS331DL_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 H3LIS331DL_STATUS_REG_XDA 0x01 // 0:a new data for the X-Axis is not available + // 1:a new data for the X-Axis is available +#define H3LIS331DL_DATAREADY_BIT H3LIS331DL_STATUS_REG_ZYXDA + +#define ValBit(VAR,Place) (VAR & (1<<Place)) +#define BIT(x) ( (x) ) + +typedef uint8_t H3LIS331DL_Axis_t; +typedef uint8_t H3LIS331DL_IntConf_t; + +//define structure +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; + +typedef enum { + H3LIS331DL_ODR_50Hz = 0x00, + H3LIS331DL_ODR_100Hz = 0x01, + H3LIS331DL_ODR_400Hz = 0x02, + H3LIS331DL_ODR_1000Hz = 0x03 +} H3LIS331DL_ODR_t; + +typedef enum { + H3LIS331DL_CONTINUOUS_MODE = 0x00, + H3LIS331DL_SINGLE_MODE = 0x01, + H3LIS331DL_SLEEP_MODE = 0x02 +} H3LIS331DL_Mode_M_t; + +typedef enum { + H3LIS331DL_POWER_DOWN = 0x00, + H3LIS331DL_NORMAL = 0x01, + H3LIS331DL_LOW_POWER_05 = 0x02, + H3LIS331DL_LOW_POWER_1 = 0x03, + H3LIS331DL_LOW_POWER_2 = 0x04, + H3LIS331DL_LOW_POWER_5 = 0x05, + H3LIS331DL_LOW_POWER_10 = 0x06, +} H3LIS331DL_Mode_t; + +typedef enum { + H3LIS331DL_HPM_NORMAL_MODE_RES = 0x00, + H3LIS331DL_HPM_REF_SIGNAL = 0x01, + H3LIS331DL_HPM_NORMAL_MODE = 0x02, +} H3LIS331DL_HPFMode_t; + +typedef enum { + H3LIS331DL_HPFCF_0 = 0x00, + H3LIS331DL_HPFCF_1 = 0x01, + H3LIS331DL_HPFCF_2 = 0x02, + H3LIS331DL_HPFCF_3 = 0x03, +} H3LIS331DL_HPFCutOffFreq_t; + +typedef enum { + H3LIS331DL_INT_SOURCE = 0x00, + H3LIS331DL_INT_1OR2_SOURCE = 0x01, + H3LIS331DL_DATA_READY = 0x02, + H3LIS331DL_BOOT_RUNNING = 0x03 +} H3LIS331DL_INT_Conf_t; + +typedef enum { + H3LIS331DL_SLEEP_TO_WAKE_DIS = 0x00, + H3LIS331DL_SLEEP_TO_WAKE_ENA = 0x03, +} H3LIS331DL_Sleep_To_Wake_Conf_t; + +typedef enum { + H3LIS331DL_FULLSCALE_2 = 0x00, + H3LIS331DL_FULLSCALE_4 = 0x01, + H3LIS331DL_FULLSCALE_8 = 0x03, +} H3LIS331DL_Fullscale_t; + +typedef enum { + H3LIS331DL_BLE_LSB = 0x00, + H3LIS331DL_BLE_MSB = 0x01 +} H3LIS331DL_Endianess_t; + +typedef enum { + H3LIS331DL_SPI_4_WIRE = 0x00, + H3LIS331DL_SPI_3_WIRE = 0x01 +} H3LIS331DL_SPIMode_t; + +typedef enum { + H3LIS331DL_X_ENABLE = 0x01, + H3LIS331DL_X_DISABLE = 0x00, + H3LIS331DL_Y_ENABLE = 0x02, + H3LIS331DL_Y_DISABLE = 0x00, + H3LIS331DL_Z_ENABLE = 0x04, + H3LIS331DL_Z_DISABLE = 0x00 +} H3LIS331DL_AXISenable_t; + +typedef enum { + H3LIS331DL_UP_SX = 0x44, + H3LIS331DL_UP_DX = 0x42, + H3LIS331DL_DW_SX = 0x41, + H3LIS331DL_DW_DX = 0x48, + H3LIS331DL_TOP = 0x60, + H3LIS331DL_BOTTOM = 0x50 +} H3LIS331DL_POSITION_6D_t; + +typedef enum { + H3LIS331DL_INT_MODE_OR = 0x00, + H3LIS331DL_INT_MODE_6D_MOVEMENT = 0x01, + H3LIS331DL_INT_MODE_AND = 0x02, + H3LIS331DL_INT_MODE_6D_POSITION = 0x03 +} H3LIS331DL_IntMode_t; + + +class H3LIS331DL +{ +public: + H3LIS331DL(PinName sda, PinName scl){ + i2c = new mbed::I2C(sda, scl); + i2c->frequency(100000); + _adjVal[0] = _adjVal[1] = _adjVal[2] = 0; + }; + void init(H3LIS331DL_ODR_t odr = H3LIS331DL_ODR_100Hz, + H3LIS331DL_Mode_t mode = H3LIS331DL_NORMAL,H3LIS331DL_Fullscale_t fullScale = H3LIS331DL_FULLSCALE_2); + void importPara(int16_t val_x, int16_t val_y, int16_t val_z); + void readXYZ(int16_t* x, int16_t* y, int16_t* z); + void getAcceleration(float* xyz); + //Sensor Configuration Functions + status_t getWHO_AM_I(uint8_t * val); + status_t setODR(H3LIS331DL_ODR_t dr); + status_t setMode(H3LIS331DL_Mode_t pm); + status_t setAxis(H3LIS331DL_Axis_t axis); + status_t setFullScale(H3LIS331DL_Fullscale_t fs); + status_t setBDU(State_t bdu); + status_t setBLE(H3LIS331DL_Endianess_t ble); + status_t setSelfTest(State_t st); + status_t setSelfTestSign(State_t st_sign); + status_t turnONEnable(H3LIS331DL_Sleep_To_Wake_Conf_t stw); + status_t setBOOT(State_t boot); + status_t setFDS(State_t fds); + status_t setSPI34Wire(H3LIS331DL_SPIMode_t sim); + + //Filtering Functions + status_t setHPFMode(H3LIS331DL_HPFMode_t hpm); + status_t setHPFCutOFF(H3LIS331DL_HPFCutOffFreq_t hpf); + status_t setFilterDataSel(State_t state); + status_t setReference(int8_t ref); + + //Interrupt Functions + status_t setIntHighLow(State_t hil); + status_t setIntPPOD(State_t pp_od); + status_t setInt1DataSign(H3LIS331DL_INT_Conf_t i_cfg); + status_t setInt2DataSign(H3LIS331DL_INT_Conf_t i_cfg); + status_t setInt1HPEnable(State_t stat); + status_t setInt2HPEnable(State_t stat); + status_t int1LatchEnable(State_t latch); + status_t int2LatchEnable(State_t latch); + status_t resetInt1Latch(void); + status_t resetInt2Latch(void); + status_t setInt1Configuration(H3LIS331DL_IntConf_t ic); + status_t setInt2Configuration(H3LIS331DL_IntConf_t ic); + status_t setInt1Threshold(uint8_t ths); + status_t setInt2Threshold(uint8_t ths); + status_t setInt1Duration(uint8_t id); + status_t setInt2Duration(uint8_t id); + status_t setInt1Mode(H3LIS331DL_IntMode_t int_mode); + status_t setInt2Mode(H3LIS331DL_IntMode_t int_mode); + status_t getInt1Src(uint8_t* val); + status_t getInt2Src(uint8_t* val); + status_t getInt1SrcBit(uint8_t statusBIT, uint8_t* val); + status_t getInt2SrcBit(uint8_t statusBIT, uint8_t* val); + + //Other Reading Functions + status_t getStatusReg(uint8_t* val); + status_t getStatusBit(uint8_t statusBIT, uint8_t* val); + status_t getAccAxesRaw(AxesRaw_t* buff); + status_t get6DPositionInt1(uint8_t* val); + status_t get6DPositionInt2(uint8_t* val); + +private: + I2C * i2c; + uint8_t readReg(uint8_t deviceAddr, uint8_t Reg, uint8_t* Data); + uint8_t writeReg(uint8_t deviceAddress, uint8_t WriteAddr, uint8_t Data); + int16_t _adjVal[3]; +}; + +#endif /*__H3LIS331DL_H */