A simple asteroids-like game utilizing various Mbed-compatible sensors

Dependencies:   mbed 4DGL-uLCD-SE PinDetect

Committer:
sralph3
Date:
Thu Jan 03 19:56:27 2019 +0000
Revision:
8:137330cfe63d
Parent:
0:f2cc64948895
Jan 3, 2019

Who changed what in which revision?

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