Weimen Li / Mbed 2 deprecated MAE433_Library

Dependencies:   mbed-dsp mbed-rtos mbed

Dependents:   MAE433_Library_Tester RobotBalancerv2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FXOS8700CQ.cpp Source File

FXOS8700CQ.cpp

Go to the documentation of this file.
00001 /**
00002  * @file FXOS8700CQ.cpp
00003  * @date June 5th, 2016
00004  * @author Weimen Li
00005  * @brief Source file for FXOS8700CQ driver.
00006  */
00007 
00008 #include <FXOS8700CQ.hpp >
00009 
00010 // These defines are extracted from Page. 25 of the datasheet, Rev. 7.0.
00011 // FXOS8700CQ I2C address
00012 const uint8_t FXOS8700CQ_SLAVE_ADDR = 0x1C; // with pins SA1=1, SA0=0, preshifted
00013 
00014 // FXOS8700CQ internal register addresses
00015 const char FXOS8700CQ_STATUS = 0x00;
00016 const char FXOS8700CQ_OUT_X_MSB = 0x01;
00017 const uint8_t FXOS8700CQ_WHOAMI = 0x0D;
00018 const uint8_t FXOS8700CQ_XYZ_DATA_CFG = 0x0E;
00019 const uint8_t FXOS8700CQ_CTRL_REG1 = 0x2A;
00020 const uint8_t FXOS8700CQ_CTRL_REG2 = 0x2B;
00021 const uint8_t FXOS8700CQ_CTRL_REG4 = 0x2D; /// Interrupt enable register.
00022 const uint8_t FXOS8700CQ_CTRL_REG5 = 0x2E; /// Interrupt pin register.
00023 const uint8_t FXOS8700CQ_M_CTRL_REG1 = 0x5B;
00024 const uint8_t FXOS8700CQ_M_CTRL_REG2 = 0x5C;
00025 const uint8_t FXOS8700CQ_WHOAMI_VAL = 0xC7;
00026 
00027 // Other defines:
00028 static const uint32_t I2CFastModeHz = 400000;
00029 static const uint32_t I2CNormalModeHz = 100000;
00030 static const uint32_t I2CSuperSlowModeHz = 25000;
00031 
00032 FXOS8700CQ::FXOS8700CQ(PinName SDA, PinName SCL, PinName INT1, PinName INT2, AccelerometerSensitivity setting)
00033 : I2CObj(SDA, SCL), dataReadyInt(INT2), accelSensitivitySetting(setting),
00034   accelInt2Float((accelSensitivitySetting == TWO) ? 1. / 4096. :
00035                  (accelSensitivitySetting == FOUR) ? 1. / 2048. : 1. / 1024.),
00036                  xOffset(0), yOffset(0), zOffset(0)
00037 {
00038 
00039     // Set the bus to operate in fast or normal mode.
00040     I2CObj.frequency(I2CFastModeHz);
00041 
00042     // Following routine is based off of manufacturer's datasheet example.
00043     // Create a buffer to hold information to be transfered.
00044     char dataPacket[64];
00045 
00046     /* Reset the device, placing it into standby mode, to set registers. */
00047     // standby
00048     // [6] = reset = 1;
00049     dataPacket[0] = FXOS8700CQ_CTRL_REG2; // First byte is register address.
00050     dataPacket[1] = 0b01000000; // Second byte is data - bit 6 set to 1 means reset.
00051     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00052     // Wait 2 ms for the reset to take place.
00053     wait_ms(2);
00054     //I2CObj.stop();
00055 
00056     /* Configure the device to send an interrupt when data is ready. */
00057     //[7-1]: Disable all other interrupt sources.
00058     //[0]: Enable data-ready interrupt with 1.
00059     dataPacket[0] = FXOS8700CQ_CTRL_REG4; // First byte is register address.
00060     dataPacket[1] = 0b00000001;
00061     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00062     //I2CObj.stop();
00063     /* Configure the data-ready interrupt to be on INT2 Pin. */
00064     //[7-1]: Other interrupt source pin assignment - we don't care because we only use the data ready interrupt.
00065     //[0]: Set to 0 for data-ready interrupt to be on INT2.
00066     dataPacket[0] = FXOS8700CQ_CTRL_REG5; // First byte is register address.
00067     dataPacket[1] = 0b00000000;
00068     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00069     //I2CObj.stop();
00070 
00071     /* Disable the magnetometer. */
00072     // write 0001 1111 = 0x1F to magnetometer control register 1
00073     // [7]: m_acal=0: auto calibration disabled
00074     // [6]: m_rst=0: no one-shot magnetic reset
00075     // [5]: m_ost=0: no one-shot magnetic measurement
00076     // [4-2]: m_os=111=7: 8x oversampling (for 200Hz) to reduce magnetometer noise
00077     // [1-0]: m_hms=00=0: only set the accelerometer to be active.
00078     dataPacket[0] = FXOS8700CQ_M_CTRL_REG1; // First byte is register address.
00079     dataPacket[1] = 0b00011100; // Second byte is data.
00080     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00081     //I2CObj.stop();
00082 
00083 
00084     /* Configure the device to disable the high-pass filter and
00085      * use the setrange.
00086      */
00087     // [7]: reserved
00088     // [6]: reserved
00089     // [5]: reserved
00090     // [4]: High pass filter filter disabled with 0.
00091     // [3]: reserved
00092     // [2]: reserved
00093     // [1-0]: fs=10 for accelerometer range of +/-8g range with 0.976mg/LSB
00094     uint8_t fs =
00095             (accelSensitivitySetting == TWO) ? 0b00 :
00096             (accelSensitivitySetting == FOUR) ? 0b01 :
00097                     0b10;
00098     dataPacket[0] = FXOS8700CQ_XYZ_DATA_CFG; // First byte is register address.
00099     dataPacket[1] = 0b00000000 | fs; // Second byte is data.
00100     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00101     //I2CObj.stop();
00102     /*
00103      * Set the device out of standby mode.
00104      */
00105     // [7-6]: aslp_rate=00 // Sleep mode output data rate is 50 Hz.
00106     // [5-3]: dr=000 for 800Hz data rate in accelerometer only mode.
00107     // [2]: lnoise=... for non-low noise mode (Low noise only possible for 2 g or 4 g accelerometer range.)
00108     // [1]: f_read=0 for normal 16 bit reads
00109     // [0]: active=1 to take the part out of standby and enable sampling
00110     uint8_t lNoise = (accelSensitivitySetting != EIGHT) ? 0b100 : 0b000;
00111     dataPacket[0] = FXOS8700CQ_CTRL_REG1; // First byte is register address.
00112     dataPacket[1] = 0b00000001 | lNoise; // Second byte is data.
00113     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, dataPacket, 2);
00114     //I2CObj.stop();
00115 
00116     // Attach the data-ready interrupt to a member interrupt handler.
00117     // Interrupts are active-low by default.
00118     dataReadyInt.fall(this, &FXOS8700CQ::dataReadyISR);
00119 
00120 }
00121 
00122 FXOS8700CQ::~FXOS8700CQ() {
00123     // TODO Auto-generated destructor stub
00124 }
00125 
00126 void FXOS8700CQ::readAccelerometer(float *xAccel, float *yAccel, float *zAccel) {
00127     // In case an interrupt occurs in the middle of our write, we spin while the data is not consistent.
00128     while((*xAccel != lastxAccel) || (*yAccel != lastyAccel) || (*zAccel != lastzAccel)) {
00129         *xAccel = lastxAccel;
00130         *yAccel = lastyAccel;
00131         *zAccel = lastzAccel;
00132     }
00133 }
00134 
00135 void FXOS8700CQ::dataReadyISR(void) {
00136     char inputBuffer[7];
00137     I2CObj.write(FXOS8700CQ_SLAVE_ADDR, &FXOS8700CQ_STATUS, 1);
00138     // Read the accelerometer values back from the slave.
00139     I2CObj.read(FXOS8700CQ_SLAVE_ADDR, inputBuffer,7);
00140 
00141     // copy the 14 bit accelerometer byte data into 16 bit words
00142     lastxAccel = accelInt2Float * ((int16_t) ((inputBuffer[1] << 8) | inputBuffer[2]) >> 2) - xOffset;
00143     lastyAccel = accelInt2Float * ((int16_t) ((inputBuffer[3] << 8) | inputBuffer[4]) >> 2) - yOffset;
00144     lastzAccel = accelInt2Float * ((int16_t) ((inputBuffer[5] << 8) | inputBuffer[6]) >> 2) - zOffset;
00145 }
00146 
00147