A class to fetch magnetometer and accelerometer data from the FXOS8700 on the K64F board
K64_MagAcc.cpp
- Committer:
- dr_john
- Date:
- 2014-06-18
- Revision:
- 0:dfd48724e473
File content as of revision 0:dfd48724e473:
/* 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); }