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.

Dependents:   fxos8700cq_example frdm_fxos8700_logger AVC_test1 frdm_accel ... more

A basic implementation of accessing the FXOS8700CQ. This should be useable, but as the Apache License says, don't expect it to be good at doing anything, even what it's supposed to do.

Committer:
trm
Date:
Tue Jun 03 19:02:19 2014 +0000
Revision:
4:e2fe752b881e
Parent:
3:2ce85aa45d7d
Removed extraneous "#define"s.

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 }