Fork of FXOS8700CQ, with modifications to setup and some additions to class on the way to make it more application configurable... also re-did 14 bit accelerometer data transform.

Dependents:   fxos8700cq_JH_explore

Fork of FXOS8700CQ by Thomas Murphy

Committer:
julianhigginson
Date:
Fri Feb 05 01:57:41 2016 +0000
Revision:
7:e2b87c7f6c8d
Parent:
6:f79ab691a47b
adjusted 14 bit 2s compliment transform (14 bits are Left justified so need to add 4 (1<<2) after bitwise inversion)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
trm 0:cf6299acfe98 1 #include "FXOS8700CQ.h"
trm 0:cf6299acfe98 2
trm 0:cf6299acfe98 3 uint8_t status_reg; // Status register contents
trm 0:cf6299acfe98 4 uint8_t raw[FXOS8700CQ_READ_LEN]; // Buffer for reading out stored data
trm 0:cf6299acfe98 5
trm 0:cf6299acfe98 6 // Construct class and its contents
trm 0:cf6299acfe98 7 FXOS8700CQ::FXOS8700CQ(PinName sda, PinName scl, int addr) : dev_i2c(sda, scl), dev_addr(addr)
trm 0:cf6299acfe98 8 {
julianhigginson 5:2781e519691b 9 // Initialization of the I2C interface
trm 0:cf6299acfe98 10 dev_i2c.frequency(I2C_400K); // Use maximum I2C frequency
trm 0:cf6299acfe98 11
julianhigginson 5:2781e519691b 12 // Initialization of the IC
julianhigginson 5:2781e519691b 13 write_setup();
trm 0:cf6299acfe98 14 }
trm 0:cf6299acfe98 15
trm 0:cf6299acfe98 16 // Destruct class
trm 0:cf6299acfe98 17 FXOS8700CQ::~FXOS8700CQ(void) {}
trm 0:cf6299acfe98 18
trm 0:cf6299acfe98 19
trm 0:cf6299acfe98 20 void FXOS8700CQ::enable(void)
trm 0:cf6299acfe98 21 {
trm 0:cf6299acfe98 22 uint8_t data[2];
trm 0:cf6299acfe98 23 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 2:4c2f8a3549a9 24 data[1] |= FXOS8700CQ_CTRL_REG1_ACTIVE;
trm 0:cf6299acfe98 25 data[0] = FXOS8700CQ_CTRL_REG1;
trm 0:cf6299acfe98 26 write_regs(data, 2); // write back
trm 2:4c2f8a3549a9 27
trm 2:4c2f8a3549a9 28 enabled = true;
trm 0:cf6299acfe98 29 }
trm 0:cf6299acfe98 30
trm 0:cf6299acfe98 31 void FXOS8700CQ::disable(void)
trm 0:cf6299acfe98 32 {
trm 0:cf6299acfe98 33 uint8_t data[2];
trm 0:cf6299acfe98 34 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 0:cf6299acfe98 35 data[0] = FXOS8700CQ_CTRL_REG1;
trm 2:4c2f8a3549a9 36 data[1] &= ~FXOS8700CQ_CTRL_REG1_ACTIVE;
trm 0:cf6299acfe98 37 write_regs(data, 2); // write back
trm 2:4c2f8a3549a9 38
trm 2:4c2f8a3549a9 39 enabled = false;
trm 0:cf6299acfe98 40 }
trm 0:cf6299acfe98 41
trm 0:cf6299acfe98 42
trm 0:cf6299acfe98 43 uint8_t FXOS8700CQ::status(void)
trm 0:cf6299acfe98 44 {
trm 0:cf6299acfe98 45 read_regs(FXOS8700CQ_STATUS, &status_reg, 1);
trm 0:cf6299acfe98 46 return status_reg;
trm 0:cf6299acfe98 47 }
trm 0:cf6299acfe98 48
trm 0:cf6299acfe98 49 uint8_t FXOS8700CQ::get_whoami(void)
trm 0:cf6299acfe98 50 {
trm 0:cf6299acfe98 51 uint8_t databyte = 0x00;
trm 0:cf6299acfe98 52 read_regs(FXOS8700CQ_WHOAMI, &databyte, 1);
trm 0:cf6299acfe98 53 return databyte;
trm 0:cf6299acfe98 54 }
trm 0:cf6299acfe98 55
julianhigginson 5:2781e519691b 56 uint8_t FXOS8700CQ::get_data(SRAWDATA *accel_data)//, SRAWDATA *magn_data)
trm 0:cf6299acfe98 57 {
trm 2:4c2f8a3549a9 58 if(!enabled) {
trm 2:4c2f8a3549a9 59 return 1;
trm 2:4c2f8a3549a9 60 }
trm 2:4c2f8a3549a9 61
julianhigginson 6:f79ab691a47b 62
julianhigginson 5:2781e519691b 63 read_regs(FXOS8700CQ_OUT_X_MSB, raw, FXOS8700CQ_READ_LEN);
trm 0:cf6299acfe98 64
julianhigginson 5:2781e519691b 65 // Pull out 14-bit, 2's complement, *L*E*F*T*-justified accelerometer data
julianhigginson 5:2781e519691b 66 // into 16 bit variables
julianhigginson 5:2781e519691b 67 accel_data->x = (raw[0] << 8) | raw[1];
julianhigginson 5:2781e519691b 68 accel_data->y = (raw[2] << 8) | raw[3];
julianhigginson 5:2781e519691b 69 accel_data->z = (raw[4] << 8) | raw[5];
julianhigginson 5:2781e519691b 70
julianhigginson 5:2781e519691b 71 //deal with -ve representations
julianhigginson 5:2781e519691b 72 if (accel_data->x && 0x8000) { //MSB is ONE
julianhigginson 7:e2b87c7f6c8d 73 accel_data->x = -(~(accel_data->x)+4);
julianhigginson 5:2781e519691b 74 }
julianhigginson 5:2781e519691b 75 if (accel_data->y && 0x8000) { //MSB is ONE
julianhigginson 7:e2b87c7f6c8d 76 accel_data->y = -(~(accel_data->y)+4);
julianhigginson 5:2781e519691b 77 }
julianhigginson 5:2781e519691b 78 if (accel_data->z && 0x8000) { //MSB is ONE
julianhigginson 7:e2b87c7f6c8d 79 accel_data->z = -(~(accel_data->z)+4);
julianhigginson 5:2781e519691b 80 }
julianhigginson 5:2781e519691b 81
julianhigginson 5:2781e519691b 82 // scale back down to actual 14 bit number
julianhigginson 5:2781e519691b 83 accel_data->x = (accel_data->x)/4;
julianhigginson 5:2781e519691b 84 accel_data->y = (accel_data->y)/4;
julianhigginson 5:2781e519691b 85 accel_data->z = (accel_data->z)/4;
trm 2:4c2f8a3549a9 86
trm 2:4c2f8a3549a9 87 return 0;
trm 0:cf6299acfe98 88 }
trm 0:cf6299acfe98 89
trm 2:4c2f8a3549a9 90 uint8_t FXOS8700CQ::get_accel_scale(void)
trm 2:4c2f8a3549a9 91 {
trm 2:4c2f8a3549a9 92 uint8_t data = 0x00;
trm 2:4c2f8a3549a9 93 read_regs(FXOS8700CQ_XYZ_DATA_CFG, &data, 1);
trm 2:4c2f8a3549a9 94 data &= FXOS8700CQ_XYZ_DATA_CFG_FS2(3); // mask with 0b11
trm 2:4c2f8a3549a9 95
trm 3:2ce85aa45d7d 96 // Choose output value based on masked data
trm 2:4c2f8a3549a9 97 switch(data) {
trm 2:4c2f8a3549a9 98 case FXOS8700CQ_XYZ_DATA_CFG_FS2(0):
trm 2:4c2f8a3549a9 99 return 2;
trm 2:4c2f8a3549a9 100 case FXOS8700CQ_XYZ_DATA_CFG_FS2(1):
trm 2:4c2f8a3549a9 101 return 4;
trm 2:4c2f8a3549a9 102 case FXOS8700CQ_XYZ_DATA_CFG_FS2(2):
trm 2:4c2f8a3549a9 103 return 8;
trm 2:4c2f8a3549a9 104 default:
trm 2:4c2f8a3549a9 105 return 0;
trm 2:4c2f8a3549a9 106 }
trm 2:4c2f8a3549a9 107 }
trm 0:cf6299acfe98 108
julianhigginson 5:2781e519691b 109 uint8_t FXOS8700CQ::read_single_reg(uint8_t RegAddr)
julianhigginson 5:2781e519691b 110 {
julianhigginson 5:2781e519691b 111 uint8_t data = 0x00;
julianhigginson 5:2781e519691b 112 read_regs(RegAddr, &data, 1);
julianhigginson 5:2781e519691b 113 return data;
julianhigginson 5:2781e519691b 114 }
julianhigginson 5:2781e519691b 115
julianhigginson 5:2781e519691b 116 uint8_t FXOS8700CQ::write_single_reg(uint8_t RegAddr, uint8_t data)
julianhigginson 5:2781e519691b 117 {
julianhigginson 5:2781e519691b 118 uint8_t message[2] = {RegAddr, data};
julianhigginson 5:2781e519691b 119 write_regs(message, 2);
julianhigginson 5:2781e519691b 120 return 1;
julianhigginson 5:2781e519691b 121 }
julianhigginson 5:2781e519691b 122
julianhigginson 5:2781e519691b 123 uint8_t FXOS8700CQ::write_setup(void)
julianhigginson 5:2781e519691b 124 {
julianhigginson 5:2781e519691b 125 uint8_t data[6] = {0, 0, 0, 0, 0, 0}; // to write over I2C: device register, up to 5 bytes data
julianhigginson 5:2781e519691b 126
julianhigginson 5:2781e519691b 127 // TODO: verify WHOAMI?
julianhigginson 5:2781e519691b 128
julianhigginson 5:2781e519691b 129 // Place peripheral in standby for configuration, resetting CTRL_REG1
julianhigginson 5:2781e519691b 130 data[0] = FXOS8700CQ_CTRL_REG1;
julianhigginson 5:2781e519691b 131 data[1] = 0x00; // this will unset CTRL_REG1:active
julianhigginson 5:2781e519691b 132 write_regs(data, 2);
julianhigginson 5:2781e519691b 133
julianhigginson 5:2781e519691b 134 // Now that the device is in standby, configure registers at will
julianhigginson 5:2781e519691b 135
julianhigginson 5:2781e519691b 136 // Setup for write-though for CTRL_REG series
julianhigginson 5:2781e519691b 137 // Keep data[0] as FXOS8700CQ_CTRL_REG1
julianhigginson 5:2781e519691b 138 data[1] = 0x24; //DR3 = b100 lnoise = 1
julianhigginson 5:2781e519691b 139 //FXOS8700CQ_CTRL_REG1_ASLP_RATE2(1) | // 0b01 gives sleep rate of 12.5Hz
julianhigginson 5:2781e519691b 140 //FXOS8700CQ_CTRL_REG1_DR3(3); // 0x001 gives ODR of 400Hz/200Hz hybrid
julianhigginson 5:2781e519691b 141
julianhigginson 5:2781e519691b 142 // FXOS8700CQ_CTRL_REG2;
julianhigginson 5:2781e519691b 143 data[2] = 0x12; //SMODS = MODS = 2 - high resolution. nothing else on here
julianhigginson 5:2781e519691b 144 //FXOS8700CQ_CTRL_REG2_SMODS2(3) | // 0b11 gives low power sleep oversampling mode
julianhigginson 5:2781e519691b 145 //FXOS8700CQ_CTRL_REG2_MODS2(1); // 0b01 gives low noise, low power oversampling mode
julianhigginson 5:2781e519691b 146
julianhigginson 5:2781e519691b 147 // No configuration changes from default 0x00 in CTRL_REG3
julianhigginson 5:2781e519691b 148 // Interrupts will be active low, their outputs in push-pull mode
julianhigginson 5:2781e519691b 149 data[3] = 0x00;
julianhigginson 5:2781e519691b 150
julianhigginson 5:2781e519691b 151 // FXOS8700CQ_CTRL_REG4;
julianhigginson 5:2781e519691b 152 data[4] =
julianhigginson 5:2781e519691b 153 FXOS8700CQ_CTRL_REG4_INT_EN_DRDY; // Enable the Data-Ready interrupt
julianhigginson 5:2781e519691b 154
julianhigginson 5:2781e519691b 155 // No configuration changes from default 0x00 in CTRL_REG5
julianhigginson 5:2781e519691b 156 // Data-Ready interrupt will appear on INT2
julianhigginson 5:2781e519691b 157 data[5] = 0x00;
julianhigginson 5:2781e519691b 158
julianhigginson 5:2781e519691b 159 // Write to the 5 CTRL_REG registers
julianhigginson 5:2781e519691b 160 write_regs(data, 6);
julianhigginson 5:2781e519691b 161
julianhigginson 5:2781e519691b 162 // FXOS8700CQ_XYZ_DATA_CFG
julianhigginson 5:2781e519691b 163 data[0] = FXOS8700CQ_XYZ_DATA_CFG;
julianhigginson 5:2781e519691b 164 data[1] =
julianhigginson 5:2781e519691b 165 FXOS8700CQ_XYZ_DATA_CFG_FS2(0); //JH 0x00 gives 2g range // 0x01 gives 4g full range, 0.488mg/LSB
julianhigginson 5:2781e519691b 166 write_regs(data, 2);
julianhigginson 5:2781e519691b 167
julianhigginson 5:2781e519691b 168 // Setup for write-through for M_CTRL_REG series
julianhigginson 5:2781e519691b 169 data[0] = FXOS8700CQ_M_CTRL_REG1;
julianhigginson 5:2781e519691b 170 data[1] = 0x00;
julianhigginson 5:2781e519691b 171 //FXOS8700CQ_M_CTRL_REG1_M_ACAL | // set automatic calibration
julianhigginson 5:2781e519691b 172 //FXOS8700CQ_M_CTRL_REG1_MO_OS3(7) | // use maximum magnetic oversampling
julianhigginson 5:2781e519691b 173 ///FXOS8700CQ_M_CTRL_REG1_M_HMS2(3); // enable hybrid sampling (both sensors)
julianhigginson 5:2781e519691b 174
julianhigginson 5:2781e519691b 175 // FXOS8700CQ_M_CTRL_REG2
julianhigginson 5:2781e519691b 176 data[2] = 0x00;
julianhigginson 5:2781e519691b 177 //FXOS8700CQ_M_CTRL_REG2_HYB_AUTOINC_MODE;
julianhigginson 5:2781e519691b 178
julianhigginson 5:2781e519691b 179 // FXOS8700CQ_M_CTRL_REG3
julianhigginson 5:2781e519691b 180 data[3] = 0x00;
julianhigginson 5:2781e519691b 181 //FXOS8700CQ_M_CTRL_REG3_M_ASLP_OS3(7); // maximum sleep magnetic oversampling
julianhigginson 5:2781e519691b 182
julianhigginson 5:2781e519691b 183 // Write to the 3 M_CTRL_REG registers
julianhigginson 5:2781e519691b 184 //write_regs(data, 4);
julianhigginson 5:2781e519691b 185
julianhigginson 5:2781e519691b 186 // Peripheral is configured, but disabled
julianhigginson 5:2781e519691b 187 enabled = false;
julianhigginson 5:2781e519691b 188 return 1;
julianhigginson 5:2781e519691b 189 }
julianhigginson 5:2781e519691b 190
julianhigginson 5:2781e519691b 191
julianhigginson 5:2781e519691b 192
trm 0:cf6299acfe98 193 // Private methods
trm 0:cf6299acfe98 194
trm 3:2ce85aa45d7d 195 // Excepting the call to dev_i2c.frequency() in the constructor,
trm 3:2ce85aa45d7d 196 // the use of the mbed I2C class is restricted to these methods
trm 0:cf6299acfe98 197 void FXOS8700CQ::read_regs(int reg_addr, uint8_t* data, int len)
trm 0:cf6299acfe98 198 {
trm 0:cf6299acfe98 199 char t[1] = {reg_addr};
trm 0:cf6299acfe98 200 dev_i2c.write(dev_addr, t, 1, true);
trm 0:cf6299acfe98 201 dev_i2c.read(dev_addr, (char *)data, len);
trm 0:cf6299acfe98 202 }
trm 0:cf6299acfe98 203
trm 0:cf6299acfe98 204 void FXOS8700CQ::write_regs(uint8_t* data, int len)
trm 0:cf6299acfe98 205 {
trm 0:cf6299acfe98 206 dev_i2c.write(dev_addr, (char*)data, len);
trm 0:cf6299acfe98 207 }