ECE 2035

Fork of MMA8452 by ECE 2035

Committer:
luisbc92
Date:
Tue Feb 09 19:45:03 2016 +0000
Revision:
1:f92fe1e48ab7
Parent:
0:53030e47347a
Tag Mod

Who changed what in which revision?

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