Library for H3LIS331DL

H3LIS331DL.h

Committer:
j3
Date:
2017-04-28
Revision:
0:915a712ec85a

File content as of revision 0:915a712ec85a:

/******************************************************************************
* 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