An in-development library to provide effective access to all features of the FXOS8700CQ on the FRDM-K64F mbed-enabled development board. As of 28 May 2014 1325EDT, the code should be generally usable and modifiable.

Committer:
gjanusz
Date:
Thu Dec 06 20:50:52 2018 +0000
Revision:
5:d1fa77b56bc7
Parent:
3:2ce85aa45d7d
On board temperature sensor

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
trm 2:4c2f8a3549a9 116 uint8_t FXOS8700CQ::get_data(SRAWDATA *accel_data, SRAWDATA *magn_data)
trm 0:cf6299acfe98 117 {
trm 2:4c2f8a3549a9 118 if(!enabled) {
trm 2:4c2f8a3549a9 119 return 1;
trm 2:4c2f8a3549a9 120 }
trm 2:4c2f8a3549a9 121
trm 2:4c2f8a3549a9 122 read_regs(FXOS8700CQ_M_OUT_X_MSB, raw, FXOS8700CQ_READ_LEN);
trm 0:cf6299acfe98 123
trm 0:cf6299acfe98 124 // Pull out 16-bit, 2's complement magnetometer data
trm 0:cf6299acfe98 125 magn_data->x = (raw[0] << 8) | raw[1];
trm 0:cf6299acfe98 126 magn_data->y = (raw[2] << 8) | raw[3];
trm 0:cf6299acfe98 127 magn_data->z = (raw[4] << 8) | raw[5];
trm 0:cf6299acfe98 128
trm 0:cf6299acfe98 129 // Pull out 14-bit, 2's complement, right-justified accelerometer data
trm 0:cf6299acfe98 130 accel_data->x = (raw[6] << 8) | raw[7];
trm 0:cf6299acfe98 131 accel_data->y = (raw[8] << 8) | raw[9];
trm 0:cf6299acfe98 132 accel_data->z = (raw[10] << 8) | raw[11];
trm 2:4c2f8a3549a9 133
trm 2:4c2f8a3549a9 134 // Have to apply corrections to make the int16_t correct
trm 2:4c2f8a3549a9 135 if(accel_data->x > UINT14_MAX/2) {
trm 2:4c2f8a3549a9 136 accel_data->x -= UINT14_MAX;
trm 2:4c2f8a3549a9 137 }
trm 2:4c2f8a3549a9 138 if(accel_data->y > UINT14_MAX/2) {
trm 2:4c2f8a3549a9 139 accel_data->y -= UINT14_MAX;
trm 2:4c2f8a3549a9 140 }
trm 2:4c2f8a3549a9 141 if(accel_data->z > UINT14_MAX/2) {
trm 2:4c2f8a3549a9 142 accel_data->z -= UINT14_MAX;
trm 2:4c2f8a3549a9 143 }
trm 2:4c2f8a3549a9 144
trm 2:4c2f8a3549a9 145 return 0;
trm 0:cf6299acfe98 146 }
trm 0:cf6299acfe98 147
trm 2:4c2f8a3549a9 148 uint8_t FXOS8700CQ::get_accel_scale(void)
trm 2:4c2f8a3549a9 149 {
trm 2:4c2f8a3549a9 150 uint8_t data = 0x00;
trm 2:4c2f8a3549a9 151 read_regs(FXOS8700CQ_XYZ_DATA_CFG, &data, 1);
trm 2:4c2f8a3549a9 152 data &= FXOS8700CQ_XYZ_DATA_CFG_FS2(3); // mask with 0b11
trm 2:4c2f8a3549a9 153
trm 3:2ce85aa45d7d 154 // Choose output value based on masked data
trm 2:4c2f8a3549a9 155 switch(data) {
trm 2:4c2f8a3549a9 156 case FXOS8700CQ_XYZ_DATA_CFG_FS2(0):
trm 2:4c2f8a3549a9 157 return 2;
trm 2:4c2f8a3549a9 158 case FXOS8700CQ_XYZ_DATA_CFG_FS2(1):
trm 2:4c2f8a3549a9 159 return 4;
trm 2:4c2f8a3549a9 160 case FXOS8700CQ_XYZ_DATA_CFG_FS2(2):
trm 2:4c2f8a3549a9 161 return 8;
trm 2:4c2f8a3549a9 162 default:
trm 2:4c2f8a3549a9 163 return 0;
trm 2:4c2f8a3549a9 164 }
trm 2:4c2f8a3549a9 165 }
trm 0:cf6299acfe98 166
trm 0:cf6299acfe98 167 // Private methods
trm 0:cf6299acfe98 168
trm 3:2ce85aa45d7d 169 // Excepting the call to dev_i2c.frequency() in the constructor,
trm 3:2ce85aa45d7d 170 // the use of the mbed I2C class is restricted to these methods
trm 0:cf6299acfe98 171 void FXOS8700CQ::read_regs(int reg_addr, uint8_t* data, int len)
trm 0:cf6299acfe98 172 {
trm 0:cf6299acfe98 173 char t[1] = {reg_addr};
trm 0:cf6299acfe98 174 dev_i2c.write(dev_addr, t, 1, true);
trm 0:cf6299acfe98 175 dev_i2c.read(dev_addr, (char *)data, len);
trm 0:cf6299acfe98 176 }
trm 0:cf6299acfe98 177
trm 0:cf6299acfe98 178 void FXOS8700CQ::write_regs(uint8_t* data, int len)
trm 0:cf6299acfe98 179 {
trm 0:cf6299acfe98 180 dev_i2c.write(dev_addr, (char*)data, len);
trm 0:cf6299acfe98 181 }