2036 mbed lab4

Dependencies:   4DGL-uLCD-SE PinDetect

Committer:
lhanks02
Date:
Mon Mar 28 18:44:30 2022 +0000
Revision:
0:bbda88bee65a
lab4

Who changed what in which revision?

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