Fork of trm's FXOS8700CQ library

Dependents:   co657_lcdplay

Fork of FXOS8700CQ by Thomas Murphy

Committer:
co657_frmb
Date:
Fri Nov 20 12:31:26 2015 +0000
Revision:
5:f27f2c5dc320
Parent:
3:2ce85aa45d7d
Changed data-type from SRAWDATA to FXOSData_t, collect accelerometer and magnetometer in one sitting.

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 {
trm 0:cf6299acfe98 9 // Initialization of the FXOS8700CQ
trm 0:cf6299acfe98 10 dev_i2c.frequency(I2C_400K); // Use maximum I2C frequency
trm 3:2ce85aa45d7d 11 uint8_t data[6] = {0, 0, 0, 0, 0, 0}; // to write over I2C: device register, up to 5 bytes data
trm 0:cf6299acfe98 12
trm 0:cf6299acfe98 13 // TODO: verify WHOAMI?
trm 2:4c2f8a3549a9 14
trm 0:cf6299acfe98 15 // Place peripheral in standby for configuration, resetting CTRL_REG1
trm 0:cf6299acfe98 16 data[0] = FXOS8700CQ_CTRL_REG1;
trm 2:4c2f8a3549a9 17 data[1] = 0x00; // this will unset CTRL_REG1:active
trm 0:cf6299acfe98 18 write_regs(data, 2);
trm 0:cf6299acfe98 19
trm 3:2ce85aa45d7d 20 // Now that the device is in standby, configure registers at will
trm 0:cf6299acfe98 21
trm 0:cf6299acfe98 22 // Setup for write-though for CTRL_REG series
trm 0:cf6299acfe98 23 // Keep data[0] as FXOS8700CQ_CTRL_REG1
trm 2:4c2f8a3549a9 24 data[1] =
trm 2:4c2f8a3549a9 25 FXOS8700CQ_CTRL_REG1_ASLP_RATE2(1) | // 0b01 gives sleep rate of 12.5Hz
trm 2:4c2f8a3549a9 26 FXOS8700CQ_CTRL_REG1_DR3(1); // 0x001 gives ODR of 400Hz/200Hz hybrid
trm 0:cf6299acfe98 27
trm 0:cf6299acfe98 28 // FXOS8700CQ_CTRL_REG2;
trm 2:4c2f8a3549a9 29 data[2] =
trm 2:4c2f8a3549a9 30 FXOS8700CQ_CTRL_REG2_SMODS2(3) | // 0b11 gives low power sleep oversampling mode
trm 2:4c2f8a3549a9 31 FXOS8700CQ_CTRL_REG2_MODS2(1); // 0b01 gives low noise, low power oversampling mode
trm 0:cf6299acfe98 32
trm 0:cf6299acfe98 33 // No configuration changes from default 0x00 in CTRL_REG3
trm 3:2ce85aa45d7d 34 // Interrupts will be active low, their outputs in push-pull mode
trm 0:cf6299acfe98 35 data[3] = 0x00;
trm 0:cf6299acfe98 36
trm 0:cf6299acfe98 37 // FXOS8700CQ_CTRL_REG4;
trm 2:4c2f8a3549a9 38 data[4] =
trm 3:2ce85aa45d7d 39 FXOS8700CQ_CTRL_REG4_INT_EN_DRDY; // Enable the Data-Ready interrupt
trm 0:cf6299acfe98 40
trm 0:cf6299acfe98 41 // No configuration changes from default 0x00 in CTRL_REG5
trm 3:2ce85aa45d7d 42 // Data-Ready interrupt will appear on INT2
trm 0:cf6299acfe98 43 data[5] = 0x00;
trm 0:cf6299acfe98 44
trm 0:cf6299acfe98 45 // Write to the 5 CTRL_REG registers
trm 0:cf6299acfe98 46 write_regs(data, 6);
trm 0:cf6299acfe98 47
trm 2:4c2f8a3549a9 48 // FXOS8700CQ_XYZ_DATA_CFG
trm 2:4c2f8a3549a9 49 data[0] = FXOS8700CQ_XYZ_DATA_CFG;
trm 2:4c2f8a3549a9 50 data[1] =
trm 2:4c2f8a3549a9 51 FXOS8700CQ_XYZ_DATA_CFG_FS2(1); // 0x01 gives 4g full range, 0.488mg/LSB
trm 2:4c2f8a3549a9 52 write_regs(data, 2);
trm 0:cf6299acfe98 53
trm 0:cf6299acfe98 54 // Setup for write-through for M_CTRL_REG series
trm 0:cf6299acfe98 55 data[0] = FXOS8700CQ_M_CTRL_REG1;
trm 2:4c2f8a3549a9 56 data[1] =
trm 2:4c2f8a3549a9 57 FXOS8700CQ_M_CTRL_REG1_M_ACAL | // set automatic calibration
trm 2:4c2f8a3549a9 58 FXOS8700CQ_M_CTRL_REG1_MO_OS3(7) | // use maximum magnetic oversampling
trm 2:4c2f8a3549a9 59 FXOS8700CQ_M_CTRL_REG1_M_HMS2(3); // enable hybrid sampling (both sensors)
trm 0:cf6299acfe98 60
trm 0:cf6299acfe98 61 // FXOS8700CQ_M_CTRL_REG2
trm 2:4c2f8a3549a9 62 data[2] =
trm 2:4c2f8a3549a9 63 FXOS8700CQ_M_CTRL_REG2_HYB_AUTOINC_MODE;
trm 0:cf6299acfe98 64
trm 0:cf6299acfe98 65 // FXOS8700CQ_M_CTRL_REG3
trm 2:4c2f8a3549a9 66 data[3] =
trm 2:4c2f8a3549a9 67 FXOS8700CQ_M_CTRL_REG3_M_ASLP_OS3(7); // maximum sleep magnetic oversampling
trm 0:cf6299acfe98 68
trm 0:cf6299acfe98 69 // Write to the 3 M_CTRL_REG registers
trm 0:cf6299acfe98 70 write_regs(data, 4);
trm 0:cf6299acfe98 71
trm 0:cf6299acfe98 72 // Peripheral is configured, but disabled
trm 2:4c2f8a3549a9 73 enabled = false;
trm 0:cf6299acfe98 74 }
trm 0:cf6299acfe98 75
trm 0:cf6299acfe98 76 // Destruct class
trm 0:cf6299acfe98 77 FXOS8700CQ::~FXOS8700CQ(void) {}
trm 0:cf6299acfe98 78
trm 0:cf6299acfe98 79
trm 0:cf6299acfe98 80 void FXOS8700CQ::enable(void)
trm 0:cf6299acfe98 81 {
trm 0:cf6299acfe98 82 uint8_t data[2];
trm 0:cf6299acfe98 83 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 2:4c2f8a3549a9 84 data[1] |= FXOS8700CQ_CTRL_REG1_ACTIVE;
trm 0:cf6299acfe98 85 data[0] = FXOS8700CQ_CTRL_REG1;
trm 0:cf6299acfe98 86 write_regs(data, 2); // write back
trm 2:4c2f8a3549a9 87
trm 2:4c2f8a3549a9 88 enabled = true;
trm 0:cf6299acfe98 89 }
trm 0:cf6299acfe98 90
trm 0:cf6299acfe98 91 void FXOS8700CQ::disable(void)
trm 0:cf6299acfe98 92 {
trm 0:cf6299acfe98 93 uint8_t data[2];
trm 0:cf6299acfe98 94 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 0:cf6299acfe98 95 data[0] = FXOS8700CQ_CTRL_REG1;
trm 2:4c2f8a3549a9 96 data[1] &= ~FXOS8700CQ_CTRL_REG1_ACTIVE;
trm 0:cf6299acfe98 97 write_regs(data, 2); // write back
trm 2:4c2f8a3549a9 98
trm 2:4c2f8a3549a9 99 enabled = false;
trm 0:cf6299acfe98 100 }
trm 0:cf6299acfe98 101
trm 0:cf6299acfe98 102
trm 0:cf6299acfe98 103 uint8_t FXOS8700CQ::status(void)
trm 0:cf6299acfe98 104 {
trm 0:cf6299acfe98 105 read_regs(FXOS8700CQ_STATUS, &status_reg, 1);
trm 0:cf6299acfe98 106 return status_reg;
trm 0:cf6299acfe98 107 }
trm 0:cf6299acfe98 108
trm 0:cf6299acfe98 109 uint8_t FXOS8700CQ::get_whoami(void)
trm 0:cf6299acfe98 110 {
trm 0:cf6299acfe98 111 uint8_t databyte = 0x00;
trm 0:cf6299acfe98 112 read_regs(FXOS8700CQ_WHOAMI, &databyte, 1);
trm 0:cf6299acfe98 113 return databyte;
trm 0:cf6299acfe98 114 }
trm 0:cf6299acfe98 115
co657_frmb 5:f27f2c5dc320 116 uint8_t FXOS8700CQ::get_data (FXOSData_t *data)
trm 0:cf6299acfe98 117 {
co657_frmb 5:f27f2c5dc320 118 int i;
co657_frmb 5:f27f2c5dc320 119
trm 2:4c2f8a3549a9 120 if(!enabled) {
trm 2:4c2f8a3549a9 121 return 1;
trm 2:4c2f8a3549a9 122 }
trm 2:4c2f8a3549a9 123
co657_frmb 5:f27f2c5dc320 124 read_regs (FXOS8700CQ_M_OUT_X_MSB, raw, FXOS8700CQ_READ_LEN);
trm 0:cf6299acfe98 125
trm 0:cf6299acfe98 126 // Pull out 16-bit, 2's complement magnetometer data
co657_frmb 5:f27f2c5dc320 127 data->s.mag_x = (raw[0] << 8) | raw[1];
co657_frmb 5:f27f2c5dc320 128 data->s.mag_y = (raw[2] << 8) | raw[3];
co657_frmb 5:f27f2c5dc320 129 data->s.mag_z = (raw[4] << 8) | raw[5];
trm 0:cf6299acfe98 130
trm 0:cf6299acfe98 131 // Pull out 14-bit, 2's complement, right-justified accelerometer data
co657_frmb 5:f27f2c5dc320 132 data->s.acc_x = (raw[6] << 8) | raw[7];
co657_frmb 5:f27f2c5dc320 133 data->s.acc_y = (raw[8] << 8) | raw[9];
co657_frmb 5:f27f2c5dc320 134 data->s.acc_z = (raw[10] << 8) | raw[11];
trm 2:4c2f8a3549a9 135
trm 2:4c2f8a3549a9 136 // Have to apply corrections to make the int16_t correct
co657_frmb 5:f27f2c5dc320 137 for (i=0; i<3; i++) {
co657_frmb 5:f27f2c5dc320 138 if (data->v[i] > (UINT14_MAX / 2)) {
co657_frmb 5:f27f2c5dc320 139 data->v[i] -= UINT14_MAX;
co657_frmb 5:f27f2c5dc320 140 }
trm 2:4c2f8a3549a9 141 }
trm 2:4c2f8a3549a9 142
trm 2:4c2f8a3549a9 143 return 0;
trm 0:cf6299acfe98 144 }
trm 0:cf6299acfe98 145
trm 2:4c2f8a3549a9 146 uint8_t FXOS8700CQ::get_accel_scale(void)
trm 2:4c2f8a3549a9 147 {
trm 2:4c2f8a3549a9 148 uint8_t data = 0x00;
trm 2:4c2f8a3549a9 149 read_regs(FXOS8700CQ_XYZ_DATA_CFG, &data, 1);
trm 2:4c2f8a3549a9 150 data &= FXOS8700CQ_XYZ_DATA_CFG_FS2(3); // mask with 0b11
trm 2:4c2f8a3549a9 151
trm 3:2ce85aa45d7d 152 // Choose output value based on masked data
trm 2:4c2f8a3549a9 153 switch(data) {
trm 2:4c2f8a3549a9 154 case FXOS8700CQ_XYZ_DATA_CFG_FS2(0):
trm 2:4c2f8a3549a9 155 return 2;
trm 2:4c2f8a3549a9 156 case FXOS8700CQ_XYZ_DATA_CFG_FS2(1):
trm 2:4c2f8a3549a9 157 return 4;
trm 2:4c2f8a3549a9 158 case FXOS8700CQ_XYZ_DATA_CFG_FS2(2):
trm 2:4c2f8a3549a9 159 return 8;
trm 2:4c2f8a3549a9 160 default:
trm 2:4c2f8a3549a9 161 return 0;
trm 2:4c2f8a3549a9 162 }
trm 2:4c2f8a3549a9 163 }
trm 0:cf6299acfe98 164
trm 0:cf6299acfe98 165 // Private methods
trm 0:cf6299acfe98 166
trm 3:2ce85aa45d7d 167 // Excepting the call to dev_i2c.frequency() in the constructor,
trm 3:2ce85aa45d7d 168 // the use of the mbed I2C class is restricted to these methods
trm 0:cf6299acfe98 169 void FXOS8700CQ::read_regs(int reg_addr, uint8_t* data, int len)
trm 0:cf6299acfe98 170 {
trm 0:cf6299acfe98 171 char t[1] = {reg_addr};
trm 0:cf6299acfe98 172 dev_i2c.write(dev_addr, t, 1, true);
trm 0:cf6299acfe98 173 dev_i2c.read(dev_addr, (char *)data, len);
trm 0:cf6299acfe98 174 }
trm 0:cf6299acfe98 175
trm 0:cf6299acfe98 176 void FXOS8700CQ::write_regs(uint8_t* data, int len)
trm 0:cf6299acfe98 177 {
trm 0:cf6299acfe98 178 dev_i2c.write(dev_addr, (char*)data, len);
trm 0:cf6299acfe98 179 }