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:
Tue Mar 04 16:23:40 2014 +0000
Revision:
11:dfd1e0afcb7b
Parent:
10:ca9ba7ad4e94
Child:
12:172540ff6b8b
Started a major rewrite of this library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 11:dfd1e0afcb7b 1 // Author: Nicholas Herriot, Ashley Mills
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 11:dfd1e0afcb7b 28 _i2c.frequency(_frequency);
ashleymills 11:dfd1e0afcb7b 29
ashleymills 11:dfd1e0afcb7b 30 // setup read and write addresses to avoid duplication
ashleymills 11:dfd1e0afcb7b 31 _readAddress = MMA8452_ADDRESS | 0x01;
ashleymills 11:dfd1e0afcb7b 32 _writeAddress = MMA8452_ADDRESS & 0xFE;
ashleymills 11:dfd1e0afcb7b 33 DBG("Done");
nherriot 0:bcf2aa85d7f9 34 }
nherriot 0:bcf2aa85d7f9 35
nherriot 0:bcf2aa85d7f9 36
nherriot 0:bcf2aa85d7f9 37 // Destroys instance
ashleymills 10:ca9ba7ad4e94 38 MMA8452::~MMA8452() {}
nherriot 0:bcf2aa85d7f9 39
nherriot 0:bcf2aa85d7f9 40 // Setting the control register bit 1 to true to activate the MMA8452
ashleymills 10:ca9ba7ad4e94 41 int MMA8452::activate() {
ashleymills 6:f6bde04bf8be 42 // perform write and return error code
ashleymills 11:dfd1e0afcb7b 43 return logicalORRegister(CTRL_REG_1,MMA8452_ACTIVE_MASK);
nherriot 3:ffb0b1650ca2 44 }
nherriot 3:ffb0b1650ca2 45
ashleymills 11:dfd1e0afcb7b 46 // Setting the control register bit 1 to 0 to standby the MMA8452
ashleymills 11:dfd1e0afcb7b 47 int MMA8452::standby() {
ashleymills 11:dfd1e0afcb7b 48 // perform write and return error code
ashleymills 11:dfd1e0afcb7b 49 return logicalANDRegister(CTRL_REG_1,MMA8452_STANDBY_MASK);
nherriot 5:b3d0abd97e55 50 }
nherriot 5:b3d0abd97e55 51
ashleymills 11:dfd1e0afcb7b 52 // this reads a register, applies a bitmask with logical AND, sets a value with logical OR,
ashleymills 11:dfd1e0afcb7b 53 // and optionally goes into and out of standby at the beginning and end of the function respectively
ashleymills 11:dfd1e0afcb7b 54 int MMA8452::maskAndApplyRegister(char reg, char mask, char value, int toggleActivation) {
ashleymills 11:dfd1e0afcb7b 55 if(toggleActivation) {
ashleymills 11:dfd1e0afcb7b 56 if(standby()) {
ashleymills 11:dfd1e0afcb7b 57 return 1;
ashleymills 11:dfd1e0afcb7b 58 }
ashleymills 11:dfd1e0afcb7b 59 }
ashleymills 11:dfd1e0afcb7b 60
ashleymills 11:dfd1e0afcb7b 61 // read from register
ashleymills 11:dfd1e0afcb7b 62 char oldValue = 0;
ashleymills 11:dfd1e0afcb7b 63 if(readRegister(reg,&oldValue)) {
ashleymills 11:dfd1e0afcb7b 64 return 1;
ashleymills 11:dfd1e0afcb7b 65 }
ashleymills 11:dfd1e0afcb7b 66
ashleymills 11:dfd1e0afcb7b 67 // apply bitmask
ashleymills 11:dfd1e0afcb7b 68 oldValue &= mask;
ashleymills 11:dfd1e0afcb7b 69
ashleymills 11:dfd1e0afcb7b 70 // set value
ashleymills 11:dfd1e0afcb7b 71 oldValue |= value;
ashleymills 11:dfd1e0afcb7b 72
ashleymills 11:dfd1e0afcb7b 73 // write back to register
ashleymills 11:dfd1e0afcb7b 74 if(writeRegister(reg,oldValue)) {
ashleymills 11:dfd1e0afcb7b 75 return 1;
ashleymills 11:dfd1e0afcb7b 76 }
ashleymills 11:dfd1e0afcb7b 77
ashleymills 11:dfd1e0afcb7b 78 if(toggleActivation) {
ashleymills 11:dfd1e0afcb7b 79 if(activate()) {
ashleymills 11:dfd1e0afcb7b 80 return 1;
ashleymills 11:dfd1e0afcb7b 81 }
ashleymills 11:dfd1e0afcb7b 82 }
ashleymills 11:dfd1e0afcb7b 83 return 0;
nherriot 0:bcf2aa85d7f9 84 }
nherriot 0:bcf2aa85d7f9 85
ashleymills 11:dfd1e0afcb7b 86 int MMA8452::setDynamicRange(DynamicRange range, int toggleActivation) {
ashleymills 11:dfd1e0afcb7b 87 return maskAndApplyRegister(
ashleymills 11:dfd1e0afcb7b 88 MMA8452_XYZ_DATA_CFG,
ashleymills 11:dfd1e0afcb7b 89 MMA8452_DYNAMIC_RANGE_MASK,
ashleymills 11:dfd1e0afcb7b 90 range,
ashleymills 11:dfd1e0afcb7b 91 toggleActivation
ashleymills 11:dfd1e0afcb7b 92 );
nherriot 0:bcf2aa85d7f9 93 }
nherriot 0:bcf2aa85d7f9 94
ashleymills 11:dfd1e0afcb7b 95 int MMA8452::setDataRate(DataRateHz dataRate, int toggleActivation) {
ashleymills 11:dfd1e0afcb7b 96 return maskAndApplyRegister(
ashleymills 11:dfd1e0afcb7b 97 MMA8452_CTRL_REG_1,
ashleymills 11:dfd1e0afcb7b 98 MMA8452_DATA_RATE_MASK,
ashleymills 11:dfd1e0afcb7b 99 dataRate<<MMA8452_DATA_RATE_MASK_SHIFT,
ashleymills 11:dfd1e0afcb7b 100 toggleActivation
ashleymills 11:dfd1e0afcb7b 101 );
nherriot 3:ffb0b1650ca2 102 }
nherriot 3:ffb0b1650ca2 103
ashleymills 11:dfd1e0afcb7b 104 int MMA8452::setBitDepth(BitDepth depth,int toggleActivation) {
ashleymills 11:dfd1e0afcb7b 105 return maskAndApplyRegister(
ashleymills 11:dfd1e0afcb7b 106 MMA8452_CTRL_REG_1,
ashleymills 11:dfd1e0afcb7b 107 MMA8452_BIT_DEPTH_MASK,
ashleymills 11:dfd1e0afcb7b 108 depth<<MMA8452_BIT_DEPTH_MASK_SHIFT,
ashleymills 11:dfd1e0afcb7b 109 toggleActivation
ashleymills 11:dfd1e0afcb7b 110 );
nherriot 3:ffb0b1650ca2 111 }
nherriot 3:ffb0b1650ca2 112
nherriot 0:bcf2aa85d7f9 113
nherriot 1:ef026bf28798 114 // Get device ID
ashleymills 11:dfd1e0afcb7b 115 int MMA8452::getDeviceID(char *dst)
nherriot 1:ef026bf28798 116 {
ashleymills 10:ca9ba7ad4e94 117 return readRegister(WHO_AM_I,dst);
nherriot 1:ef026bf28798 118 }
nherriot 1:ef026bf28798 119
nherriot 1:ef026bf28798 120
ashleymills 10:ca9ba7ad4e94 121 int MMA8452::readRaw(char src, char *dst, int len) {
ashleymills 8:89272163f395 122 // this is the register we want to get data from
ashleymills 8:89272163f395 123 char register_address[1];
ashleymills 8:89272163f395 124 register_address[0] = src;
ashleymills 8:89272163f395 125
ashleymills 11:dfd1e0afcb7b 126 if(_i2c.write(_writeAddress,register_address,1,true) == 0)
ashleymills 8:89272163f395 127 {
ashleymills 11:dfd1e0afcb7b 128 if(_i2c.read(_readAddress,dst,len)==0)
ashleymills 8:89272163f395 129 {
ashleymills 8:89272163f395 130 return 0;
ashleymills 8:89272163f395 131 }
ashleymills 8:89272163f395 132 }
ashleymills 8:89272163f395 133
ashleymills 8:89272163f395 134 // failure case, zero array and return error
ashleymills 8:89272163f395 135 for(int i=0; i<len; i++) {
ashleymills 8:89272163f395 136 dst[i] = 0x00;
ashleymills 8:89272163f395 137 }
ashleymills 8:89272163f395 138 return 1;
ashleymills 8:89272163f395 139 }
nherriot 3:ffb0b1650ca2 140
nherriot 3:ffb0b1650ca2 141 // Reads x data. This method reads two registers containing the x-axis values from the accelerometer.
nherriot 3:ffb0b1650ca2 142 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
nherriot 3:ffb0b1650ca2 143 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
nherriot 3:ffb0b1650ca2 144 // the raw data.
ashleymills 10:ca9ba7ad4e94 145 //int MMA8452::read_x(int& xaxisLSB)
ashleymills 11:dfd1e0afcb7b 146 int MMA8452::readRawX(char *xaxis) {
ashleymills 10:ca9ba7ad4e94 147 return readRaw(OUT_X_MSB,xaxis,2);
nherriot 0:bcf2aa85d7f9 148 }
nherriot 0:bcf2aa85d7f9 149
nherriot 0:bcf2aa85d7f9 150
nherriot 3:ffb0b1650ca2 151 // Reads y data. This method reads two registers containing the x-axis values from the accelerometer.
nherriot 3:ffb0b1650ca2 152 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
nherriot 3:ffb0b1650ca2 153 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
nherriot 3:ffb0b1650ca2 154 // the raw data.
nherriot 3:ffb0b1650ca2 155
ashleymills 10:ca9ba7ad4e94 156 int MMA8452::readRawY(char *yaxis) {
ashleymills 10:ca9ba7ad4e94 157 return readRaw(OUT_Y_MSB,yaxis,2);
nherriot 3:ffb0b1650ca2 158 }
nherriot 3:ffb0b1650ca2 159
nherriot 0:bcf2aa85d7f9 160
nherriot 3:ffb0b1650ca2 161
nherriot 3:ffb0b1650ca2 162 // Reads z data. This method reads two registers containing the x-axis values from the accelerometer.
nherriot 3:ffb0b1650ca2 163 // It takes a 2 byte char array and copies the register values into the buffer. If it fails the char array
nherriot 3:ffb0b1650ca2 164 // is set to '0'. It returns '0' success '1' fail. This method does nothing to the registers - just returns
nherriot 3:ffb0b1650ca2 165 // the raw data.
nherriot 3:ffb0b1650ca2 166
ashleymills 10:ca9ba7ad4e94 167 int MMA8452::readRawZ(char *zaxis)
nherriot 3:ffb0b1650ca2 168 {
ashleymills 10:ca9ba7ad4e94 169 return readRaw(OUT_Z_MSB,zaxis,2);
nherriot 3:ffb0b1650ca2 170 }
nherriot 0:bcf2aa85d7f9 171
nherriot 0:bcf2aa85d7f9 172
nherriot 0:bcf2aa85d7f9 173
nherriot 0:bcf2aa85d7f9 174 // Reads y data
ashleymills 10:ca9ba7ad4e94 175 int MMA8452::read_y()
nherriot 0:bcf2aa85d7f9 176 {
nherriot 1:ef026bf28798 177 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 0:bcf2aa85d7f9 178
ashleymills 11:dfd1e0afcb7b 179 _i2c.start(); // Start
ashleymills 11:dfd1e0afcb7b 180 _i2c.write(mcu_address); // A write to device 0x98
ashleymills 11:dfd1e0afcb7b 181 _i2c.write(OUT_Y_MSB); // Register to read
ashleymills 11:dfd1e0afcb7b 182 _i2c.start();
ashleymills 11:dfd1e0afcb7b 183 _i2c.write(mcu_address); // Read from device 0x99
ashleymills 11:dfd1e0afcb7b 184 int y = _i2c.read(0); // Read the data
ashleymills 11:dfd1e0afcb7b 185 _i2c.stop();
nherriot 0:bcf2aa85d7f9 186
nherriot 1:ef026bf28798 187 return y;
nherriot 0:bcf2aa85d7f9 188
nherriot 0:bcf2aa85d7f9 189 }
nherriot 0:bcf2aa85d7f9 190
nherriot 0:bcf2aa85d7f9 191 // Reads z data
ashleymills 10:ca9ba7ad4e94 192 int MMA8452::read_z()
nherriot 0:bcf2aa85d7f9 193 {
nherriot 1:ef026bf28798 194 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 0:bcf2aa85d7f9 195
ashleymills 11:dfd1e0afcb7b 196 _i2c.start(); // Start
ashleymills 11:dfd1e0afcb7b 197 _i2c.write(mcu_address); // A write to device 0x98
ashleymills 11:dfd1e0afcb7b 198 _i2c.write(OUT_Z_MSB); // Register to read
ashleymills 11:dfd1e0afcb7b 199 _i2c.start();
ashleymills 11:dfd1e0afcb7b 200 _i2c.write(mcu_address); // Read from device 0x99
ashleymills 11:dfd1e0afcb7b 201 int z = _i2c.read(0); // Read the data
ashleymills 11:dfd1e0afcb7b 202 _i2c.stop();
nherriot 0:bcf2aa85d7f9 203
nherriot 1:ef026bf28798 204 return z;
nherriot 0:bcf2aa85d7f9 205
nherriot 0:bcf2aa85d7f9 206 }
nherriot 0:bcf2aa85d7f9 207
nherriot 0:bcf2aa85d7f9 208
ashleymills 11:dfd1e0afcb7b 209 MMA8452::DynamicRange MMA8452::getDynamicRange() {
ashleymills 11:dfd1e0afcb7b 210 char rval = 0;
ashleymills 11:dfd1e0afcb7b 211 if(readRegister(MMA8452_CTRL_REG_1,&rval)) {
ashleymills 11:dfd1e0afcb7b 212 return MMA8452::DYNAMIC_RANGE_UNKNOWN;
ashleymills 11:dfd1e0afcb7b 213 }
ashleymills 11:dfd1e0afcb7b 214 rval &= (MMA8452_DYNAMIC_RANGE_MASK^0xFF);
ashleymills 11:dfd1e0afcb7b 215 return (MMA8452::DynamicRange)rval;
ashleymills 11:dfd1e0afcb7b 216 }
ashleymills 11:dfd1e0afcb7b 217
ashleymills 11:dfd1e0afcb7b 218 MMA8452::DataRateHz MMA8452::getDataRate() {
ashleymills 11:dfd1e0afcb7b 219 char rval = 0;
ashleymills 11:dfd1e0afcb7b 220 if(readRegister(MMA8452_CTRL_REG_1,&rval)) {
ashleymills 11:dfd1e0afcb7b 221 return MMA8452::RATE_UNKNOWN;
ashleymills 11:dfd1e0afcb7b 222 }
ashleymills 11:dfd1e0afcb7b 223 // logical AND with inverse of mask
ashleymills 11:dfd1e0afcb7b 224 rval = rval&(MMA8452_DATA_RATE_MASK^0xFF);
ashleymills 11:dfd1e0afcb7b 225 // shift back into position
ashleymills 11:dfd1e0afcb7b 226 rval >>= MMA8452_DATA_RATE_MASK_SHIFT;
ashleymills 11:dfd1e0afcb7b 227 return (MMA8452::DataRateHz)rval;
ashleymills 11:dfd1e0afcb7b 228 }
ashleymills 11:dfd1e0afcb7b 229
nherriot 0:bcf2aa85d7f9 230 // Reads xyz
ashleymills 10:ca9ba7ad4e94 231 int MMA8452::readRawXYZ(char *x, char *y, char *z)
nherriot 1:ef026bf28798 232 {
nherriot 1:ef026bf28798 233
nherriot 1:ef026bf28798 234
nherriot 1:ef026bf28798 235 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 1:ef026bf28798 236 char register_buffer[6] ={0,0,0,0,0,0};
nherriot 1:ef026bf28798 237 const char Addr_X = OUT_X_MSB;
ashleymills 11:dfd1e0afcb7b 238 _i2c.write(mcu_address); // A write to device 0x98
ashleymills 11:dfd1e0afcb7b 239 _i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register
nherriot 1:ef026bf28798 240
ashleymills 11:dfd1e0afcb7b 241 if(_i2c.write(mcu_address,&Addr_X,1) == 0)
nherriot 1:ef026bf28798 242 {
ashleymills 11:dfd1e0afcb7b 243 if(_i2c.read(mcu_address,register_buffer,6) == 0)
nherriot 1:ef026bf28798 244 {
nherriot 1:ef026bf28798 245 *x = register_buffer[1];
nherriot 1:ef026bf28798 246 *y = register_buffer[3];
nherriot 1:ef026bf28798 247 *z = register_buffer[5];
nherriot 1:ef026bf28798 248 return 0; // yahoooooo
nherriot 1:ef026bf28798 249 }
nherriot 1:ef026bf28798 250 else
nherriot 1:ef026bf28798 251 {
nherriot 1:ef026bf28798 252 return 1; // failed oh nooo!
nherriot 1:ef026bf28798 253 }
nherriot 1:ef026bf28798 254 }
nherriot 1:ef026bf28798 255 else
nherriot 1:ef026bf28798 256 {
nherriot 1:ef026bf28798 257 return 1; // failed oh nooo!
nherriot 1:ef026bf28798 258 }
nherriot 0:bcf2aa85d7f9 259
nherriot 1:ef026bf28798 260 }
nherriot 0:bcf2aa85d7f9 261
ashleymills 11:dfd1e0afcb7b 262 // apply an AND mask to a register. read register value, apply mask, write it back
ashleymills 11:dfd1e0afcb7b 263 int MMA8452::logicalANDRegister(char addr, char mask) {
ashleymills 11:dfd1e0afcb7b 264 char value = 0;
ashleymills 11:dfd1e0afcb7b 265 // read register value
ashleymills 11:dfd1e0afcb7b 266 if(readRegister(addr,&value)) {
ashleymills 11:dfd1e0afcb7b 267 return 0;
ashleymills 11:dfd1e0afcb7b 268 }
ashleymills 11:dfd1e0afcb7b 269 // apply mask
ashleymills 11:dfd1e0afcb7b 270 value &= mask;
ashleymills 11:dfd1e0afcb7b 271 return writeRegister(addr,value);
ashleymills 11:dfd1e0afcb7b 272 }
ashleymills 11:dfd1e0afcb7b 273
ashleymills 11:dfd1e0afcb7b 274
ashleymills 11:dfd1e0afcb7b 275 // apply an OR mask to a register. read register value, apply mask, write it back
ashleymills 11:dfd1e0afcb7b 276 int MMA8452::logicalORRegister(char addr, char mask) {
ashleymills 11:dfd1e0afcb7b 277 char value = 0;
ashleymills 11:dfd1e0afcb7b 278 // read register value
ashleymills 11:dfd1e0afcb7b 279 if(readRegister(addr,&value)) {
ashleymills 11:dfd1e0afcb7b 280 return 0;
ashleymills 11:dfd1e0afcb7b 281 }
ashleymills 11:dfd1e0afcb7b 282 // apply mask
ashleymills 11:dfd1e0afcb7b 283 value |= mask;
ashleymills 11:dfd1e0afcb7b 284 return writeRegister(addr,value);
ashleymills 11:dfd1e0afcb7b 285 }
ashleymills 11:dfd1e0afcb7b 286
nherriot 0:bcf2aa85d7f9 287
ashleymills 11:dfd1e0afcb7b 288 // apply an OR mask to a register. read register value, apply mask, write it back
ashleymills 11:dfd1e0afcb7b 289 int MMA8452::logicalXORRegister(char addr, char mask) {
ashleymills 11:dfd1e0afcb7b 290 char value = 0;
ashleymills 11:dfd1e0afcb7b 291 // read register value
ashleymills 11:dfd1e0afcb7b 292 if(readRegister(addr,&value)) {
ashleymills 11:dfd1e0afcb7b 293 return 0;
ashleymills 11:dfd1e0afcb7b 294 }
ashleymills 11:dfd1e0afcb7b 295 // apply mask
ashleymills 11:dfd1e0afcb7b 296 value ^= mask;
ashleymills 11:dfd1e0afcb7b 297 return writeRegister(addr,value);
ashleymills 11:dfd1e0afcb7b 298 }
ashleymills 11:dfd1e0afcb7b 299
ashleymills 11:dfd1e0afcb7b 300 // Write register (The device must be placed in Standby Mode to change the value of the registers)
ashleymills 11:dfd1e0afcb7b 301 int MMA8452::writeRegister(char addr, char data) {
ashleymills 11:dfd1e0afcb7b 302 // what this actually does is the following
ashleymills 11:dfd1e0afcb7b 303 // 1. tell I2C bus to start transaction
ashleymills 11:dfd1e0afcb7b 304 // 2. tell slave we want to write (slave address & write flag)
ashleymills 11:dfd1e0afcb7b 305 // 3. send the write address
ashleymills 11:dfd1e0afcb7b 306 // 4. send the data to write
ashleymills 11:dfd1e0afcb7b 307 // 5. tell I2C bus to end transaction
ashleymills 11:dfd1e0afcb7b 308
ashleymills 11:dfd1e0afcb7b 309 // we can wrap this up in the I2C library write function
ashleymills 11:dfd1e0afcb7b 310 char buf[2] = {0,0};
ashleymills 11:dfd1e0afcb7b 311 buf[0] = addr;
ashleymills 11:dfd1e0afcb7b 312 buf[1] = data;
ashleymills 11:dfd1e0afcb7b 313 return _i2c.write(MMA8452_ADDRESS, buf,2);
ashleymills 11:dfd1e0afcb7b 314 // note, could also do return writeRegister(addr,&data,1);
nherriot 0:bcf2aa85d7f9 315 }
nherriot 0:bcf2aa85d7f9 316
ashleymills 11:dfd1e0afcb7b 317
ashleymills 11:dfd1e0afcb7b 318 int MMA8452::writeRegister(char addr, char *data, int nbytes) {
ashleymills 11:dfd1e0afcb7b 319 // writing multiple bytes is a little bit annoying because
ashleymills 11:dfd1e0afcb7b 320 // the I2C library doesn't support sending the address separately
ashleymills 11:dfd1e0afcb7b 321 // so we just do it manually
nherriot 0:bcf2aa85d7f9 322
ashleymills 11:dfd1e0afcb7b 323 // 1. tell I2C bus to start transaction
ashleymills 11:dfd1e0afcb7b 324 _i2c.start();
ashleymills 11:dfd1e0afcb7b 325 // 2. tell slave we want to write (slave address & write flag)
ashleymills 11:dfd1e0afcb7b 326 if(_i2c.write(_writeAddress)!=1) {
ashleymills 11:dfd1e0afcb7b 327 return 1;
ashleymills 11:dfd1e0afcb7b 328 }
ashleymills 11:dfd1e0afcb7b 329 // 3. send the write address
ashleymills 11:dfd1e0afcb7b 330 if(_i2c.write(addr)!=1) {
ashleymills 11:dfd1e0afcb7b 331 return 1;
ashleymills 11:dfd1e0afcb7b 332 }
ashleymills 11:dfd1e0afcb7b 333 // 4. send the data to write
ashleymills 11:dfd1e0afcb7b 334 for(int i=0; i<nbytes; i++) {
ashleymills 11:dfd1e0afcb7b 335 if(_i2c.write(data[i])!=1) {
ashleymills 11:dfd1e0afcb7b 336 return 1;
ashleymills 11:dfd1e0afcb7b 337 }
ashleymills 11:dfd1e0afcb7b 338 }
ashleymills 11:dfd1e0afcb7b 339 // 5. tell I2C bus to end transaction
ashleymills 11:dfd1e0afcb7b 340 _i2c.stop();
ashleymills 11:dfd1e0afcb7b 341 return 0;
ashleymills 11:dfd1e0afcb7b 342 }
ashleymills 11:dfd1e0afcb7b 343
ashleymills 11:dfd1e0afcb7b 344 int MMA8452::readRegister(char addr, char *dst, int nbytes) {
ashleymills 11:dfd1e0afcb7b 345 // this is a bit odd, but basically proceeds like this
ashleymills 11:dfd1e0afcb7b 346 // 1. Send a start command
ashleymills 11:dfd1e0afcb7b 347 // 2. Tell the slave we want to write (slave address & write flag)
ashleymills 11:dfd1e0afcb7b 348 // 3. Send the address of the register (addr)
ashleymills 11:dfd1e0afcb7b 349 // 4. Send another start command to delineate read portion
ashleymills 11:dfd1e0afcb7b 350 // 5. Tell the slave we want to read (slave address & read flag)
ashleymills 11:dfd1e0afcb7b 351 // 6. Read the register value bytes
ashleymills 11:dfd1e0afcb7b 352 // 7. Send a stop command
ashleymills 11:dfd1e0afcb7b 353
ashleymills 11:dfd1e0afcb7b 354 // we can wrap this process in the I2C library read and write commands
ashleymills 11:dfd1e0afcb7b 355 if(_i2c.write(MMA8452_ADDRESS,&addr,1,true)) {
ashleymills 11:dfd1e0afcb7b 356 return 1;
ashleymills 8:89272163f395 357 }
ashleymills 11:dfd1e0afcb7b 358 return _i2c.read(MMA8452_ADDRESS,dst,nbytes);
ashleymills 11:dfd1e0afcb7b 359 }
ashleymills 11:dfd1e0afcb7b 360
ashleymills 11:dfd1e0afcb7b 361 // most registers are 1 byte, so here is a convenience function
ashleymills 11:dfd1e0afcb7b 362 int MMA8452::readRegister(char addr, char *dst) {
ashleymills 11:dfd1e0afcb7b 363 return readRegister(addr,dst,1);
nherriot 0:bcf2aa85d7f9 364 }
ashleymills 11:dfd1e0afcb7b 365
ashleymills 11:dfd1e0afcb7b 366 void MMA8452::debugRegister(char reg) {
ashleymills 11:dfd1e0afcb7b 367 // get register value
ashleymills 11:dfd1e0afcb7b 368 char v = 0;
ashleymills 11:dfd1e0afcb7b 369 if(readRegister(reg,&v)) {
ashleymills 11:dfd1e0afcb7b 370 DBG("Error reading control register");
ashleymills 11:dfd1e0afcb7b 371 return;
ashleymills 11:dfd1e0afcb7b 372 }
ashleymills 11:dfd1e0afcb7b 373 // print out details
ashleymills 11:dfd1e0afcb7b 374 switch(reg) {
ashleymills 11:dfd1e0afcb7b 375 case MMA8452_CTRL_REG_1:
ashleymills 11:dfd1e0afcb7b 376 DBG("CTRL_REG_1 has value: 0x%x",v);
ashleymills 11:dfd1e0afcb7b 377 DBG(" 7 ALSP_RATE_1: %d",(v&0x80)>>7);
ashleymills 11:dfd1e0afcb7b 378 DBG(" 6 ALSP_RATE_0: %d",(v&0x40)>>6);
ashleymills 11:dfd1e0afcb7b 379 DBG(" 5 DR2: %d", (v&0x20)>>5);
ashleymills 11:dfd1e0afcb7b 380 DBG(" 4 DR1: %d", (v&0x10)>>4);
ashleymills 11:dfd1e0afcb7b 381 DBG(" 3 DR0: %d", (v&0x08)>>3);
ashleymills 11:dfd1e0afcb7b 382 DBG(" 2 LNOISE: %d", (v&0x04)>>2);
ashleymills 11:dfd1e0afcb7b 383 DBG(" 1 FREAD: %d", (v&0x02)>>1);
ashleymills 11:dfd1e0afcb7b 384 DBG(" 0 ACTIVE: %d", (v&0x01));
ashleymills 11:dfd1e0afcb7b 385 break;
ashleymills 11:dfd1e0afcb7b 386
ashleymills 11:dfd1e0afcb7b 387 case MMA8452_XYZ_DATA_CFG:
ashleymills 11:dfd1e0afcb7b 388 DBG("XYZ_DATA_CFG has value: 0x%x",v);
ashleymills 11:dfd1e0afcb7b 389 DBG(" 7 Unused: %d", (v&0x80)>>7);
ashleymills 11:dfd1e0afcb7b 390 DBG(" 6 0: %d", (v&0x40)>>6);
ashleymills 11:dfd1e0afcb7b 391 DBG(" 5 0: %d", (v&0x20)>>5);
ashleymills 11:dfd1e0afcb7b 392 DBG(" 4 HPF_Out: %d",(v&0x10)>>4);
ashleymills 11:dfd1e0afcb7b 393 DBG(" 3 0: %d", (v&0x08)>>3);
ashleymills 11:dfd1e0afcb7b 394 DBG(" 2 0: %d", (v&0x04)>>2);
ashleymills 11:dfd1e0afcb7b 395 DBG(" 1 FS1: %d", (v&0x02)>>1);
ashleymills 11:dfd1e0afcb7b 396 DBG(" 0 FS0: %d", (v&0x01));
ashleymills 11:dfd1e0afcb7b 397 switch(v&0x03) {
ashleymills 11:dfd1e0afcb7b 398 case 0:
ashleymills 11:dfd1e0afcb7b 399 DBG("Dynamic range: 2G");
ashleymills 11:dfd1e0afcb7b 400 break;
ashleymills 11:dfd1e0afcb7b 401 case 1:
ashleymills 11:dfd1e0afcb7b 402 DBG("Dynamic range: 4G");
ashleymills 11:dfd1e0afcb7b 403 break;
ashleymills 11:dfd1e0afcb7b 404 case 2:
ashleymills 11:dfd1e0afcb7b 405 DBG("Dynamic range: 8G");
ashleymills 11:dfd1e0afcb7b 406 break;
ashleymills 11:dfd1e0afcb7b 407 default:
ashleymills 11:dfd1e0afcb7b 408 DBG("Unknown dynamic range");
ashleymills 11:dfd1e0afcb7b 409 break;
ashleymills 11:dfd1e0afcb7b 410 }
ashleymills 11:dfd1e0afcb7b 411 break;
ashleymills 11:dfd1e0afcb7b 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 }