Library for driving the MMA8452 accelerometer over I2C

Dependents:   MMA8452_Test MMA8452_Demo Dualing_Tanks IMU-Controlled_MP3_Player ... more

Here is a simple example:

#include "mbed.h"
#include "MMA8452.h"

int main() {
   Serial pc(USBTX,USBRX);
   pc.baud(115200);
   double x = 0, y = 0, z = 0;

   MMA8452 acc(p28, p27, 40000);
   acc.setBitDepth(MMA8452::BIT_DEPTH_12);
   acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
   acc.setDataRate(MMA8452::RATE_100);
   
   while(1) {
      if(!acc.isXYZReady()) {
         wait(0.01);
         continue;
      }
      acc.readXYZGravity(&x,&y,&z);
      pc.printf("Gravities: %lf %lf %lf\r\n",x,y,z);
   }
}

An easy way to test that this actually works is to run the loop above and hold the MMA8452 parallel to the ground along the respective axis (and upsidedown in each axis). You will see 1G on the respective axis and 0G on the others.

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 }