Laser tag guns code https://os.mbed.com/users/ddakev/notebook/laser-tag-system/

Dependencies:   mbed 4DGL-uLCD-SE PinDetect SoftI2C

Committer:
ddakev
Date:
Mon Apr 22 17:40:30 2019 +0000
Revision:
1:7d957da791a5
Parent:
0:4c644bb83761
Bug fixes

Who changed what in which revision?

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