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.
FXOS8700CQ.cpp@4:e2fe752b881e, 2014-06-03 (annotated)
- 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?
User | Revision | Line number | New 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 | } |