A class to fetch magnetometer and accelerometer data from the FXOS8700 on the K64F board

Committer:
dr_john
Date:
Wed Jun 18 17:12:40 2014 +0000
Revision:
0:dfd48724e473
First release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dr_john 0:dfd48724e473 1 /* Copyright (c) 2014 J Kernthaler MIT License
dr_john 0:dfd48724e473 2 *
dr_john 0:dfd48724e473 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
dr_john 0:dfd48724e473 4 * and associated documentation files (the "Software"), to deal in the Software without
dr_john 0:dfd48724e473 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
dr_john 0:dfd48724e473 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
dr_john 0:dfd48724e473 7 * Software is furnished to do so, subject to the following conditions:
dr_john 0:dfd48724e473 8 *
dr_john 0:dfd48724e473 9 * The above copyright notice and this permission notice shall be included in all copies or
dr_john 0:dfd48724e473 10 * substantial portions of the Software.
dr_john 0:dfd48724e473 11 *
dr_john 0:dfd48724e473 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
dr_john 0:dfd48724e473 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
dr_john 0:dfd48724e473 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
dr_john 0:dfd48724e473 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dr_john 0:dfd48724e473 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
dr_john 0:dfd48724e473 17 */
dr_john 0:dfd48724e473 18
dr_john 0:dfd48724e473 19
dr_john 0:dfd48724e473 20 #include "K64MagAcc.h"
dr_john 0:dfd48724e473 21
dr_john 0:dfd48724e473 22 // FXOS8700CQ internal register addresses
dr_john 0:dfd48724e473 23 #define FXOS8700Q_STATUS 0x00
dr_john 0:dfd48724e473 24 #define FXOS8700Q_OUT_X_MSB 0x01
dr_john 0:dfd48724e473 25 #define FXOS8700Q_OUT_Y_MSB 0x03
dr_john 0:dfd48724e473 26 #define FXOS8700Q_OUT_Z_MSB 0x05
dr_john 0:dfd48724e473 27 #define FXOS8700Q_M_OUT_X_MSB 0x33
dr_john 0:dfd48724e473 28 #define FXOS8700Q_M_OUT_Y_MSB 0x35
dr_john 0:dfd48724e473 29 #define FXOS8700Q_M_OUT_Z_MSB 0x37
dr_john 0:dfd48724e473 30 #define FXOS8700Q_WHOAMI 0x0D
dr_john 0:dfd48724e473 31 #define FXOS8700Q_XYZ_DATA_CFG 0x0E
dr_john 0:dfd48724e473 32 #define FXOS8700Q_CTRL_REG1 0x2A
dr_john 0:dfd48724e473 33 #define FXOS8700Q_M_CTRL_REG1 0x5B
dr_john 0:dfd48724e473 34 #define FXOS8700Q_M_CTRL_REG2 0x5C
dr_john 0:dfd48724e473 35 #define FXOS8700Q_WHOAMI_VAL 0xC7
dr_john 0:dfd48724e473 36
dr_john 0:dfd48724e473 37 /*
dr_john 0:dfd48724e473 38 Mag data is from 16 bit ADC, +/- 1200 uTesla full scale, so 1 lsb is 1200/32768
dr_john 0:dfd48724e473 39 Acc data is from 14 bit ADC, and conversion factor is for +/- 2g full scale
dr_john 0:dfd48724e473 40 */
dr_john 0:dfd48724e473 41 const float MagScale = 0.0366;
dr_john 0:dfd48724e473 42 const float AccScale = 0.244e-3;
dr_john 0:dfd48724e473 43
dr_john 0:dfd48724e473 44 /** K64MagAcc class
dr_john 0:dfd48724e473 45 * Used for setting up and reading data from the FXOS8700Q device on the
dr_john 0:dfd48724e473 46 * K64F board.
dr_john 0:dfd48724e473 47 * Usage
dr_john 0:dfd48724e473 48 * Call the Update method to read data from the device
dr_john 0:dfd48724e473 49 * The data is made available through two float arrays Mag and Acc
dr_john 0:dfd48724e473 50 * @param sda Pin name of the I2C sda connection
dr_john 0:dfd48724e473 51 * @param sdl Pin name of the sdl connection
dr_john 0:dfd48724e473 52 * @param addr Address of the device on the I2C bus
dr_john 0:dfd48724e473 53 * @note On the K64F board these parameters are hard wired, so you can leave them out to use the default settings
dr_john 0:dfd48724e473 54 */
dr_john 0:dfd48724e473 55 K64MagAcc::K64MagAcc(PinName sda, PinName sdl, int addr):i2c(sda, sdl)
dr_john 0:dfd48724e473 56 {
dr_john 0:dfd48724e473 57 i2addr = addr;
dr_john 0:dfd48724e473 58 i2c.frequency(400000);
dr_john 0:dfd48724e473 59 writeControl(FXOS8700Q_CTRL_REG1, 0x00); // put device in standby
dr_john 0:dfd48724e473 60 writeControl(FXOS8700Q_M_CTRL_REG1, 0x1F);
dr_john 0:dfd48724e473 61 writeControl(FXOS8700Q_M_CTRL_REG2, 0x20);
dr_john 0:dfd48724e473 62 writeControl(FXOS8700Q_XYZ_DATA_CFG, 0x00); // sets accelerometer to +/- 2g range or 0.244 mg per lsb
dr_john 0:dfd48724e473 63 writeControl(FXOS8700Q_CTRL_REG1, 0x1D); // make device active
dr_john 0:dfd48724e473 64 }
dr_john 0:dfd48724e473 65
dr_john 0:dfd48724e473 66 void K64MagAcc::Update(void)
dr_john 0:dfd48724e473 67 {
dr_john 0:dfd48724e473 68 // read status, magnetometer and accel data
dr_john 0:dfd48724e473 69 readRegs(FXOS8700Q_STATUS, SensorData, 13);
dr_john 0:dfd48724e473 70 Status = SensorData[0];
dr_john 0:dfd48724e473 71 AccData[0] = Unpick14(1);
dr_john 0:dfd48724e473 72 AccData[1] = Unpick14(3);
dr_john 0:dfd48724e473 73 AccData[2] = Unpick14(5);
dr_john 0:dfd48724e473 74 MagData[0] = Unpick(7);
dr_john 0:dfd48724e473 75 MagData[1] = Unpick(9);
dr_john 0:dfd48724e473 76 MagData[2] = Unpick(11);
dr_john 0:dfd48724e473 77 Scale(MagData, Mag, MagScale);
dr_john 0:dfd48724e473 78 Scale(AccData, Acc, AccScale);
dr_john 0:dfd48724e473 79 }
dr_john 0:dfd48724e473 80
dr_john 0:dfd48724e473 81 uint8_t K64MagAcc::WhoAmI(void)
dr_john 0:dfd48724e473 82 {
dr_john 0:dfd48724e473 83 uint8_t data;
dr_john 0:dfd48724e473 84 readRegs(FXOS8700Q_WHOAMI, &data, 1);
dr_john 0:dfd48724e473 85 return data;
dr_john 0:dfd48724e473 86 }
dr_john 0:dfd48724e473 87
dr_john 0:dfd48724e473 88 int16_t K64MagAcc::Unpick(int n)
dr_john 0:dfd48724e473 89 {
dr_john 0:dfd48724e473 90 return (SensorData[n] << 8) | SensorData[n+1];
dr_john 0:dfd48724e473 91 }
dr_john 0:dfd48724e473 92
dr_john 0:dfd48724e473 93 int16_t K64MagAcc::Unpick14(int n)
dr_john 0:dfd48724e473 94 {
dr_john 0:dfd48724e473 95 // pulls 14 bit data from SensorData and returns it as a signed integer
dr_john 0:dfd48724e473 96 return (int16_t)(((SensorData[n] << 8) | SensorData[n+1]))>>2;
dr_john 0:dfd48724e473 97 }
dr_john 0:dfd48724e473 98
dr_john 0:dfd48724e473 99 void K64MagAcc::Scale(int16_t * RawData, float * ScaledData, float Factor)
dr_john 0:dfd48724e473 100 {
dr_john 0:dfd48724e473 101 for(int i = 0; i < 3; i++)
dr_john 0:dfd48724e473 102 *ScaledData++ = *RawData++ * Factor;
dr_john 0:dfd48724e473 103 }
dr_john 0:dfd48724e473 104
dr_john 0:dfd48724e473 105 void K64MagAcc::readRegs(int RegAddr, uint8_t * data, int len)
dr_john 0:dfd48724e473 106 {
dr_john 0:dfd48724e473 107 char t[1] = {RegAddr};
dr_john 0:dfd48724e473 108 i2c.write(i2addr, t, 1, true);
dr_john 0:dfd48724e473 109 i2c.read(i2addr, (char *)data, len);
dr_john 0:dfd48724e473 110 }
dr_john 0:dfd48724e473 111
dr_john 0:dfd48724e473 112 void K64MagAcc::writeRegs(uint8_t * data, int len)
dr_john 0:dfd48724e473 113 {
dr_john 0:dfd48724e473 114 i2c.write(i2addr, (char *)data, len);
dr_john 0:dfd48724e473 115 }
dr_john 0:dfd48724e473 116
dr_john 0:dfd48724e473 117 void K64MagAcc::writeControl(uint8_t reg, uint8_t data)
dr_john 0:dfd48724e473 118 {
dr_john 0:dfd48724e473 119 uint8_t buffer[2];
dr_john 0:dfd48724e473 120 buffer[0] = reg;
dr_john 0:dfd48724e473 121 buffer[1] = data;
dr_john 0:dfd48724e473 122 i2c.write(i2addr, (char*) buffer, 2);
dr_john 0:dfd48724e473 123 }