ECE 2036 Project

Dependencies:   mbed wave_player 4DGL-uLCD-SE

Committer:
abraha2d
Date:
Thu Nov 21 16:10:57 2019 +0000
Revision:
2:2042f29de6b7
Parent:
0:cf4396614a79
Because other peeps is wanting dis...

Who changed what in which revision?

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