1

Committer:
ashleymills
Date:
Wed Mar 05 16:47:13 2014 +0000
Revision:
16:d6dde2318edc
Parent:
14:0602b45ca70f
Child:
17:6e4232c421c0
Added data ready query commands for each independent axes.

Who changed what in which revision?

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