library mma8452

Dependents:   APP3_Capteur_V2

Fork of MMA8452 by Ashley Mills

Committer:
ashleymills
Date:
Fri Mar 07 11:55:30 2014 +0000
Revision:
20:d55e9d7eb17e
Parent:
19:4d6cd7140a71
Child:
21:a92a632a0cc7
Independent read methods present.

Who changed what in which revision?

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