MMA8452

Dependents:   ECE2035_SUM17_Project

Committer:
kennyainny
Date:
Fri Jul 14 21:42:37 2017 +0000
Revision:
0:79012a2fa4d1
no changes

Who changed what in which revision?

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