pocket tanks

Committer:
ece2035ta
Date:
Sun Oct 04 20:55:34 2015 +0000
Revision:
0:fccb20977af0
\Yay!

Who changed what in which revision?

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