ECE 4180 Final Project

Dependencies:   mbed PinDetect

Committer:
amitchell41
Date:
Wed Dec 12 17:11:24 2018 +0000
Revision:
3:660252b9fa29
Parent:
0:eff94d72c9f4
Final version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
amitchell41 0:eff94d72c9f4 1 // Authors: Ashley Mills, Nicholas Herriot
amitchell41 0:eff94d72c9f4 2 /* Copyright (c) 2013 Vodafone, MIT License
amitchell41 0:eff94d72c9f4 3 *
amitchell41 0:eff94d72c9f4 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
amitchell41 0:eff94d72c9f4 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
amitchell41 0:eff94d72c9f4 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
amitchell41 0:eff94d72c9f4 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
amitchell41 0:eff94d72c9f4 8 * furnished to do so, subject to the following conditions:
amitchell41 0:eff94d72c9f4 9 *
amitchell41 0:eff94d72c9f4 10 * The above copyright notice and this permission notice shall be included in all copies or
amitchell41 0:eff94d72c9f4 11 * substantial portions of the Software.
amitchell41 0:eff94d72c9f4 12 *
amitchell41 0:eff94d72c9f4 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
amitchell41 0:eff94d72c9f4 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
amitchell41 0:eff94d72c9f4 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
amitchell41 0:eff94d72c9f4 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
amitchell41 0:eff94d72c9f4 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
amitchell41 0:eff94d72c9f4 18 */
amitchell41 0:eff94d72c9f4 19
amitchell41 0:eff94d72c9f4 20 #include "MMA8452.h"
amitchell41 0:eff94d72c9f4 21 #include "mbed.h"
amitchell41 0:eff94d72c9f4 22
amitchell41 0:eff94d72c9f4 23 #ifdef MMA8452_DEBUG
amitchell41 0:eff94d72c9f4 24 // you need to define Serial pc(USBTX,USBRX) somewhere for the below line to make sense
amitchell41 0:eff94d72c9f4 25 extern Serial pc;
amitchell41 0:eff94d72c9f4 26 #define MMA8452_DBG(...) pc.printf(__VA_ARGS__); pc.printf("\r\n");
amitchell41 0:eff94d72c9f4 27 #else
amitchell41 0:eff94d72c9f4 28 #define MMA8452_DBG(...)
amitchell41 0:eff94d72c9f4 29 #endif
amitchell41 0:eff94d72c9f4 30
amitchell41 0:eff94d72c9f4 31 // Connect module at I2C address using I2C port pins sda and scl
amitchell41 0:eff94d72c9f4 32 MMA8452::MMA8452(PinName sda, PinName scl, int frequency) : _i2c(sda, scl) , _frequency(frequency) {
amitchell41 0:eff94d72c9f4 33 MMA8452_DBG("Creating MMA8452");
amitchell41 0:eff94d72c9f4 34
amitchell41 0:eff94d72c9f4 35 // set I2C frequency
amitchell41 0:eff94d72c9f4 36 _i2c.frequency(_frequency);
amitchell41 0:eff94d72c9f4 37
amitchell41 0:eff94d72c9f4 38 // setup read and write addresses for convenience
amitchell41 0:eff94d72c9f4 39 _readAddress = MMA8452_ADDRESS | 0x01;
amitchell41 0:eff94d72c9f4 40 _writeAddress = MMA8452_ADDRESS & 0xFE;
amitchell41 0:eff94d72c9f4 41
amitchell41 0:eff94d72c9f4 42 // set some defaults
amitchell41 0:eff94d72c9f4 43 _bitDepth = BIT_DEPTH_UNKNOWN;
amitchell41 0:eff94d72c9f4 44 setBitDepth(BIT_DEPTH_12);
amitchell41 0:eff94d72c9f4 45 _dynamicRange = DYNAMIC_RANGE_UNKNOWN;
amitchell41 0:eff94d72c9f4 46 setDynamicRange(DYNAMIC_RANGE_2G);
amitchell41 0:eff94d72c9f4 47
amitchell41 0:eff94d72c9f4 48 MMA8452_DBG("Done");
amitchell41 0:eff94d72c9f4 49 }
amitchell41 0:eff94d72c9f4 50
amitchell41 0:eff94d72c9f4 51
amitchell41 0:eff94d72c9f4 52 // Destroys instance
amitchell41 0:eff94d72c9f4 53 MMA8452::~MMA8452() {}
amitchell41 0:eff94d72c9f4 54
amitchell41 0:eff94d72c9f4 55 // Setting the control register bit 1 to true to activate the MMA8452
amitchell41 0:eff94d72c9f4 56 int MMA8452::activate() {
amitchell41 0:eff94d72c9f4 57 // perform write and return error code
amitchell41 0:eff94d72c9f4 58 return logicalORRegister(MMA8452_CTRL_REG_1,MMA8452_ACTIVE_MASK);
amitchell41 0:eff94d72c9f4 59 }
amitchell41 0:eff94d72c9f4 60
amitchell41 0:eff94d72c9f4 61 // Setting the control register bit 1 to 0 to standby the MMA8452
amitchell41 0:eff94d72c9f4 62 int MMA8452::standby() {
amitchell41 0:eff94d72c9f4 63 // perform write and return error code
amitchell41 0:eff94d72c9f4 64 return logicalANDRegister(MMA8452_CTRL_REG_1,MMA8452_STANDBY_MASK);
amitchell41 0:eff94d72c9f4 65 }
amitchell41 0:eff94d72c9f4 66
amitchell41 0:eff94d72c9f4 67 // this reads a register, applies a bitmask with logical AND, sets a value with logical OR,
amitchell41 0:eff94d72c9f4 68 // and optionally goes into and out of standby at the beginning and end of the function respectively
amitchell41 0:eff94d72c9f4 69 int MMA8452::maskAndApplyRegister(char reg, char mask, char value, int toggleActivation) {
amitchell41 0:eff94d72c9f4 70 if(toggleActivation) {
amitchell41 0:eff94d72c9f4 71 if(standby()) {
amitchell41 0:eff94d72c9f4 72 return 1;
amitchell41 0:eff94d72c9f4 73 }
amitchell41 0:eff94d72c9f4 74 }
amitchell41 0:eff94d72c9f4 75
amitchell41 0:eff94d72c9f4 76 // read from register
amitchell41 0:eff94d72c9f4 77 char oldValue = 0;
amitchell41 0:eff94d72c9f4 78 if(readRegister(reg,&oldValue)) {
amitchell41 0:eff94d72c9f4 79 return 1;
amitchell41 0:eff94d72c9f4 80 }
amitchell41 0:eff94d72c9f4 81
amitchell41 0:eff94d72c9f4 82 // apply bitmask
amitchell41 0:eff94d72c9f4 83 oldValue &= mask;
amitchell41 0:eff94d72c9f4 84
amitchell41 0:eff94d72c9f4 85 // set value
amitchell41 0:eff94d72c9f4 86 oldValue |= value;
amitchell41 0:eff94d72c9f4 87
amitchell41 0:eff94d72c9f4 88 // write back to register
amitchell41 0:eff94d72c9f4 89 if(writeRegister(reg,oldValue)) {
amitchell41 0:eff94d72c9f4 90 return 1;
amitchell41 0:eff94d72c9f4 91 }
amitchell41 0:eff94d72c9f4 92
amitchell41 0:eff94d72c9f4 93 if(toggleActivation) {
amitchell41 0:eff94d72c9f4 94 if(activate()) {
amitchell41 0:eff94d72c9f4 95 return 1;
amitchell41 0:eff94d72c9f4 96 }
amitchell41 0:eff94d72c9f4 97 }
amitchell41 0:eff94d72c9f4 98 return 0;
amitchell41 0:eff94d72c9f4 99 }
amitchell41 0:eff94d72c9f4 100
amitchell41 0:eff94d72c9f4 101 int MMA8452::setDynamicRange(DynamicRange range, int toggleActivation) {
amitchell41 0:eff94d72c9f4 102 _dynamicRange = range;
amitchell41 0:eff94d72c9f4 103 return maskAndApplyRegister(
amitchell41 0:eff94d72c9f4 104 MMA8452_XYZ_DATA_CFG,
amitchell41 0:eff94d72c9f4 105 MMA8452_DYNAMIC_RANGE_MASK,
amitchell41 0:eff94d72c9f4 106 range,
amitchell41 0:eff94d72c9f4 107 toggleActivation
amitchell41 0:eff94d72c9f4 108 );
amitchell41 0:eff94d72c9f4 109 }
amitchell41 0:eff94d72c9f4 110
amitchell41 0:eff94d72c9f4 111 int MMA8452::setDataRate(DataRateHz dataRate, int toggleActivation) {
amitchell41 0:eff94d72c9f4 112 return maskAndApplyRegister(
amitchell41 0:eff94d72c9f4 113 MMA8452_CTRL_REG_1,
amitchell41 0:eff94d72c9f4 114 MMA8452_DATA_RATE_MASK,
amitchell41 0:eff94d72c9f4 115 dataRate<<MMA8452_DATA_RATE_MASK_SHIFT,
amitchell41 0:eff94d72c9f4 116 toggleActivation
amitchell41 0:eff94d72c9f4 117 );
amitchell41 0:eff94d72c9f4 118 }
amitchell41 0:eff94d72c9f4 119
amitchell41 0:eff94d72c9f4 120 int MMA8452::setBitDepth(BitDepth depth,int toggleActivation) {
amitchell41 0:eff94d72c9f4 121 _bitDepth = depth;
amitchell41 0:eff94d72c9f4 122 return maskAndApplyRegister(
amitchell41 0:eff94d72c9f4 123 MMA8452_CTRL_REG_1,
amitchell41 0:eff94d72c9f4 124 MMA8452_BIT_DEPTH_MASK,
amitchell41 0:eff94d72c9f4 125 depth<<MMA8452_BIT_DEPTH_MASK_SHIFT,
amitchell41 0:eff94d72c9f4 126 toggleActivation
amitchell41 0:eff94d72c9f4 127 );
amitchell41 0:eff94d72c9f4 128 }
amitchell41 0:eff94d72c9f4 129
amitchell41 0:eff94d72c9f4 130 char MMA8452::getMaskedRegister(int addr, char mask) {
amitchell41 0:eff94d72c9f4 131 char rval = 0;
amitchell41 0:eff94d72c9f4 132 if(readRegister(addr,&rval)) {
amitchell41 0:eff94d72c9f4 133 return 0;
amitchell41 0:eff94d72c9f4 134 }
amitchell41 0:eff94d72c9f4 135 return (rval&mask);
amitchell41 0:eff94d72c9f4 136 }
amitchell41 0:eff94d72c9f4 137
amitchell41 0:eff94d72c9f4 138 int MMA8452::isXYZReady() {
amitchell41 0:eff94d72c9f4 139 return getMaskedRegister(MMA8452_STATUS,MMA8452_STATUS_ZYXDR_MASK)>0;
amitchell41 0:eff94d72c9f4 140 }
amitchell41 0:eff94d72c9f4 141
amitchell41 0:eff94d72c9f4 142 int MMA8452::isXReady() {
amitchell41 0:eff94d72c9f4 143 return getMaskedRegister(MMA8452_STATUS,MMA8452_STATUS_XDR_MASK)>0;
amitchell41 0:eff94d72c9f4 144 }
amitchell41 0:eff94d72c9f4 145
amitchell41 0:eff94d72c9f4 146 int MMA8452::isYReady() {
amitchell41 0:eff94d72c9f4 147 return getMaskedRegister(MMA8452_STATUS,MMA8452_STATUS_YDR_MASK)>0;
amitchell41 0:eff94d72c9f4 148 }
amitchell41 0:eff94d72c9f4 149
amitchell41 0:eff94d72c9f4 150 int MMA8452::isZReady() {
amitchell41 0:eff94d72c9f4 151 return getMaskedRegister(MMA8452_STATUS,MMA8452_STATUS_ZDR_MASK)>0;
amitchell41 0:eff94d72c9f4 152 }
amitchell41 0:eff94d72c9f4 153
amitchell41 0:eff94d72c9f4 154
amitchell41 0:eff94d72c9f4 155 int MMA8452::getDeviceID(char *dst) {
amitchell41 0:eff94d72c9f4 156 return readRegister(MMA8452_WHO_AM_I,dst);
amitchell41 0:eff94d72c9f4 157 }
amitchell41 0:eff94d72c9f4 158
amitchell41 0:eff94d72c9f4 159 int MMA8452::getStatus(char* dst) {
amitchell41 0:eff94d72c9f4 160 return readRegister(MMA8452_STATUS,dst);
amitchell41 0:eff94d72c9f4 161 }
amitchell41 0:eff94d72c9f4 162
amitchell41 0:eff94d72c9f4 163 MMA8452::DynamicRange MMA8452::getDynamicRange() {
amitchell41 0:eff94d72c9f4 164 char rval = 0;
amitchell41 0:eff94d72c9f4 165 if(readRegister(MMA8452_XYZ_DATA_CFG,&rval)) {
amitchell41 0:eff94d72c9f4 166 return MMA8452::DYNAMIC_RANGE_UNKNOWN;
amitchell41 0:eff94d72c9f4 167 }
amitchell41 0:eff94d72c9f4 168 rval &= (MMA8452_DYNAMIC_RANGE_MASK^0xFF);
amitchell41 0:eff94d72c9f4 169 return (MMA8452::DynamicRange)rval;
amitchell41 0:eff94d72c9f4 170 }
amitchell41 0:eff94d72c9f4 171
amitchell41 0:eff94d72c9f4 172 MMA8452::DataRateHz MMA8452::getDataRate() {
amitchell41 0:eff94d72c9f4 173 char rval = 0;
amitchell41 0:eff94d72c9f4 174 if(readRegister(MMA8452_CTRL_REG_1,&rval)) {
amitchell41 0:eff94d72c9f4 175 return MMA8452::RATE_UNKNOWN;
amitchell41 0:eff94d72c9f4 176 }
amitchell41 0:eff94d72c9f4 177 // logical AND with inverse of mask
amitchell41 0:eff94d72c9f4 178 rval = rval&(MMA8452_DATA_RATE_MASK^0xFF);
amitchell41 0:eff94d72c9f4 179 // shift back into position
amitchell41 0:eff94d72c9f4 180 rval >>= MMA8452_DATA_RATE_MASK_SHIFT;
amitchell41 0:eff94d72c9f4 181 return (MMA8452::DataRateHz)rval;
amitchell41 0:eff94d72c9f4 182 }
amitchell41 0:eff94d72c9f4 183
amitchell41 0:eff94d72c9f4 184 // Reads xyz
amitchell41 0:eff94d72c9f4 185 int MMA8452::readXYZRaw(char *dst) {
amitchell41 0:eff94d72c9f4 186 if(_bitDepth==BIT_DEPTH_UNKNOWN) {
amitchell41 0:eff94d72c9f4 187 return 1;
amitchell41 0:eff94d72c9f4 188 }
amitchell41 0:eff94d72c9f4 189 int readLen = 3;
amitchell41 0:eff94d72c9f4 190 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 191 readLen = 6;
amitchell41 0:eff94d72c9f4 192 }
amitchell41 0:eff94d72c9f4 193 return readRegister(MMA8452_OUT_X_MSB,dst,readLen);
amitchell41 0:eff94d72c9f4 194 }
amitchell41 0:eff94d72c9f4 195
amitchell41 0:eff94d72c9f4 196 int MMA8452::readXRaw(char *dst) {
amitchell41 0:eff94d72c9f4 197 if(_bitDepth==BIT_DEPTH_UNKNOWN) {
amitchell41 0:eff94d72c9f4 198 return 1;
amitchell41 0:eff94d72c9f4 199 }
amitchell41 0:eff94d72c9f4 200 int readLen = 1;
amitchell41 0:eff94d72c9f4 201 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 202 readLen = 2;
amitchell41 0:eff94d72c9f4 203 }
amitchell41 0:eff94d72c9f4 204 return readRegister(MMA8452_OUT_X_MSB,dst,readLen);
amitchell41 0:eff94d72c9f4 205 }
amitchell41 0:eff94d72c9f4 206
amitchell41 0:eff94d72c9f4 207 int MMA8452::readYRaw(char *dst) {
amitchell41 0:eff94d72c9f4 208 if(_bitDepth==BIT_DEPTH_UNKNOWN) {
amitchell41 0:eff94d72c9f4 209 return 1;
amitchell41 0:eff94d72c9f4 210 }
amitchell41 0:eff94d72c9f4 211 int readLen = 1;
amitchell41 0:eff94d72c9f4 212 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 213 readLen = 2;
amitchell41 0:eff94d72c9f4 214 }
amitchell41 0:eff94d72c9f4 215 return readRegister(MMA8452_OUT_Y_MSB,dst,readLen);
amitchell41 0:eff94d72c9f4 216 }
amitchell41 0:eff94d72c9f4 217
amitchell41 0:eff94d72c9f4 218 int MMA8452::readZRaw(char *dst) {
amitchell41 0:eff94d72c9f4 219 if(_bitDepth==BIT_DEPTH_UNKNOWN) {
amitchell41 0:eff94d72c9f4 220 return 1;
amitchell41 0:eff94d72c9f4 221 }
amitchell41 0:eff94d72c9f4 222 int readLen = 1;
amitchell41 0:eff94d72c9f4 223 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 224 readLen = 2;
amitchell41 0:eff94d72c9f4 225 }
amitchell41 0:eff94d72c9f4 226 return readRegister(MMA8452_OUT_Z_MSB,dst,readLen);
amitchell41 0:eff94d72c9f4 227 }
amitchell41 0:eff94d72c9f4 228
amitchell41 0:eff94d72c9f4 229 int MMA8452::readXYZCounts(int *x, int *y, int *z) {
amitchell41 0:eff94d72c9f4 230 char buf[6];
amitchell41 0:eff94d72c9f4 231 if(readXYZRaw((char*)&buf)) {
amitchell41 0:eff94d72c9f4 232 return 1;
amitchell41 0:eff94d72c9f4 233 }
amitchell41 0:eff94d72c9f4 234 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 235 *x = twelveBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 236 *y = twelveBitToSigned(&buf[2]);
amitchell41 0:eff94d72c9f4 237 *z = twelveBitToSigned(&buf[4]);
amitchell41 0:eff94d72c9f4 238 } else {
amitchell41 0:eff94d72c9f4 239 *x = eightBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 240 *y = eightBitToSigned(&buf[1]);
amitchell41 0:eff94d72c9f4 241 *z = eightBitToSigned(&buf[2]);
amitchell41 0:eff94d72c9f4 242 }
amitchell41 0:eff94d72c9f4 243
amitchell41 0:eff94d72c9f4 244 return 0;
amitchell41 0:eff94d72c9f4 245 }
amitchell41 0:eff94d72c9f4 246
amitchell41 0:eff94d72c9f4 247 int MMA8452::readXCount(int *x) {
amitchell41 0:eff94d72c9f4 248 char buf[2];
amitchell41 0:eff94d72c9f4 249 if(readXRaw((char*)&buf)) {
amitchell41 0:eff94d72c9f4 250 return 1;
amitchell41 0:eff94d72c9f4 251 }
amitchell41 0:eff94d72c9f4 252 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 253 *x = twelveBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 254 } else {
amitchell41 0:eff94d72c9f4 255 *x = eightBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 256 }
amitchell41 0:eff94d72c9f4 257 return 0;
amitchell41 0:eff94d72c9f4 258 }
amitchell41 0:eff94d72c9f4 259
amitchell41 0:eff94d72c9f4 260 int MMA8452::readYCount(int *y) {
amitchell41 0:eff94d72c9f4 261 char buf[2];
amitchell41 0:eff94d72c9f4 262 if(readYRaw((char*)&buf)) {
amitchell41 0:eff94d72c9f4 263 return 1;
amitchell41 0:eff94d72c9f4 264 }
amitchell41 0:eff94d72c9f4 265 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 266 *y = twelveBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 267 } else {
amitchell41 0:eff94d72c9f4 268 *y = eightBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 269 }
amitchell41 0:eff94d72c9f4 270 return 0;
amitchell41 0:eff94d72c9f4 271 }
amitchell41 0:eff94d72c9f4 272
amitchell41 0:eff94d72c9f4 273 int MMA8452::readZCount(int *z) {
amitchell41 0:eff94d72c9f4 274 char buf[2];
amitchell41 0:eff94d72c9f4 275 if(readZRaw((char*)&buf)) {
amitchell41 0:eff94d72c9f4 276 return 1;
amitchell41 0:eff94d72c9f4 277 }
amitchell41 0:eff94d72c9f4 278 if(_bitDepth==BIT_DEPTH_12) {
amitchell41 0:eff94d72c9f4 279 *z = twelveBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 280 } else {
amitchell41 0:eff94d72c9f4 281 *z = eightBitToSigned(&buf[0]);
amitchell41 0:eff94d72c9f4 282 }
amitchell41 0:eff94d72c9f4 283 return 0;
amitchell41 0:eff94d72c9f4 284 }
amitchell41 0:eff94d72c9f4 285
amitchell41 0:eff94d72c9f4 286 double MMA8452::convertCountToGravity(int count, int countsPerG) {
amitchell41 0:eff94d72c9f4 287 return (double)count/(double)countsPerG;
amitchell41 0:eff94d72c9f4 288 }
amitchell41 0:eff94d72c9f4 289
amitchell41 0:eff94d72c9f4 290 int MMA8452::getCountsPerG() {
amitchell41 0:eff94d72c9f4 291 // assume starting with DYNAMIC_RANGE_2G and BIT_DEPTH_12
amitchell41 0:eff94d72c9f4 292 int countsPerG = 1024;
amitchell41 0:eff94d72c9f4 293 if(_bitDepth==BIT_DEPTH_8) {
amitchell41 0:eff94d72c9f4 294 countsPerG = 64;
amitchell41 0:eff94d72c9f4 295 }
amitchell41 0:eff94d72c9f4 296 switch(_dynamicRange) {
amitchell41 0:eff94d72c9f4 297 case DYNAMIC_RANGE_4G:
amitchell41 0:eff94d72c9f4 298 countsPerG /= 2;
amitchell41 0:eff94d72c9f4 299 break;
amitchell41 0:eff94d72c9f4 300 case DYNAMIC_RANGE_8G:
amitchell41 0:eff94d72c9f4 301 countsPerG /= 4;
amitchell41 0:eff94d72c9f4 302 break;
amitchell41 0:eff94d72c9f4 303 }
amitchell41 0:eff94d72c9f4 304 return countsPerG;
amitchell41 0:eff94d72c9f4 305 }
amitchell41 0:eff94d72c9f4 306
amitchell41 0:eff94d72c9f4 307 int MMA8452::readXYZGravity(double *x, double *y, double *z) {
amitchell41 0:eff94d72c9f4 308 int xCount = 0, yCount = 0, zCount = 0;
amitchell41 0:eff94d72c9f4 309 if(readXYZCounts(&xCount,&yCount,&zCount)) {
amitchell41 0:eff94d72c9f4 310 return 1;
amitchell41 0:eff94d72c9f4 311 }
amitchell41 0:eff94d72c9f4 312 int countsPerG = getCountsPerG();
amitchell41 0:eff94d72c9f4 313
amitchell41 0:eff94d72c9f4 314 *x = convertCountToGravity(xCount,countsPerG);
amitchell41 0:eff94d72c9f4 315 *y = convertCountToGravity(yCount,countsPerG);
amitchell41 0:eff94d72c9f4 316 *z = convertCountToGravity(zCount,countsPerG);
amitchell41 0:eff94d72c9f4 317 return 0;
amitchell41 0:eff94d72c9f4 318 }
amitchell41 0:eff94d72c9f4 319
amitchell41 0:eff94d72c9f4 320 int MMA8452::readXGravity(double *x) {
amitchell41 0:eff94d72c9f4 321 int xCount = 0;
amitchell41 0:eff94d72c9f4 322 if(readXCount(&xCount)) {
amitchell41 0:eff94d72c9f4 323 return 1;
amitchell41 0:eff94d72c9f4 324 }
amitchell41 0:eff94d72c9f4 325 int countsPerG = getCountsPerG();
amitchell41 0:eff94d72c9f4 326
amitchell41 0:eff94d72c9f4 327 *x = convertCountToGravity(xCount,countsPerG);
amitchell41 0:eff94d72c9f4 328 return 0;
amitchell41 0:eff94d72c9f4 329 }
amitchell41 0:eff94d72c9f4 330
amitchell41 0:eff94d72c9f4 331 int MMA8452::readYGravity(double *y) {
amitchell41 0:eff94d72c9f4 332 int yCount = 0;
amitchell41 0:eff94d72c9f4 333 if(readYCount(&yCount)) {
amitchell41 0:eff94d72c9f4 334 return 1;
amitchell41 0:eff94d72c9f4 335 }
amitchell41 0:eff94d72c9f4 336 int countsPerG = getCountsPerG();
amitchell41 0:eff94d72c9f4 337
amitchell41 0:eff94d72c9f4 338 *y = convertCountToGravity(yCount,countsPerG);
amitchell41 0:eff94d72c9f4 339 return 0;
amitchell41 0:eff94d72c9f4 340 }
amitchell41 0:eff94d72c9f4 341
amitchell41 0:eff94d72c9f4 342 int MMA8452::readZGravity(double *z) {
amitchell41 0:eff94d72c9f4 343 int zCount = 0;
amitchell41 0:eff94d72c9f4 344 if(readZCount(&zCount)) {
amitchell41 0:eff94d72c9f4 345 return 1;
amitchell41 0:eff94d72c9f4 346 }
amitchell41 0:eff94d72c9f4 347 int countsPerG = getCountsPerG();
amitchell41 0:eff94d72c9f4 348
amitchell41 0:eff94d72c9f4 349 *z = convertCountToGravity(zCount,countsPerG);
amitchell41 0:eff94d72c9f4 350 return 0;
amitchell41 0:eff94d72c9f4 351 }
amitchell41 0:eff94d72c9f4 352
amitchell41 0:eff94d72c9f4 353 // apply an AND mask to a register. read register value, apply mask, write it back
amitchell41 0:eff94d72c9f4 354 int MMA8452::logicalANDRegister(char addr, char mask) {
amitchell41 0:eff94d72c9f4 355 char value = 0;
amitchell41 0:eff94d72c9f4 356 // read register value
amitchell41 0:eff94d72c9f4 357 if(readRegister(addr,&value)) {
amitchell41 0:eff94d72c9f4 358 return 0;
amitchell41 0:eff94d72c9f4 359 }
amitchell41 0:eff94d72c9f4 360 // apply mask
amitchell41 0:eff94d72c9f4 361 value &= mask;
amitchell41 0:eff94d72c9f4 362 return writeRegister(addr,value);
amitchell41 0:eff94d72c9f4 363 }
amitchell41 0:eff94d72c9f4 364
amitchell41 0:eff94d72c9f4 365
amitchell41 0:eff94d72c9f4 366 // apply an OR mask to a register. read register value, apply mask, write it back
amitchell41 0:eff94d72c9f4 367 int MMA8452::logicalORRegister(char addr, char mask) {
amitchell41 0:eff94d72c9f4 368 char value = 0;
amitchell41 0:eff94d72c9f4 369 // read register value
amitchell41 0:eff94d72c9f4 370 if(readRegister(addr,&value)) {
amitchell41 0:eff94d72c9f4 371 return 0;
amitchell41 0:eff94d72c9f4 372 }
amitchell41 0:eff94d72c9f4 373 // apply mask
amitchell41 0:eff94d72c9f4 374 value |= mask;
amitchell41 0:eff94d72c9f4 375 return writeRegister(addr,value);
amitchell41 0:eff94d72c9f4 376 }
amitchell41 0:eff94d72c9f4 377
amitchell41 0:eff94d72c9f4 378 // apply an OR mask to a register. read register value, apply mask, write it back
amitchell41 0:eff94d72c9f4 379 int MMA8452::logicalXORRegister(char addr, char mask) {
amitchell41 0:eff94d72c9f4 380 char value = 0;
amitchell41 0:eff94d72c9f4 381 // read register value
amitchell41 0:eff94d72c9f4 382 if(readRegister(addr,&value)) {
amitchell41 0:eff94d72c9f4 383 return 0;
amitchell41 0:eff94d72c9f4 384 }
amitchell41 0:eff94d72c9f4 385 // apply mask
amitchell41 0:eff94d72c9f4 386 value ^= mask;
amitchell41 0:eff94d72c9f4 387 return writeRegister(addr,value);
amitchell41 0:eff94d72c9f4 388 }
amitchell41 0:eff94d72c9f4 389
amitchell41 0:eff94d72c9f4 390 // Write register (The device must be placed in Standby Mode to change the value of the registers)
amitchell41 0:eff94d72c9f4 391 int MMA8452::writeRegister(char addr, char data) {
amitchell41 0:eff94d72c9f4 392 // what this actually does is the following
amitchell41 0:eff94d72c9f4 393 // 1. tell I2C bus to start transaction
amitchell41 0:eff94d72c9f4 394 // 2. tell slave we want to write (slave address & write flag)
amitchell41 0:eff94d72c9f4 395 // 3. send the write address
amitchell41 0:eff94d72c9f4 396 // 4. send the data to write
amitchell41 0:eff94d72c9f4 397 // 5. tell I2C bus to end transaction
amitchell41 0:eff94d72c9f4 398
amitchell41 0:eff94d72c9f4 399 // we can wrap this up in the I2C library write function
amitchell41 0:eff94d72c9f4 400 char buf[2] = {0,0};
amitchell41 0:eff94d72c9f4 401 buf[0] = addr;
amitchell41 0:eff94d72c9f4 402 buf[1] = data;
amitchell41 0:eff94d72c9f4 403 return _i2c.write(MMA8452_ADDRESS, buf,2);
amitchell41 0:eff94d72c9f4 404 // note, could also do return writeRegister(addr,&data,1);
amitchell41 0:eff94d72c9f4 405 }
amitchell41 0:eff94d72c9f4 406
amitchell41 0:eff94d72c9f4 407 int MMA8452::eightBitToSigned(char *buf) {
amitchell41 0:eff94d72c9f4 408 return (int8_t)*buf;
amitchell41 0:eff94d72c9f4 409 }
amitchell41 0:eff94d72c9f4 410
amitchell41 0:eff94d72c9f4 411 int MMA8452::twelveBitToSigned(char *buf) {
amitchell41 0:eff94d72c9f4 412 // cheat by using the int16_t internal type
amitchell41 0:eff94d72c9f4 413 // all we need to do is convert to little-endian format and shift right
amitchell41 0:eff94d72c9f4 414 int16_t x = 0;
amitchell41 0:eff94d72c9f4 415 ((char*)&x)[1] = buf[0];
amitchell41 0:eff94d72c9f4 416 ((char*)&x)[0] = buf[1];
amitchell41 0:eff94d72c9f4 417 // note this only works because the below is an arithmetic right shift
amitchell41 0:eff94d72c9f4 418 return x>>4;
amitchell41 0:eff94d72c9f4 419 }
amitchell41 0:eff94d72c9f4 420
amitchell41 0:eff94d72c9f4 421 int MMA8452::writeRegister(char addr, char *data, int nbytes) {
amitchell41 0:eff94d72c9f4 422 // writing multiple bytes is a little bit annoying because
amitchell41 0:eff94d72c9f4 423 // the I2C library doesn't support sending the address separately
amitchell41 0:eff94d72c9f4 424 // so we just do it manually
amitchell41 0:eff94d72c9f4 425
amitchell41 0:eff94d72c9f4 426 // 1. tell I2C bus to start transaction
amitchell41 0:eff94d72c9f4 427 _i2c.start();
amitchell41 0:eff94d72c9f4 428 // 2. tell slave we want to write (slave address & write flag)
amitchell41 0:eff94d72c9f4 429 if(_i2c.write(_writeAddress)!=1) {
amitchell41 0:eff94d72c9f4 430 return 1;
amitchell41 0:eff94d72c9f4 431 }
amitchell41 0:eff94d72c9f4 432 // 3. send the write address
amitchell41 0:eff94d72c9f4 433 if(_i2c.write(addr)!=1) {
amitchell41 0:eff94d72c9f4 434 return 1;
amitchell41 0:eff94d72c9f4 435 }
amitchell41 0:eff94d72c9f4 436 // 4. send the data to write
amitchell41 0:eff94d72c9f4 437 for(int i=0; i<nbytes; i++) {
amitchell41 0:eff94d72c9f4 438 if(_i2c.write(data[i])!=1) {
amitchell41 0:eff94d72c9f4 439 return 1;
amitchell41 0:eff94d72c9f4 440 }
amitchell41 0:eff94d72c9f4 441 }
amitchell41 0:eff94d72c9f4 442 // 5. tell I2C bus to end transaction
amitchell41 0:eff94d72c9f4 443 _i2c.stop();
amitchell41 0:eff94d72c9f4 444 return 0;
amitchell41 0:eff94d72c9f4 445 }
amitchell41 0:eff94d72c9f4 446
amitchell41 0:eff94d72c9f4 447 int MMA8452::readRegister(char addr, char *dst, int nbytes) {
amitchell41 0:eff94d72c9f4 448 // this is a bit odd, but basically proceeds like this
amitchell41 0:eff94d72c9f4 449 // 1. Send a start command
amitchell41 0:eff94d72c9f4 450 // 2. Tell the slave we want to write (slave address & write flag)
amitchell41 0:eff94d72c9f4 451 // 3. Send the address of the register (addr)
amitchell41 0:eff94d72c9f4 452 // 4. Send another start command to delineate read portion
amitchell41 0:eff94d72c9f4 453 // 5. Tell the slave we want to read (slave address & read flag)
amitchell41 0:eff94d72c9f4 454 // 6. Read the register value bytes
amitchell41 0:eff94d72c9f4 455 // 7. Send a stop command
amitchell41 0:eff94d72c9f4 456
amitchell41 0:eff94d72c9f4 457 // we can wrap this process in the I2C library read and write commands
amitchell41 0:eff94d72c9f4 458 if(_i2c.write(MMA8452_ADDRESS,&addr,1,true)) {
amitchell41 0:eff94d72c9f4 459 return 1;
amitchell41 0:eff94d72c9f4 460 }
amitchell41 0:eff94d72c9f4 461 return _i2c.read(MMA8452_ADDRESS,dst,nbytes);
amitchell41 0:eff94d72c9f4 462 }
amitchell41 0:eff94d72c9f4 463
amitchell41 0:eff94d72c9f4 464 // most registers are 1 byte, so here is a convenience function
amitchell41 0:eff94d72c9f4 465 int MMA8452::readRegister(char addr, char *dst) {
amitchell41 0:eff94d72c9f4 466 return readRegister(addr,dst,1);
amitchell41 0:eff94d72c9f4 467 }
amitchell41 0:eff94d72c9f4 468
amitchell41 0:eff94d72c9f4 469 MMA8452::BitDepth MMA8452::getBitDepth() {
amitchell41 0:eff94d72c9f4 470 return _bitDepth;
amitchell41 0:eff94d72c9f4 471 }
amitchell41 0:eff94d72c9f4 472
amitchell41 0:eff94d72c9f4 473 #ifdef MMA8452_DEBUG
amitchell41 0:eff94d72c9f4 474 void MMA8452::debugRegister(char reg) {
amitchell41 0:eff94d72c9f4 475 // get register value
amitchell41 0:eff94d72c9f4 476 char v = 0;
amitchell41 0:eff94d72c9f4 477 if(readRegister(reg,&v)) {
amitchell41 0:eff94d72c9f4 478 MMA8452_DBG("Error reading specified register");
amitchell41 0:eff94d72c9f4 479 return;
amitchell41 0:eff94d72c9f4 480 }
amitchell41 0:eff94d72c9f4 481 // print out details
amitchell41 0:eff94d72c9f4 482 switch(reg) {
amitchell41 0:eff94d72c9f4 483 case MMA8452_CTRL_REG_1:
amitchell41 0:eff94d72c9f4 484 MMA8452_DBG("CTRL_REG_1 has value: 0x%x",v);
amitchell41 0:eff94d72c9f4 485 MMA8452_DBG(" 7 ALSP_RATE_1: %d",(v&0x80)>>7);
amitchell41 0:eff94d72c9f4 486 MMA8452_DBG(" 6 ALSP_RATE_0: %d",(v&0x40)>>6);
amitchell41 0:eff94d72c9f4 487 MMA8452_DBG(" 5 DR2: %d", (v&0x20)>>5);
amitchell41 0:eff94d72c9f4 488 MMA8452_DBG(" 4 DR1: %d", (v&0x10)>>4);
amitchell41 0:eff94d72c9f4 489 MMA8452_DBG(" 3 DR0: %d", (v&0x08)>>3);
amitchell41 0:eff94d72c9f4 490 MMA8452_DBG(" 2 LNOISE: %d", (v&0x04)>>2);
amitchell41 0:eff94d72c9f4 491 MMA8452_DBG(" 1 FREAD: %d", (v&0x02)>>1);
amitchell41 0:eff94d72c9f4 492 MMA8452_DBG(" 0 ACTIVE: %d", (v&0x01));
amitchell41 0:eff94d72c9f4 493 break;
amitchell41 0:eff94d72c9f4 494
amitchell41 0:eff94d72c9f4 495 case MMA8452_XYZ_DATA_CFG:
amitchell41 0:eff94d72c9f4 496 MMA8452_DBG("XYZ_DATA_CFG has value: 0x%x",v);
amitchell41 0:eff94d72c9f4 497 MMA8452_DBG(" 7 Unused: %d", (v&0x80)>>7);
amitchell41 0:eff94d72c9f4 498 MMA8452_DBG(" 6 0: %d", (v&0x40)>>6);
amitchell41 0:eff94d72c9f4 499 MMA8452_DBG(" 5 0: %d", (v&0x20)>>5);
amitchell41 0:eff94d72c9f4 500 MMA8452_DBG(" 4 HPF_Out: %d",(v&0x10)>>4);
amitchell41 0:eff94d72c9f4 501 MMA8452_DBG(" 3 0: %d", (v&0x08)>>3);
amitchell41 0:eff94d72c9f4 502 MMA8452_DBG(" 2 0: %d", (v&0x04)>>2);
amitchell41 0:eff94d72c9f4 503 MMA8452_DBG(" 1 FS1: %d", (v&0x02)>>1);
amitchell41 0:eff94d72c9f4 504 MMA8452_DBG(" 0 FS0: %d", (v&0x01));
amitchell41 0:eff94d72c9f4 505 switch(v&0x03) {
amitchell41 0:eff94d72c9f4 506 case 0:
amitchell41 0:eff94d72c9f4 507 MMA8452_DBG("Dynamic range: 2G");
amitchell41 0:eff94d72c9f4 508 break;
amitchell41 0:eff94d72c9f4 509 case 1:
amitchell41 0:eff94d72c9f4 510 MMA8452_DBG("Dynamic range: 4G");
amitchell41 0:eff94d72c9f4 511 break;
amitchell41 0:eff94d72c9f4 512 case 2:
amitchell41 0:eff94d72c9f4 513 MMA8452_DBG("Dynamic range: 8G");
amitchell41 0:eff94d72c9f4 514 break;
amitchell41 0:eff94d72c9f4 515 default:
amitchell41 0:eff94d72c9f4 516 MMA8452_DBG("Unknown dynamic range");
amitchell41 0:eff94d72c9f4 517 break;
amitchell41 0:eff94d72c9f4 518 }
amitchell41 0:eff94d72c9f4 519 break;
amitchell41 0:eff94d72c9f4 520
amitchell41 0:eff94d72c9f4 521 case MMA8452_STATUS:
amitchell41 0:eff94d72c9f4 522 MMA8452_DBG("STATUS has value: 0x%x",v);
amitchell41 0:eff94d72c9f4 523 MMA8452_DBG(" 7 ZYXOW: %d",(v&0x80)>>7);
amitchell41 0:eff94d72c9f4 524 MMA8452_DBG(" 6 ZOW: %d", (v&0x40)>>6);
amitchell41 0:eff94d72c9f4 525 MMA8452_DBG(" 5 YOW: %d", (v&0x20)>>5);
amitchell41 0:eff94d72c9f4 526 MMA8452_DBG(" 4 XOW: %d", (v&0x10)>>4);
amitchell41 0:eff94d72c9f4 527 MMA8452_DBG(" 3 ZYXDR: %d",(v&0x08)>>3);
amitchell41 0:eff94d72c9f4 528 MMA8452_DBG(" 2 ZDR: %d", (v&0x04)>>2);
amitchell41 0:eff94d72c9f4 529 MMA8452_DBG(" 1 YDR: %d", (v&0x02)>>1);
amitchell41 0:eff94d72c9f4 530 MMA8452_DBG(" 0 XDR: %d", (v&0x01));
amitchell41 0:eff94d72c9f4 531 break;
amitchell41 0:eff94d72c9f4 532
amitchell41 0:eff94d72c9f4 533 default:
amitchell41 0:eff94d72c9f4 534 MMA8452_DBG("Unknown register address: 0x%x",reg);
amitchell41 0:eff94d72c9f4 535 break;
amitchell41 0:eff94d72c9f4 536 }
amitchell41 0:eff94d72c9f4 537 }
amitchell41 0:eff94d72c9f4 538 #endif