ECE 2035

Dependents:   ECE2035_FroggerGame_SUM2015 ECE2035_FroggerGame_SUM20151241 ECE2035_FroggerGame_SUM2015 rpg_game_shell ... more

Committer:
ece2035ta
Date:
Sun Jul 05 16:35:08 2015 +0000
Revision:
0:53030e47347a
ECE 2035

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