Library for H3LIS331DL
Revision 0:915a712ec85a, committed 2017-04-28
- Comitter:
- j3
- Date:
- Fri Apr 28 00:07:39 2017 +0000
- Commit message:
- init commit
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 |
diff -r 000000000000 -r 915a712ec85a H3LIS331DL.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/H3LIS331DL.cpp Fri Apr 28 00:07:39 2017 +0000 @@ -0,0 +1,336 @@ +/****************************************************************************** +* MIT License +* +* Copyright (c) 2017 Justin J. Jordan +* +* 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" + + +//************************** Base Class member fxs ***************************** +int32_t H3LIS331DL::getDeviceId(uint8_t &data) +{ + uint8_t local_data; + + int32_t rtn_val = readRegister(WHO_AM_I, local_data); + if(rtn_val == 0) + { + data = local_data; + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::readControlRegisters(ControlRegisters_s &controlRegisters) +{ + uint8_t data[5]; + + int32_t rtn_val = readBlock(CTRL_REG1, 5, data); + if(rtn_val == 0) + { + uint8_t idx = 0; + controlRegisters.reg1.all = data[idx++]; + controlRegisters.reg2.all = data[idx++]; + controlRegisters.reg3.all = data[idx++]; + controlRegisters.reg4.all = data[idx++]; + controlRegisters.reg5.all = data[idx++]; + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::writeControlRegisters( +const ControlRegisters_s &controlRegisters) +{ + uint8_t data[5]; + uint8_t idx = 0; + + data[idx++] = controlRegisters.reg1.all; + data[idx++] = controlRegisters.reg2.all; + data[idx++] = controlRegisters.reg3.all; + data[idx++] = controlRegisters.reg4.all; + data[idx++] = controlRegisters.reg5.all; + + return writeBlock(CTRL_REG1, idx, data); +} + + +//****************************************************************************** +int32_t H3LIS331DL::resetHPF() +{ + uint8_t data; //dummy data for read + return readRegister(HP_FILTER_RESET, data); +} + + +//****************************************************************************** +int32_t H3LIS331DL::readReferenceRegister(uint8_t &ref) +{ + uint8_t data; + + int32_t rtn_val = readRegister(REFERENCE, data); + if(rtn_val == 0) + { + ref = data; + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::writeReferenceRegister(const uint8_t ref) +{ + return writeRegister(REFERENCE, ref); +} + + +//****************************************************************************** +int32_t H3LIS331DL::readStatusRegister(STATUS_REG_u &status) +{ + uint8_t data; + + int32_t rtn_val = readRegister(STATUS_REG, data); + if(rtn_val == 0) + { + status.all = data; + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::writeStatusRegister(const STATUS_REG_u &status) +{ + return writeRegister(STATUS_REG, status.all); +} + + +//****************************************************************************** +int32_t H3LIS331DL::readAxis(Axis_s &axis) +{ + uint8_t data[6]; + + int32_t rtn_val = readBlock(OUT_X_L, 6, data); + if(rtn_val == 0) + { + uint8_t idx = 0; + axis.x_axis = 0; + axis.x_axis = data[idx++]; + axis.x_axis += (data[idx++] << 8); + + axis.y_axis = 0; + axis.y_axis = data[idx++]; + axis.y_axis += (data[idx++] << 8); + + axis.z_axis = 0; + axis.z_axis = data[idx++]; + axis.z_axis += (data[idx++] << 8); + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::readInterruptConfig(InterruptConfig_s &cfg, bool oneOrTwo) +{ + uint8_t data[4]; + Register_e reg = oneOrTwo ? INT1_CFG : INT2_CFG; + + int32_t rtn_val = readBlock(reg, 4, data); + if(rtn_val == 0) + { + uint8_t idx = 0; + cfg.cfg.all = data[idx++]; + cfg.src.all = data[idx++]; + cfg.threshold = data[idx++]; + cfg.duration = data[idx++]; + } + + return rtn_val; +} + + +//****************************************************************************** +int32_t H3LIS331DL::writeInterruptConfig(const InterruptConfig_s &cfg, +bool oneOrTwo) +{ + uint8_t data[4]; + Register_e reg = oneOrTwo ? INT1_CFG : INT2_CFG; + uint8_t idx = 0; + + data[idx++] = cfg.cfg.all; + data[idx++] = cfg.src.all; + data[idx++] = cfg.threshold; + data[idx++] = cfg.duration; + + return writeBlock(reg, idx, data); +} + + +//*************************** I2C Implementation ****************************** +H3LIS331DL_I2C::H3LIS331DL_I2C(I2C &i2cBus, uint8_t slvAdrs): +m_i2cBus(i2cBus), m_w_adrs(slvAdrs << 1), m_r_adrs((slvAdrs << 1) | 1) +{ +} + + +//***************************************************************************** +int32_t H3LIS331DL_I2C::readRegister(Register_e reg, uint8_t &data) +{ + char local_data[1]; + local_data[0] = reg; + + int32_t rtn_val = m_i2cBus.write(m_w_adrs, local_data, 1, true); + if(rtn_val == 0) + { + rtn_val = m_i2cBus.read(m_r_adrs, local_data, 1); + if(rtn_val == 0) + { + data = local_data[0]; + } + } + + return rtn_val; +} + + +//***************************************************************************** +int32_t H3LIS331DL_I2C::writeRegister(Register_e reg, const uint8_t data) +{ + char local_data[2]; + local_data[0] = reg; + local_data[1] = data; + + return m_i2cBus.write(m_w_adrs, local_data, 2); +} + + +//***************************************************************************** +int32_t H3LIS331DL_I2C::readBlock(Register_e startReg, +const uint8_t readLength, uint8_t *data) +{ + char local_data[readLength]; + local_data[0] = startReg; + + int32_t rtn_val = m_i2cBus.write(m_w_adrs, local_data, 1, true); + if(rtn_val == 0) + { + rtn_val = m_i2cBus.read(m_r_adrs, local_data, readLength); + if(rtn_val == 0) + { + for(uint8_t idx = 0; idx < readLength; idx++) + { + data[idx] = local_data[idx]; + } + } + } + + return rtn_val; +} + + +//***************************************************************************** +int32_t H3LIS331DL_I2C::writeBlock(Register_e startReg, +const uint8_t writeLength, const uint8_t *data) +{ + char local_data[writeLength + 1]; + local_data[0] = startReg; + + uint8_t idx = 1; + for(; idx < (writeLength + 1); idx++) + { + local_data[idx] = data[idx]; + } + + return m_i2cBus.write(m_w_adrs, local_data, idx); +} + + +//*************************** SPI Implementation ****************************** +H3LIS331DL_SPI::H3LIS331DL_SPI(SPI &spiBus, PinName cs): +m_spiBus(spiBus), m_cs(cs, 1) +{ +} + + +//***************************************************************************** +int32_t H3LIS331DL_SPI::readRegister(Register_e reg, uint8_t &data) +{ + m_cs = 0; + m_spiBus.write(R_BIT | reg); + data = m_spiBus.write(0xFF); + m_cs = 1; + + return 0; +} + + +//***************************************************************************** +int32_t H3LIS331DL_SPI::writeRegister(Register_e reg, const uint8_t data) +{ + m_cs = 0; + m_spiBus.write(reg); + m_spiBus.write(data); + m_cs = 1; + + return 0; +} + + +//***************************************************************************** +int32_t H3LIS331DL_SPI::readBlock(Register_e startReg, +const uint8_t readLength, uint8_t *data) +{ + m_cs = 0; + m_spiBus.write(R_BIT | AUTO_INC_BIT | startReg); + for(uint8_t idx = 0; idx < readLength; idx++) + { + data[idx] = m_spiBus.write(0xFF); + } + m_cs = 1; + + return 0; +} + + +//***************************************************************************** +int32_t H3LIS331DL_SPI::writeBlock(Register_e startReg, +const uint8_t writeLength, const uint8_t *data) +{ + m_cs = 0; + m_spiBus.write(AUTO_INC_BIT | startReg); + for(uint8_t idx = 0; idx < writeLength; idx++) + { + m_spiBus.write(data[idx]); + } + m_cs = 1; + + return 0; +} +
diff -r 000000000000 -r 915a712ec85a H3LIS331DL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/H3LIS331DL.h Fri Apr 28 00:07:39 2017 +0000 @@ -0,0 +1,482 @@ +/****************************************************************************** +* MIT License +* +* Copyright (c) 2017 Justin J. Jordan +* +* 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. +******************************************************************************/ + + +#ifndef _H3LIS331DL_H_ +#define _H3LIS331DL_H_ + + +#include "mbed.h" + + +/** +@brief The H3LIS331DL is a low-power highperformance 3-axis linear accelerometer +belonging to the “nano” family, with digital I2C/SPI serial interface standard +output. +*/ +class H3LIS331DL +{ + +public: + + static const uint8_t DEVICE_ID = 0x32; + + ///H3LIS331DL Register map + enum Register_e + { + WHO_AM_I = 0x0F, + CTRL_REG1 = 0x20, + CTRL_REG2 = 0x21, + CTRL_REG3 = 0x22, + CTRL_REG4 = 0x23, + CTRL_REG5 = 0x24, + HP_FILTER_RESET = 0x25, + REFERENCE = 0x26, + STATUS_REG = 0x27, + OUT_X_L = 0x28, + OUT_X_H = 0x29, + OUT_Y_L = 0x2A, + OUT_Y_H = 0x2B, + OUT_Z_L = 0x2C, + OUT_Z_H = 0x2D, + INT1_CFG = 0x30, + INT1_SRC = 0x31, + INT1_THS = 0x32, + INT1_DURATION = 0x33, + INT2_CFG = 0x34, + INT2_SRC = 0x35, + INT2_THS = 0x36, + INT2_DURATION = 0x37 + }; + + union CTRL_REG1_u + { + uint8_t all; + + struct BitField_s + { + uint8_t xen : 1; + uint8_t yen : 1; + uint8_t zen : 1; + uint8_t dr0 : 1; + uint8_t dr1 : 1; + uint8_t pm0 : 1; + uint8_t pm1 : 1; + uint8_t pm2 : 1; + }bits; + }; + + union CTRL_REG2_u + { + uint8_t all; + + struct BitField_s + { + uint8_t hpcf0 : 1; + uint8_t hpcf1 : 1; + uint8_t hpen1 : 1; + uint8_t hpen2 : 1; + uint8_t fds : 1; + uint8_t hpm0 : 1; + uint8_t hpm1 : 1; + uint8_t boot : 1; + }bits; + }; + + union CTRL_REG3_u + { + uint8_t all; + + struct BitField_s + { + uint8_t i1_cfg0 : 1; + uint8_t i1_cfg1 : 1; + uint8_t lir1 : 1; + uint8_t i2_cfg0 : 1; + uint8_t i2_cfg1 : 1; + uint8_t lir2 : 1; + uint8_t pp_od : 1; + uint8_t ihl : 1; + }bits; + }; + + union CTRL_REG4_u + { + uint8_t all; + + struct BitField_s + { + uint8_t sim : 1; + uint8_t res1 : 1; + uint8_t res2 : 1; + uint8_t res3 : 1; + uint8_t fs0 : 1; + uint8_t fs1 : 1; + uint8_t ble : 1; + uint8_t bdu : 1; + }bits; + }; + + union CTRL_REG5_u + { + uint8_t all; + + struct BitField_s + { + uint8_t turnOn0 : 1; + uint8_t turnOn1 : 1; + uint8_t res2 : 1; + uint8_t res3 : 1; + uint8_t res4 : 1; + uint8_t res5 : 1; + uint8_t res6 : 1; + uint8_t res7 : 1; + }bits; + }; + + union STATUS_REG_u + { + uint8_t all; + + struct BitField_s + { + uint8_t xda : 1; + uint8_t yda : 1; + uint8_t zda : 1; + uint8_t zyxda : 1; + uint8_t xor_ : 1; + uint8_t yor : 1; + uint8_t zor : 1; + uint8_t zyxor : 1; + }bits; + }; + + union INT_CFG_u + { + uint8_t all; + + struct BitField_s + { + uint8_t xlie : 1; + uint8_t xhie : 1; + uint8_t ylie : 1; + uint8_t yhie : 1; + uint8_t zlie : 1; + uint8_t zhie : 1; + uint8_t res6 : 1; + uint8_t aoi : 1; + }bits; + }; + + union INT_SRC_u + { + uint8_t all; + + struct BitField_s + { + uint8_t xl : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t yh : 1; + uint8_t zl : 1; + uint8_t zh : 1; + uint8_t ia : 1; + uint8_t res7 : 1; + }bits; + }; + + struct ControlRegisters_s + { + CTRL_REG1_u reg1; + CTRL_REG2_u reg2; + CTRL_REG3_u reg3; + CTRL_REG4_u reg4; + CTRL_REG5_u reg5; + }; + + struct Axis_s + { + uint16_t x_axis; + uint16_t y_axis; + uint16_t z_axis; + }; + + struct InterruptConfig_s + { + INT_CFG_u cfg; + INT_SRC_u src; + uint8_t threshold; + uint8_t duration; + }; + + ///@brief Get the device id of the accelerometer. + /// + ///On Entry: + ///@param[in] data - Place holder for data + /// + ///On Exit: + ///@param[out] data - Device ID on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t getDeviceId(uint8_t &data); + + ///@brief Read all 5 control registers. + /// + ///On Entry: + ///@param[in] controlRegisters - Reference to ControlRegisters_s object + /// + ///On Exit: + ///@param[out] controlRegisters - contents of control registers on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t readControlRegisters(ControlRegisters_s &controlRegisters); + + ///@brief Write all 5 control registers. + /// + ///On Entry: + ///@param[in] controlRegisters - Reference to ControlRegisters_s object + /// containing configuration to write + /// + ///On Exit: + ///@param[out] none + /// + ///@returns 0 on success, non-0 otherwise + int32_t writeControlRegisters(const ControlRegisters_s &controlRegisters); + + ///@brief Resets High Pass Filter, if HPF is enabled, will 0 axis + /// + ///On Entry: + ///@param[in] none + /// + ///On Exit: + ///@param[out] none + /// + ///@returns 0 on success, non-0 otherwise + int32_t resetHPF(); + + ///@brief Read reference register + /// + ///On Entry: + ///@param[in] ref - byte for data + /// + ///On Exit: + ///@param[out] ref - contents of reference register on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t readReferenceRegister(uint8_t &ref); + + ///@brief Writes reference register + /// + ///On Entry: + ///@param[in] ref - reference value to be writen + /// + ///On Exit: + ///@param[out] none + /// + ///@returns 0 on success, non-0 otherwise + int32_t writeReferenceRegister(const uint8_t ref); + + ///@brief Read status register + /// + ///On Entry: + ///@param[in] status - Object for holding status data + /// + ///On Exit: + ///@param[out] status - contents of status register on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t readStatusRegister(STATUS_REG_u &status); + + ///@brief Writes status register + /// + ///On Entry: + ///@param[in] status - Object holding data to write + /// + ///On Exit: + ///@param[out] none + /// + ///@returns 0 on success, non-0 otherwise + int32_t writeStatusRegister(const STATUS_REG_u &status); + + ///@brief Reads all three axis + /// + ///On Entry: + ///@param[in] axis - object for holding data + /// + ///On Exit: + ///@param[out] axis - contents of registers on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t readAxis(Axis_s &axis); + + ///@brief Reads interrupt one or two's config, src, threshold and duration + /// data. + /// + ///On Entry: + ///@param[in] cfg - Object to hold data + ///@param[in] oneOrTwo - Boolean representing which interrupt's data to read + /// + ///On Exit: + ///@param[out] cfg - Chosen interrupt's data on success + /// + ///@returns 0 on success, non-0 otherwise + int32_t readInterruptConfig(InterruptConfig_s &cfg, bool oneOrTwo); + + ///@brief Writes interrupt one or two's config, src, threshold and duration + /// data. + ///On Entry: + ///@param[in] cfg - Data to write + ///@param[in] oneOrTwo - Boolean representing which interrupt's data to + /// write + /// + ///On Exit: + ///@param[out] none + /// + ///@returns 0 on success, non-0 otherwise + int32_t writeInterruptConfig(const InterruptConfig_s &cfg, bool oneOrTwo); + +protected: + + ///@brief Read given register. + /// + ///On Entry: + ///@param[in] reg - Register to read. + /// + ///On Exit: + ///@param[out] data - Contents of register on success. + /// + ///@returns 0 on success, non-0 otherwise + virtual int32_t readRegister(Register_e reg, uint8_t &data) = 0; + + ///@brief Write given register. + /// + ///On Entry: + ///@param[in] reg - Register to write. + ///@param[in] data - Data to write. + /// + ///On Exit: + /// + ///@returns 0 on success, non-0 otherwise + virtual int32_t writeRegister(Register_e reg, const uint8_t data) = 0; + + ///@brief Read number of bytes starting at startReg + /// + ///On Entry: + ///@param[in] startReg - Register to start reading from. + ///@param[in] readLength - Number of bytes to read. + ///@param[in] data - Pointer to buffer for storing data + /// + ///On Exit: + ///@param[out] data - Contents of read registers on success. + /// + ///@returns 0 on success, non-0 otherwise + virtual int32_t readBlock(Register_e startReg, const uint8_t readLength, + uint8_t *data) = 0; + + ///@brief Write number of bytes starting at startReg + /// + ///On Entry: + ///@param[in] startReg - Register to start writing to. + ///@param[in] writeLength - Number of bytes to write. + ///@param[in] data - Pointer to write data buffer + /// + ///On Exit: + /// + ///@returns 0 on success, non-0 otherwise + virtual int32_t writeBlock(Register_e startReg, const uint8_t writeLength, + const uint8_t *data) = 0; +}; + + +/** +@brief H3LIS331DL type for I2C interface +*/ +class H3LIS331DL_I2C: public H3LIS331DL +{ + +public: + + H3LIS331DL_I2C(I2C &i2cBus, uint8_t slvAdrs); + + ~H3LIS331DL_I2C(){} + +private: + + virtual int32_t readRegister(Register_e reg, uint8_t &data); + + virtual int32_t writeRegister(Register_e reg, const uint8_t data); + + virtual int32_t readBlock(Register_e startReg, const uint8_t readLength, + uint8_t *data); + + virtual int32_t writeBlock(Register_e startReg, const uint8_t writeLength, + const uint8_t *data); + + I2C m_i2cBus; + uint8_t m_w_adrs, m_r_adrs; +}; + + +/** +@brief H3LIS331DL type for SPI interface +*/ +class H3LIS331DL_SPI: public H3LIS331DL +{ + +public: + + static const uint8_t R_BIT = 0x80; + static const uint8_t AUTO_INC_BIT = 0x40; + + H3LIS331DL_SPI(SPI &spiBus, PinName cs); + + ~H3LIS331DL_SPI(){} + +private: + + virtual int32_t readRegister(Register_e reg, uint8_t &data); + + virtual int32_t writeRegister(Register_e reg, const uint8_t data); + + virtual int32_t readBlock(Register_e startReg, const uint8_t readLength, + uint8_t *data); + + virtual int32_t writeBlock(Register_e startReg, const uint8_t writeLength, + const uint8_t *data); + + SPI m_spiBus; + DigitalOut m_cs; +}; + +#endif /*_H3LIS331DL_H_*/ + +///@brief fx documentation template.\n +/// +///On Entry: +///@param[in] none +/// +///On Exit: +///@param[out] none +/// +///@returns none \ No newline at end of file