FXOS8700CQ, 6-Axis Sensor with Integrated Linear Accelerometer and Magnetometer

Dependents:   test_FXOS8700CQ testSensor

FXOS8700CQ.cpp

Committer:
Rhyme
Date:
2015-12-25
Revision:
0:08ed32d49eca

File content as of revision 0:08ed32d49eca:

#include "mbed.h"
#include "FXOS8700CQ.h"

/* Register Address definitions */
#define REG_STATUS           0x00
#define REG_OUT_X_MSB        0x01
#define REG_OUT_X_LSB        0x02
#define REG_OUT_Y_MSB        0x03
#define REG_OUT_Y_LSB        0x04
#define REG_OUT_Z_MSB        0x05
#define REG_OUT_Z_LSB        0x06
/* RESERVED                  0x07 */
/* RESERVED                  0x08 */
#define REG_F_SETUP          0x09
#define REG_TRIG_CFG         0x0A
#define REG_SYSMOD           0x0B
#define REG_INT_SOURCE       0x0C
#define REG_WHO_AM_I         0x0D
#define REG_XYZ_DATA_CFG     0x0E
#define REG_HP_FILTER_CUTOFF 0x0F
#define REG_PL_STATUS        0x10
#define REG_PL_CFG           0x11
#define REG_PL_COUNT         0x12
#define REG_PL_BF_ZCOMP      0x13
#define REG_PL_THS_REG       0x14
#define REG_A_FFMT_CFG       0x15
#define REG_A_FFMT_SRC       0x16
#define REG_A_FFMT_THS       0x17
#define REG_A_FFMT_COUNT     0x18
/* RESERVED                  0x19 */
/* RESERVED                  0x1A */
/* RESERVED                  0x1B */
/* RESERVED                  0x1C */
#define REG_TRANSIENT_CFG    0x1D
#define REG_TRANSIENT_SRC    0x1E
#define REG_TRANSIENT_THS    0x1F
#define REG_TRANSIENT_COUNT  0x20
#define REG_PULSE_CFG        0x21
#define REG_PULSE_SRC        0x22
#define REG_PULSE_THSX       0x23
#define REG_PULSE_THSY       0x24
#define REG_PULSE_THSZ       0x25
#define REG_PULSE_TMLT       0x26
#define REG_PULSE_LTCY       0x27
#define REG_PULSE_WIND       0x28
#define REG_ASLP_COUNT       0x29
#define REG_CTRL_REG1        0x2A
#define REG_CTRL_REG2        0x2B
#define REG_CTRL_REG3        0x2C
#define REG_CTRL_REG4        0x2D
#define REG_CTRL_REG5        0x2E
#define REG_OFF_X            0x2F
#define REG_OFF_Y            0x30
#define REG_OFF_Z            0x31
#define REG_M_DR_STATUS      0x32
#define REG_M_OUT_X_MSB      0x33
#define REG_M_OUT_X_LSB      0x34
#define REG_M_OUT_Y_MSB      0x35
#define REG_M_OUT_Y_LSB      0x36
#define REG_M_OUT_Z_MSB      0x37
#define REG_M_OUT_Z_LSB      0x38
#define REG_CMP_X_MSB        0x39
#define REG_CMP_X_LSB        0x3A
#define REG_CMP_Y_MSB        0x3B
#define REG_CMP_Y_LSB        0x3C
#define REG_CMP_Z_MSB        0x3D
#define REG_CMP_Z_LSB        0x3E
#define REG_M_OFF_X_MSB      0x3F
#define REG_M_OFF_X_LSB      0x40
#define REG_M_OFF_Y_MSB      0x41
#define REG_M_OFF_Y_LSB      0x42
#define REG_M_OFF_Z_MSB      0x43
#define REG_M_OFF_Z_LSB      0x44
#define REG_MAX_X_MSB        0x45
#define REG_MAX_X_LSB        0x46
#define REG_MAX_Y_MSB        0x47
#define REG_MAX_Y_LSB        0x48
#define REG_MAX_Z_MSB        0x49
#define REG_MAX_Z_LSB        0x4A
#define REG_MIN_X_MSB        0x4B
#define REG_MIN_X_LSB        0x4C
#define REG_MIN_Y_MSB        0x4D
#define REG_MIN_Y_LSB        0x4E
#define REG_MIN_Z_MSB        0x4F
#define REG_MIN_Z_LSB        0x50
#define REG_TEMP             0x51
#define REG_M_THS_CFG        0x52
#define REG_M_THS_SRC        0x53
#define REG_M_THS_X_MSB      0x54
#define REG_M_THS_X_LSB      0x55
#define REG_M_THS_Y_MSB      0x56
#define REG_M_THS_Y_LSB      0x57
#define REG_M_THS_Z_MSB      0x58
#define REG_M_THS_Z_LSB      0x59
#define REG_M_THS_COUNT      0x5A
#define REG_M_CTRL_REG1      0x5B
#define REG_M_CTRL_REG2      0x5C
#define REG_M_CTRL_REG3      0x5D
#define REG_M_INT_SRC        0x5E
#define REG_A_VECM_CFG       0x5F
#define REG_A_VECM_THS_MSB   0x60
#define REG_A_VECM_THS_LSB   0x61
#define REG_A_VECM_CNT       0x62
#define REG_A_VECM_INITX_MSB 0x63
#define REG_A_VECM_INITX_LSB 0x64
#define REG_A_VECM_INITY_MSB 0x65
#define REG_A_VECM_INITY_LSB 0x66
#define REG_A_VECM_INITZ_MSB 0x67
#define REG_A_VECM_INITZ_LSB 0x68
#define REG_M_VECM_CFG       0x69
#define REG_M_VECM_THS_MSB   0x6A
#define REG_M_VECM_THS_LSB   0x6B
#define REG_M_VECM_CNT       0x6C
#define REG_M_VECM_INITX_MSB 0x6D
#define REG_M_VECM_INITX_LSB 0x6E
#define REG_M_VECM_INITY_MSB 0x6F
#define REG_M_VECM_INITY_LSB 0x70
#define REG_M_VECM_INITZ_MSB 0x71
#define REG_M_VECM_INITZ_LSB 0x72
#define REG_A_FFMT_THS_X_MSB 0x73
#define REG_A_FFMT_THS_X_LSB 0x74
#define REG_A_FFMT_THS_Y_MSB 0x75
#define REG_A_FFMT_THS_Y_LSB 0x76
#define REG_A_FFMT_THS_Z_MSB 0x77
#define REG_A_FFMT_THS_Z_LSB 0x78
/* RESERVED                  0x79 */

