WITB2

Dependencies:   mbed 4DGL-uLCD-SE PinDetect

Committer:
Nydrel
Date:
Thu Nov 29 18:37:00 2018 +0000
Revision:
5:ed52ac77cdf9
Parent:
0:5e90b8577fef
witb 2;

Who changed what in which revision?

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