LAME

Dependencies:   mbed 4DGL-uLCD-SE SDFileSystem PinDetect

Committer:
kmillion3
Date:
Sun May 01 22:17:57 2022 +0000
Revision:
5:05f7a84d0078
LAME;

Who changed what in which revision?

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