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.

Files at this revision

API Documentation at this revision

Comitter:
trm
Date:
Wed May 28 13:28:18 2014 +0000
Child:
1:3ec7e2676e48
Commit message:
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.

Changed in this revision

FXOS8700CQ.cpp Show annotated file Show diff for this revision Revisions of this file
FXOS8700CQ.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FXOS8700CQ.cpp	Wed May 28 13:28:18 2014 +0000
@@ -0,0 +1,130 @@
+#include "FXOS8700CQ.h"
+
+uint8_t status_reg; // Status register contents
+uint8_t raw[FXOS8700CQ_READ_LEN]; // Buffer for reading out stored data
+
+// Construct class and its contents
+FXOS8700CQ::FXOS8700CQ(PinName sda, PinName scl, int addr) : dev_i2c(sda, scl), dev_addr(addr)
+{
+    // Initialization of the FXOS8700CQ
+    dev_i2c.frequency(I2C_400K); // Use maximum I2C frequency
+    uint8_t data[6] = {0, 0, 0, 0, 0, 0}; // target device write address, single byte to write at address
+
+    // TODO: verify WHOAMI?
+    
+    // TODO: un-magic-number register configuration
+
+    // Place peripheral in standby for configuration, resetting CTRL_REG1
+    data[0] = FXOS8700CQ_CTRL_REG1;
+    // Keep data[1] as 0x00
+    write_regs(data, 2);
+
+    // Now that the device is in standby, configure registers
+
+    // Setup for write-though for CTRL_REG series
+    // Keep data[0] as FXOS8700CQ_CTRL_REG1
+    data[1] = 0x08; // 400 Hz single rate, 200 Hz hybrid mode
+
+    // FXOS8700CQ_CTRL_REG2;
+    data[2] = 0x18; // set low power sleep sampling, no auto sleep, normal sampling
+
+    // No configuration changes from default 0x00 in CTRL_REG3
+    // Interrupts will be active low
+    data[3] = 0x00;
+
+    // FXOS8700CQ_CTRL_REG4;
+    data[4] = 0x01; // enable data ready interrupt
+
+    // No configuration changes from default 0x00 in CTRL_REG5
+    // Data ready interrupt will appear on INT2
+    data[5] = 0x00;
+
+    // Write to the 5 CTRL_REG registers
+    write_regs(data, 6);
+
+    // No configuration changes from default 0x00 in XYZ_DATA_CFG
+    // No high pass filter and +/- 2g range for accelerometer
+    // Do not write any changes
+
+    // Setup for write-through for M_CTRL_REG series
+    data[0] = FXOS8700CQ_M_CTRL_REG1;
+    data[1] = 0x9F; // automatic calibration, maximum oversampling, hybrid sampling mode
+
+    // FXOS8700CQ_M_CTRL_REG2
+    data[2] = 0x20; // allow automatic read-through from accel to magn data at acc_z (0x05/0x06)
+
+    // FXOS8700CQ_M_CTRL_REG3
+    data[3] = 0x70; // use calibration data, sleep oversampling
+
+    // Write to the 3 M_CTRL_REG registers
+    write_regs(data, 4);
+
+    // Peripheral is configured, but disabled
+}
+
+// Destruct class
+FXOS8700CQ::~FXOS8700CQ(void) {}
+
+
+void FXOS8700CQ::enable(void)
+{
+    uint8_t data[2];
+    read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
+    data[1] |= 0x01; // set bit 0, CTRL_REG1:active
+    data[0] = FXOS8700CQ_CTRL_REG1;
+    write_regs(data, 2); // write back
+}
+
+void FXOS8700CQ::disable(void)
+{
+    uint8_t data[2];
+    read_regs( FXOS8700CQ_CTRL_REG1, &data[1], 1);
+    data[1] &= 0xFE; // unset bit 0, CTRL_REG1:active
+    data[0] = FXOS8700CQ_CTRL_REG1;
+    write_regs(data, 2); // write back
+}
+
+
+uint8_t FXOS8700CQ::status(void)
+{
+    read_regs(FXOS8700CQ_STATUS, &status_reg, 1);
+    return status_reg;
+}
+
+uint8_t FXOS8700CQ::get_whoami(void)
+{
+    uint8_t databyte = 0x00;
+    read_regs(FXOS8700CQ_WHOAMI, &databyte, 1);
+    return databyte;
+}
+
+void FXOS8700CQ::get_data(SRAWDATA *accel_data, SRAWDATA *magn_data)
+{
+    read_regs(FXOS8700CQ_OUT_X_MSB, raw, FXOS8700CQ_READ_LEN); // WRONG, getting accel then magn
+
+    // Pull out 16-bit, 2's complement magnetometer data
+    magn_data->x = (raw[0] << 8) | raw[1];
+    magn_data->y = (raw[2] << 8) | raw[3];
+    magn_data->z = (raw[4] << 8) | raw[5];
+
+    // Below is wrong, using left-justified version
+    // Pull out 14-bit, 2's complement, right-justified accelerometer data
+    accel_data->x = (raw[6] << 8) | raw[7];
+    accel_data->y = (raw[8] << 8) | raw[9];
+    accel_data->z = (raw[10] << 8) | raw[11];
+}
+
+
+// Private methods
+
+void FXOS8700CQ::read_regs(int reg_addr, uint8_t* data, int len)
+{
+    char t[1] = {reg_addr};
+    dev_i2c.write(dev_addr, t, 1, true);
+    dev_i2c.read(dev_addr, (char *)data, len);
+}
+
+void FXOS8700CQ::write_regs(uint8_t* data, int len)
+{
+    dev_i2c.write(dev_addr, (char*)data, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FXOS8700CQ.h	Wed May 28 13:28:18 2014 +0000
@@ -0,0 +1,87 @@
+#ifndef FXOS8700CQ_H
+#define FXOS8700CQ_H
+
+#include "mbed.h" // Building this for the mbed platform
+
+#define I2C_400K 400000
+
+// FXOS8700CQ I2C address
+#define FXOS8700CQ_SLAVE_ADDR0 (0x1E<<1) // with pins SA0=0, SA1=0
+#define FXOS8700CQ_SLAVE_ADDR1 (0x1D<<1) // with pins SA0=1, SA1=0
+#define FXOS8700CQ_SLAVE_ADDR2 (0x1C<<1) // with pins SA0=0, SA1=1
+#define FXOS8700CQ_SLAVE_ADDR3 (0x1F<<1) // with pins SA0=1, SA1=1
+
+// FXOS8700CQ internal register addresses
+#define FXOS8700CQ_STATUS 0x00
+#define FXOS8700CQ_OUT_X_MSB 0x01
+#define FXOS8700CQ_WHOAMI 0x0D
+#define FXOS8700CQ_XYZ_DATA_CFG 0x0E
+#define FXOS8700CQ_CTRL_REG1 0x2A
+#define FXOS8700CQ_CTRL_REG2 0x2B
+#define FXOS8700CQ_CTRL_REG3 0x2C
+#define FXOS8700CQ_CTRL_REG4 0x2D
+#define FXOS8700CQ_CTRL_REG5 0x2E
+
+#define FXOS8700CQ_M_OUT_X_MSB 0x34
+
+#define FXOS8700CQ_M_CTRL_REG1 0x5B
+#define FXOS8700CQ_M_CTRL_REG2 0x5C
+#define FXOS8700CQ_M_CTRL_REG3 0x5D
+
+// FXOS8700CQ WHOAMI production register value
+#define FXOS8700CQ_WHOAMI_VAL 0xC7
+
+// 6 channels of two bytes = 12 bytes; read from FXOS8700CQ_OUT_X_MSB
+#define FXOS8700CQ_READ_LEN 12
+
+// From mbed I2C documentation for complete read/write transactions
+#define I2C_SUCCESS 0
+#define I2C_FAILURE 1
+
+// For processing the accelerometer data to right-justified 2's complement
+#define UINT14_MAX 16383
+
+// TODO: struct to hold the data out of the sensor
+typedef struct {
+    int16_t x;
+    int16_t y;
+    int16_t z;
+} SRAWDATA;
+
+class FXOS8700CQ
+{
+public:
+    /**
+    * FXOS8700CQ constructor
+    *
+    * @param sda SDA pin
+    * @param sdl SCL pin
+    * @param addr address of the I2C peripheral in (7-bit << 1) form
+    */
+
+    FXOS8700CQ(PinName sda, PinName scl, int addr);
+
+    /**
+    * FXOS8700CQ destructor
+    */
+    ~FXOS8700CQ();
+
+    void enable(void);
+    void disable(void);
+    uint8_t get_whoami(void);
+    uint8_t status(void);
+    void get_data(SRAWDATA *accel_data, SRAWDATA *magn_data);
+
+
+
+private:
+    I2C dev_i2c; // instance of the mbed I2C class
+    uint8_t dev_addr; // Device I2C address, in (7-bit << 1) form
+
+    // I2C helper methods
+    void read_regs(int reg_addr, uint8_t* data, int len);
+    void write_regs(uint8_t* data, int len);
+
+};
+
+#endif