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:
Wed May 28 13:28:18 2014 +0000
Revision:
0:cf6299acfe98
Child:
2:4c2f8a3549a9
Successful driver for FXOS8700CQ on FRDM-K64F. Configured for 2g accelerometer range, hybrid readings at 200Hz, data ready interrupts on INT2, auto-zero of the magnometer, full-data read. WARNING: data is swapped acc/magn and acc data is 4x large.

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 0:cf6299acfe98 11 uint8_t data[6] = {0, 0, 0, 0, 0, 0}; // target device write address, single byte to write at address
trm 0:cf6299acfe98 12
trm 0:cf6299acfe98 13 // TODO: verify WHOAMI?
trm 0:cf6299acfe98 14
trm 0:cf6299acfe98 15 // TODO: un-magic-number register configuration
trm 0:cf6299acfe98 16
trm 0:cf6299acfe98 17 // Place peripheral in standby for configuration, resetting CTRL_REG1
trm 0:cf6299acfe98 18 data[0] = FXOS8700CQ_CTRL_REG1;
trm 0:cf6299acfe98 19 // Keep data[1] as 0x00
trm 0:cf6299acfe98 20 write_regs(data, 2);
trm 0:cf6299acfe98 21
trm 0:cf6299acfe98 22 // Now that the device is in standby, configure registers
trm 0:cf6299acfe98 23
trm 0:cf6299acfe98 24 // Setup for write-though for CTRL_REG series
trm 0:cf6299acfe98 25 // Keep data[0] as FXOS8700CQ_CTRL_REG1
trm 0:cf6299acfe98 26 data[1] = 0x08; // 400 Hz single rate, 200 Hz hybrid mode
trm 0:cf6299acfe98 27
trm 0:cf6299acfe98 28 // FXOS8700CQ_CTRL_REG2;
trm 0:cf6299acfe98 29 data[2] = 0x18; // set low power sleep sampling, no auto sleep, normal sampling
trm 0:cf6299acfe98 30
trm 0:cf6299acfe98 31 // No configuration changes from default 0x00 in CTRL_REG3
trm 0:cf6299acfe98 32 // Interrupts will be active low
trm 0:cf6299acfe98 33 data[3] = 0x00;
trm 0:cf6299acfe98 34
trm 0:cf6299acfe98 35 // FXOS8700CQ_CTRL_REG4;
trm 0:cf6299acfe98 36 data[4] = 0x01; // enable data ready interrupt
trm 0:cf6299acfe98 37
trm 0:cf6299acfe98 38 // No configuration changes from default 0x00 in CTRL_REG5
trm 0:cf6299acfe98 39 // Data ready interrupt will appear on INT2
trm 0:cf6299acfe98 40 data[5] = 0x00;
trm 0:cf6299acfe98 41
trm 0:cf6299acfe98 42 // Write to the 5 CTRL_REG registers
trm 0:cf6299acfe98 43 write_regs(data, 6);
trm 0:cf6299acfe98 44
trm 0:cf6299acfe98 45 // No configuration changes from default 0x00 in XYZ_DATA_CFG
trm 0:cf6299acfe98 46 // No high pass filter and +/- 2g range for accelerometer
trm 0:cf6299acfe98 47 // Do not write any changes
trm 0:cf6299acfe98 48
trm 0:cf6299acfe98 49 // Setup for write-through for M_CTRL_REG series
trm 0:cf6299acfe98 50 data[0] = FXOS8700CQ_M_CTRL_REG1;
trm 0:cf6299acfe98 51 data[1] = 0x9F; // automatic calibration, maximum oversampling, hybrid sampling mode
trm 0:cf6299acfe98 52
trm 0:cf6299acfe98 53 // FXOS8700CQ_M_CTRL_REG2
trm 0:cf6299acfe98 54 data[2] = 0x20; // allow automatic read-through from accel to magn data at acc_z (0x05/0x06)
trm 0:cf6299acfe98 55
trm 0:cf6299acfe98 56 // FXOS8700CQ_M_CTRL_REG3
trm 0:cf6299acfe98 57 data[3] = 0x70; // use calibration data, sleep oversampling
trm 0:cf6299acfe98 58
trm 0:cf6299acfe98 59 // Write to the 3 M_CTRL_REG registers
trm 0:cf6299acfe98 60 write_regs(data, 4);
trm 0:cf6299acfe98 61
trm 0:cf6299acfe98 62 // Peripheral is configured, but disabled
trm 0:cf6299acfe98 63 }
trm 0:cf6299acfe98 64
trm 0:cf6299acfe98 65 // Destruct class
trm 0:cf6299acfe98 66 FXOS8700CQ::~FXOS8700CQ(void) {}
trm 0:cf6299acfe98 67
trm 0:cf6299acfe98 68
trm 0:cf6299acfe98 69 void FXOS8700CQ::enable(void)
trm 0:cf6299acfe98 70 {
trm 0:cf6299acfe98 71 uint8_t data[2];
trm 0:cf6299acfe98 72 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 0:cf6299acfe98 73 data[1] |= 0x01; // set bit 0, CTRL_REG1:active
trm 0:cf6299acfe98 74 data[0] = FXOS8700CQ_CTRL_REG1;
trm 0:cf6299acfe98 75 write_regs(data, 2); // write back
trm 0:cf6299acfe98 76 }
trm 0:cf6299acfe98 77
trm 0:cf6299acfe98 78 void FXOS8700CQ::disable(void)
trm 0:cf6299acfe98 79 {
trm 0:cf6299acfe98 80 uint8_t data[2];
trm 0:cf6299acfe98 81 read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
trm 0:cf6299acfe98 82 data[1] &= 0xFE; // unset bit 0, CTRL_REG1:active
trm 0:cf6299acfe98 83 data[0] = FXOS8700CQ_CTRL_REG1;
trm 0:cf6299acfe98 84 write_regs(data, 2); // write back
trm 0:cf6299acfe98 85 }
trm 0:cf6299acfe98 86
trm 0:cf6299acfe98 87
trm 0:cf6299acfe98 88 uint8_t FXOS8700CQ::status(void)
trm 0:cf6299acfe98 89 {
trm 0:cf6299acfe98 90 read_regs(FXOS8700CQ_STATUS, &status_reg, 1);
trm 0:cf6299acfe98 91 return status_reg;
trm 0:cf6299acfe98 92 }
trm 0:cf6299acfe98 93
trm 0:cf6299acfe98 94 uint8_t FXOS8700CQ::get_whoami(void)
trm 0:cf6299acfe98 95 {
trm 0:cf6299acfe98 96 uint8_t databyte = 0x00;
trm 0:cf6299acfe98 97 read_regs(FXOS8700CQ_WHOAMI, &databyte, 1);
trm 0:cf6299acfe98 98 return databyte;
trm 0:cf6299acfe98 99 }
trm 0:cf6299acfe98 100
trm 0:cf6299acfe98 101 void FXOS8700CQ::get_data(SRAWDATA *accel_data, SRAWDATA *magn_data)
trm 0:cf6299acfe98 102 {
trm 0:cf6299acfe98 103 read_regs(FXOS8700CQ_OUT_X_MSB, raw, FXOS8700CQ_READ_LEN); // WRONG, getting accel then magn
trm 0:cf6299acfe98 104
trm 0:cf6299acfe98 105 // Pull out 16-bit, 2's complement magnetometer data
trm 0:cf6299acfe98 106 magn_data->x = (raw[0] << 8) | raw[1];
trm 0:cf6299acfe98 107 magn_data->y = (raw[2] << 8) | raw[3];
trm 0:cf6299acfe98 108 magn_data->z = (raw[4] << 8) | raw[5];
trm 0:cf6299acfe98 109
trm 0:cf6299acfe98 110 // Below is wrong, using left-justified version
trm 0:cf6299acfe98 111 // Pull out 14-bit, 2's complement, right-justified accelerometer data
trm 0:cf6299acfe98 112 accel_data->x = (raw[6] << 8) | raw[7];
trm 0:cf6299acfe98 113 accel_data->y = (raw[8] << 8) | raw[9];
trm 0:cf6299acfe98 114 accel_data->z = (raw[10] << 8) | raw[11];
trm 0:cf6299acfe98 115 }
trm 0:cf6299acfe98 116
trm 0:cf6299acfe98 117
trm 0:cf6299acfe98 118 // Private methods
trm 0:cf6299acfe98 119
trm 0:cf6299acfe98 120 void FXOS8700CQ::read_regs(int reg_addr, uint8_t* data, int len)
trm 0:cf6299acfe98 121 {
trm 0:cf6299acfe98 122 char t[1] = {reg_addr};
trm 0:cf6299acfe98 123 dev_i2c.write(dev_addr, t, 1, true);
trm 0:cf6299acfe98 124 dev_i2c.read(dev_addr, (char *)data, len);
trm 0:cf6299acfe98 125 }
trm 0:cf6299acfe98 126
trm 0:cf6299acfe98 127 void FXOS8700CQ::write_regs(uint8_t* data, int len)
trm 0:cf6299acfe98 128 {
trm 0:cf6299acfe98 129 dev_i2c.write(dev_addr, (char*)data, len);
trm 0:cf6299acfe98 130 }