#define FXOS8700CQ_WHO_AM_I 0xC7

FXOS8700CQ::FXOS8700CQ(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) 
{
    // activate the peripheral
}

FXOS8700CQ::~FXOS8700CQ() { }

void FXOS8700CQ::readRegs(int addr, uint8_t * data, int len) 
{
    char t[1] = {addr} ;
    m_i2c.write(m_addr, t, 1, true) ;
    m_i2c.read(m_addr, (char*)data, len) ;
}

void FXOS8700CQ::writeRegs(uint8_t * data, int len) 
{
   m_i2c.write(m_addr, (char *)data, len) ;
}

void FXOS8700CQ::standby(void) 
{
    uint8_t data[2] ;
    data[0] = REG_CTRL_REG1 ;
    data[1] = 0x00 ;
    writeRegs(data, 2) ;
}

void FXOS8700CQ::activate(void) 
{
    uint8_t data[2] ;
    data[0] = REG_CTRL_REG1 ;
    data[1] = 0x01 ;
    writeRegs(data, 2) ;
}

void FXOS8700CQ::init(void)
{
    uint8_t data[2] ;
    readRegs(REG_WHO_AM_I, data, 1) ;
    if (data[0] != FXOS8700CQ_WHO_AM_I) {
        printf("Wrong FXOS8700CQ id[0x%02X], 0x%02X expected\n",
            data[0], FXOS8700CQ_WHO_AM_I ) ;
    }
    /* write 0000_0000 = 0x00 to CTRL_REG1 => standby */
    data[0] = REG_CTRL_REG1 ;
    data[1] = 0x00 ;
    writeRegs(data, 2) ; 
    /* write 0001_1111 = 0x1F to M_CTRL_REG1 */
    data[0] = REG_M_CTRL_REG1 ;
    data[1] = 0x1F ;
    writeRegs(data, 2) ;
    /* write 0010_0000 = 0x20 to M_CTRL_REG2 */
    data[0] = REG_M_CTRL_REG2 ;
    data[1] = 0x20 ;
    writeRegs(data, 2) ;
    /* write 0000_0001 = 0x01 to XYZ_DATA_CFG */
    data[0] = REG_XYZ_DATA_CFG ;
    data[1] = 0x01 ;
    writeRegs(data, 2) ;
    /* write 0000_1101 = 0x0D to CTRL_REG1 */
    data[0] = REG_CTRL_REG1 ;
    data[1] = 0x0D ;
    writeRegs(data, 2) ;
}

void FXOS8700CQ::readAccMgnData(int16_t *accData, int16_t *mgnData) 
{
    uint8_t buf[13] ; /* status + acc (6bytes) + mgn (6bytes) */
    readRegs(REG_STATUS, buf, 13) ;
    // copy the 14 bit accelerometer byte data into 16 bit words
    accData[0] = (int16_t)((buf[1] << 8) | buf[2]) >> 2 ;
    accData[1] = (int16_t)((buf[3] << 8) | buf[4]) >> 2 ;
    accData[2] = (int16_t)((buf[5] << 8) | buf[6]) >> 2 ;
    // copy the magnetometer byte data into 16 bit words
    mgnData[0] = (buf[ 7] << 8) | buf[ 8] ;
    mgnData[1] = (buf[ 9] << 8) | buf[10] ;
    mgnData[2] = (buf[11] << 8) | buf[12] ;
}