Lab4

Dependencies:   mbed 4DGL-uLCD-SE PinDetect

Committer:
ckaminsky7
Date:
Fri Oct 22 20:30:07 2021 +0000
Revision:
0:42967dd26360
Lab4 Farkle Game

Who changed what in which revision?

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