A class to fetch magnetometer and accelerometer data from the FXOS8700 on the K64F board
Diff: K64_MagAcc.cpp
- Revision:
- 0:dfd48724e473
diff -r 000000000000 -r dfd48724e473 K64_MagAcc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/K64_MagAcc.cpp Wed Jun 18 17:12:40 2014 +0000 @@ -0,0 +1,123 @@ +/* Copyright (c) 2014 J Kernthaler MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#include "K64MagAcc.h" + +// FXOS8700CQ internal register addresses +#define FXOS8700Q_STATUS 0x00 +#define FXOS8700Q_OUT_X_MSB 0x01 +#define FXOS8700Q_OUT_Y_MSB 0x03 +#define FXOS8700Q_OUT_Z_MSB 0x05 +#define FXOS8700Q_M_OUT_X_MSB 0x33 +#define FXOS8700Q_M_OUT_Y_MSB 0x35 +#define FXOS8700Q_M_OUT_Z_MSB 0x37 +#define FXOS8700Q_WHOAMI 0x0D +#define FXOS8700Q_XYZ_DATA_CFG 0x0E +#define FXOS8700Q_CTRL_REG1 0x2A +#define FXOS8700Q_M_CTRL_REG1 0x5B +#define FXOS8700Q_M_CTRL_REG2 0x5C +#define FXOS8700Q_WHOAMI_VAL 0xC7 + +/* +Mag data is from 16 bit ADC, +/- 1200 uTesla full scale, so 1 lsb is 1200/32768 +Acc data is from 14 bit ADC, and conversion factor is for +/- 2g full scale +*/ +const float MagScale = 0.0366; +const float AccScale = 0.244e-3; + +/** K64MagAcc class + * Used for setting up and reading data from the FXOS8700Q device on the + * K64F board. + * Usage + * Call the Update method to read data from the device + * The data is made available through two float arrays Mag and Acc + * @param sda Pin name of the I2C sda connection + * @param sdl Pin name of the sdl connection + * @param addr Address of the device on the I2C bus + * @note On the K64F board these parameters are hard wired, so you can leave them out to use the default settings + */ +K64MagAcc::K64MagAcc(PinName sda, PinName sdl, int addr):i2c(sda, sdl) +{ + i2addr = addr; + i2c.frequency(400000); + writeControl(FXOS8700Q_CTRL_REG1, 0x00); // put device in standby + writeControl(FXOS8700Q_M_CTRL_REG1, 0x1F); + writeControl(FXOS8700Q_M_CTRL_REG2, 0x20); + writeControl(FXOS8700Q_XYZ_DATA_CFG, 0x00); // sets accelerometer to +/- 2g range or 0.244 mg per lsb + writeControl(FXOS8700Q_CTRL_REG1, 0x1D); // make device active +} + +void K64MagAcc::Update(void) +{ + // read status, magnetometer and accel data + readRegs(FXOS8700Q_STATUS, SensorData, 13); + Status = SensorData[0]; + AccData[0] = Unpick14(1); + AccData[1] = Unpick14(3); + AccData[2] = Unpick14(5); + MagData[0] = Unpick(7); + MagData[1] = Unpick(9); + MagData[2] = Unpick(11); + Scale(MagData, Mag, MagScale); + Scale(AccData, Acc, AccScale); +} + +uint8_t K64MagAcc::WhoAmI(void) +{ + uint8_t data; + readRegs(FXOS8700Q_WHOAMI, &data, 1); + return data; +} + +int16_t K64MagAcc::Unpick(int n) +{ + return (SensorData[n] << 8) | SensorData[n+1]; +} + +int16_t K64MagAcc::Unpick14(int n) +{ + // pulls 14 bit data from SensorData and returns it as a signed integer + return (int16_t)(((SensorData[n] << 8) | SensorData[n+1]))>>2; +} + +void K64MagAcc::Scale(int16_t * RawData, float * ScaledData, float Factor) +{ + for(int i = 0; i < 3; i++) + *ScaledData++ = *RawData++ * Factor; +} + +void K64MagAcc::readRegs(int RegAddr, uint8_t * data, int len) +{ + char t[1] = {RegAddr}; + i2c.write(i2addr, t, 1, true); + i2c.read(i2addr, (char *)data, len); +} + +void K64MagAcc::writeRegs(uint8_t * data, int len) +{ + i2c.write(i2addr, (char *)data, len); +} + +void K64MagAcc::writeControl(uint8_t reg, uint8_t data) +{ +uint8_t buffer[2]; + buffer[0] = reg; + buffer[1] = data; + i2c.write(i2addr, (char*) buffer, 2); +} \ No newline at end of file