1

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 }