World In Balance game

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Committer:
jchin32
Date:
Wed Nov 08 20:25:03 2017 +0000
Revision:
0:1305fa20a8db
World In Balance Game

Who changed what in which revision?

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