Andrew Shi / Mbed 2 deprecated Lab4

Dependencies:   mbed 4DGL-uLCD-SE PinDetect

Committer:
ashi31
Date:
Fri Oct 22 03:57:47 2021 +0000
Revision:
0:7d8ffdfdb16e
Lab4

Who changed what in which revision?

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