A compilation of some hardware sensors and their shared programming interfaces.

Committer:
mgottscho
Date:
Wed Mar 19 00:35:31 2014 +0000
Revision:
1:15396cab58d1
Parent:
0:8d34cc2ff388
Updated for most recent UtilityLib.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mgottscho 0:8d34cc2ff388 1 /* MMA8451Q.cpp
mgottscho 0:8d34cc2ff388 2 * Tested with mbed board: FRDM-KL46Z
mgottscho 0:8d34cc2ff388 3 * Author: Mark Gottscho
mgottscho 0:8d34cc2ff388 4 * mgottscho@ucla.edu
mgottscho 0:8d34cc2ff388 5 */
mgottscho 0:8d34cc2ff388 6
mgottscho 0:8d34cc2ff388 7 #include "mbed.h"
mgottscho 0:8d34cc2ff388 8 #include "I2CSensor.h"
mgottscho 0:8d34cc2ff388 9 #include "PeriodicSensor.h"
mgottscho 0:8d34cc2ff388 10 #include "SleepableSensor.h"
mgottscho 0:8d34cc2ff388 11 #include "MMA8451Q.h"
mgottscho 0:8d34cc2ff388 12
mgottscho 0:8d34cc2ff388 13 using namespace std;
mgottscho 0:8d34cc2ff388 14
mgottscho 0:8d34cc2ff388 15 //////////////////// PUBLIC METHODS ////////////////////
mgottscho 0:8d34cc2ff388 16
mgottscho 0:8d34cc2ff388 17 MMA8451Q::MMA8451Q(PinName sda, PinName scl, int i2c_addr) :
mgottscho 0:8d34cc2ff388 18 I2CSensor(sda, scl, i2c_addr), //parent constructor
mgottscho 0:8d34cc2ff388 19 PeriodicSensor(0.05), //default max sampling rate of 20Hz
mgottscho 0:8d34cc2ff388 20 SleepableSensor(),
mgottscho 0:8d34cc2ff388 21 __x(0),
mgottscho 0:8d34cc2ff388 22 __y(0),
mgottscho 0:8d34cc2ff388 23 __z(0),
mgottscho 0:8d34cc2ff388 24 __active(false),
mgottscho 0:8d34cc2ff388 25 __14b_data_enabled(true),
mgottscho 0:8d34cc2ff388 26 __output_data_rate(MMA8451Q::smpl_rate_t(0)),
mgottscho 0:8d34cc2ff388 27 __scale(MMA8451Q::scale_t(0)),
mgottscho 0:8d34cc2ff388 28 __div(G2_DIV)
mgottscho 0:8d34cc2ff388 29 { }
mgottscho 0:8d34cc2ff388 30
mgottscho 0:8d34cc2ff388 31 MMA8451Q::~MMA8451Q() {}
mgottscho 0:8d34cc2ff388 32
mgottscho 0:8d34cc2ff388 33 void MMA8451Q::selfInit() {
mgottscho 0:8d34cc2ff388 34 __i2c.frequency(400000);
mgottscho 0:8d34cc2ff388 35 reset();
mgottscho 0:8d34cc2ff388 36 setOutputDataRate(HZ800);
mgottscho 0:8d34cc2ff388 37 setScale(G2);
mgottscho 0:8d34cc2ff388 38 set14bData(true);
mgottscho 0:8d34cc2ff388 39 //enableDataReadyInterrupt(true, true); //INT1
mgottscho 0:8d34cc2ff388 40 }
mgottscho 0:8d34cc2ff388 41
mgottscho 0:8d34cc2ff388 42 void MMA8451Q::reset() {
mgottscho 0:8d34cc2ff388 43 uint8_t data = CTRL_REG2_RST_MASK;
mgottscho 0:8d34cc2ff388 44 setRegister(CTRL_REG2, data);
mgottscho 0:8d34cc2ff388 45 wait(0.1);
mgottscho 0:8d34cc2ff388 46 }
mgottscho 0:8d34cc2ff388 47
mgottscho 0:8d34cc2ff388 48 uint8_t MMA8451Q::whoAmI() {
mgottscho 0:8d34cc2ff388 49 return getRegister(WHO_AM_I);
mgottscho 0:8d34cc2ff388 50 }
mgottscho 0:8d34cc2ff388 51
mgottscho 0:8d34cc2ff388 52 bool MMA8451Q::isActive() {
mgottscho 0:8d34cc2ff388 53 return __active;
mgottscho 0:8d34cc2ff388 54 }
mgottscho 0:8d34cc2ff388 55
mgottscho 0:8d34cc2ff388 56 void MMA8451Q::setActive(bool activate) {
mgottscho 0:8d34cc2ff388 57 uint8_t data;
mgottscho 0:8d34cc2ff388 58 data = getRegister(CTRL_REG1);
mgottscho 0:8d34cc2ff388 59 if (activate)
mgottscho 0:8d34cc2ff388 60 data |= CTRL_REG1_ACTIVE_MASK; //Set bit
mgottscho 0:8d34cc2ff388 61 else
mgottscho 0:8d34cc2ff388 62 data &= ~CTRL_REG1_ACTIVE_MASK; //Clear bit
mgottscho 0:8d34cc2ff388 63 setRegister(CTRL_REG1, data);
mgottscho 0:8d34cc2ff388 64 __active = activate;
mgottscho 0:8d34cc2ff388 65 }
mgottscho 0:8d34cc2ff388 66
mgottscho 0:8d34cc2ff388 67 uint8_t MMA8451Q::getSystemMode() {
mgottscho 0:8d34cc2ff388 68 return getRegister(SYSMOD);
mgottscho 0:8d34cc2ff388 69 }
mgottscho 0:8d34cc2ff388 70
mgottscho 0:8d34cc2ff388 71 bool MMA8451Q::is14bDataEnabled() {
mgottscho 0:8d34cc2ff388 72 return __14b_data_enabled;
mgottscho 0:8d34cc2ff388 73 }
mgottscho 0:8d34cc2ff388 74
mgottscho 0:8d34cc2ff388 75 void MMA8451Q::set14bData(bool enable) {
mgottscho 0:8d34cc2ff388 76 bool wasActive = isActive();
mgottscho 0:8d34cc2ff388 77 if (wasActive)
mgottscho 0:8d34cc2ff388 78 setActive(false); //deactivate before updating control bits
mgottscho 0:8d34cc2ff388 79
mgottscho 0:8d34cc2ff388 80 uint8_t data;
mgottscho 0:8d34cc2ff388 81 data = getRegister(CTRL_REG1);
mgottscho 0:8d34cc2ff388 82 data = (data & ~CTRL_REG1_F_READ_MASK) | (CTRL_REG1_F_READ_MASK & enable); //Set 2nd LSB to enable
mgottscho 0:8d34cc2ff388 83 setRegister(CTRL_REG1, data);
mgottscho 0:8d34cc2ff388 84 __14b_data_enabled = enable;
mgottscho 0:8d34cc2ff388 85
mgottscho 0:8d34cc2ff388 86 if (wasActive)
mgottscho 0:8d34cc2ff388 87 setActive(true); //restore activity
mgottscho 0:8d34cc2ff388 88 }
mgottscho 0:8d34cc2ff388 89
mgottscho 0:8d34cc2ff388 90 MMA8451Q::smpl_rate_t MMA8451Q::getOutputDataRate() {
mgottscho 0:8d34cc2ff388 91 return __output_data_rate;
mgottscho 0:8d34cc2ff388 92 }
mgottscho 0:8d34cc2ff388 93
mgottscho 0:8d34cc2ff388 94 void MMA8451Q::setOutputDataRate(MMA8451Q::smpl_rate_t rate) {
mgottscho 0:8d34cc2ff388 95 bool wasActive = __active;
mgottscho 0:8d34cc2ff388 96 if (wasActive)
mgottscho 0:8d34cc2ff388 97 setActive(false); //must disable to update register
mgottscho 0:8d34cc2ff388 98
mgottscho 0:8d34cc2ff388 99 uint8_t data, dr;
mgottscho 0:8d34cc2ff388 100 data = getRegister(CTRL_REG1);
mgottscho 0:8d34cc2ff388 101 switch (rate) {
mgottscho 0:8d34cc2ff388 102 case HZ800:
mgottscho 0:8d34cc2ff388 103 dr = 0;
mgottscho 0:8d34cc2ff388 104 break;
mgottscho 0:8d34cc2ff388 105 case HZ400:
mgottscho 0:8d34cc2ff388 106 dr = 1;
mgottscho 0:8d34cc2ff388 107 break;
mgottscho 0:8d34cc2ff388 108 case HZ200:
mgottscho 0:8d34cc2ff388 109 dr = 2;
mgottscho 0:8d34cc2ff388 110 break;
mgottscho 0:8d34cc2ff388 111 case HZ100:
mgottscho 0:8d34cc2ff388 112 dr = 3;
mgottscho 0:8d34cc2ff388 113 break;
mgottscho 0:8d34cc2ff388 114 case HZ50:
mgottscho 0:8d34cc2ff388 115 dr = 4;
mgottscho 0:8d34cc2ff388 116 break;
mgottscho 0:8d34cc2ff388 117 case HZ12_5:
mgottscho 0:8d34cc2ff388 118 dr = 5;
mgottscho 0:8d34cc2ff388 119 break;
mgottscho 0:8d34cc2ff388 120 case HZ6_25:
mgottscho 0:8d34cc2ff388 121 dr = 6;
mgottscho 0:8d34cc2ff388 122 break;
mgottscho 0:8d34cc2ff388 123 case HZ1_56:
mgottscho 0:8d34cc2ff388 124 dr = 7;
mgottscho 0:8d34cc2ff388 125 break;
mgottscho 0:8d34cc2ff388 126 default:
mgottscho 0:8d34cc2ff388 127 dr = 0; //800HZ
mgottscho 0:8d34cc2ff388 128 break;
mgottscho 0:8d34cc2ff388 129 }
mgottscho 0:8d34cc2ff388 130 data = (data & ~CTRL_REG1_DR_MASK) | (dr << 3);
mgottscho 0:8d34cc2ff388 131 setRegister(CTRL_REG1, data);
mgottscho 0:8d34cc2ff388 132
mgottscho 0:8d34cc2ff388 133 if (wasActive)
mgottscho 0:8d34cc2ff388 134 setActive(true); //Restore active state
mgottscho 0:8d34cc2ff388 135
mgottscho 0:8d34cc2ff388 136 __output_data_rate = rate;
mgottscho 0:8d34cc2ff388 137 }
mgottscho 0:8d34cc2ff388 138
mgottscho 0:8d34cc2ff388 139 MMA8451Q::scale_t MMA8451Q::getScale() {
mgottscho 0:8d34cc2ff388 140 return __scale;
mgottscho 0:8d34cc2ff388 141 }
mgottscho 0:8d34cc2ff388 142
mgottscho 0:8d34cc2ff388 143 void MMA8451Q::setScale(MMA8451Q::scale_t scale) {
mgottscho 0:8d34cc2ff388 144 bool wasActive = __active;
mgottscho 0:8d34cc2ff388 145 if (wasActive)
mgottscho 0:8d34cc2ff388 146 setActive(false); //deactivate before updating control bits
mgottscho 0:8d34cc2ff388 147
mgottscho 0:8d34cc2ff388 148 uint8_t data = getRegister(XYZ_DATA_CFG);
mgottscho 0:8d34cc2ff388 149 data = (data & ~XYZ_DATA_CFG_FS_MASK) | scale;
mgottscho 0:8d34cc2ff388 150 setRegister(XYZ_DATA_CFG, data);
mgottscho 0:8d34cc2ff388 151
mgottscho 0:8d34cc2ff388 152 if (wasActive)
mgottscho 0:8d34cc2ff388 153 setActive(true); //restore activity
mgottscho 0:8d34cc2ff388 154
mgottscho 0:8d34cc2ff388 155 __scale = scale;
mgottscho 0:8d34cc2ff388 156 switch (scale) {
mgottscho 0:8d34cc2ff388 157 default:
mgottscho 0:8d34cc2ff388 158 case G2:
mgottscho 0:8d34cc2ff388 159 __div = G2_DIV;
mgottscho 0:8d34cc2ff388 160 break;
mgottscho 0:8d34cc2ff388 161 case G4:
mgottscho 0:8d34cc2ff388 162 __div = G4_DIV;
mgottscho 0:8d34cc2ff388 163 break;
mgottscho 0:8d34cc2ff388 164 case G8:
mgottscho 0:8d34cc2ff388 165 __div = G8_DIV;
mgottscho 0:8d34cc2ff388 166 break;
mgottscho 0:8d34cc2ff388 167 }
mgottscho 0:8d34cc2ff388 168 }
mgottscho 0:8d34cc2ff388 169
mgottscho 0:8d34cc2ff388 170 void MMA8451Q::enableDataReadyInterrupt(bool enable, bool pinSelect) {
mgottscho 0:8d34cc2ff388 171 //Deactivate sensor
mgottscho 0:8d34cc2ff388 172 bool wasActive = __active;
mgottscho 0:8d34cc2ff388 173 if (wasActive)
mgottscho 0:8d34cc2ff388 174 setActive(false);
mgottscho 0:8d34cc2ff388 175
mgottscho 0:8d34cc2ff388 176 //Configure interrupt
mgottscho 0:8d34cc2ff388 177 uint8_t tmp;
mgottscho 0:8d34cc2ff388 178 if (pinSelect)
mgottscho 0:8d34cc2ff388 179 tmp = 0xFF;
mgottscho 0:8d34cc2ff388 180 else
mgottscho 0:8d34cc2ff388 181 tmp = 0x00;
mgottscho 0:8d34cc2ff388 182 uint8_t data = tmp & CTRL_REG5_INT_CFG_DRDY_MASK; //Clear all other interrupt configurations, because I said so
mgottscho 0:8d34cc2ff388 183 setRegister(CTRL_REG5, data);
mgottscho 0:8d34cc2ff388 184
mgottscho 0:8d34cc2ff388 185 //Enable interrupt
mgottscho 0:8d34cc2ff388 186 if (enable)
mgottscho 0:8d34cc2ff388 187 tmp = 0xFF;
mgottscho 0:8d34cc2ff388 188 else
mgottscho 0:8d34cc2ff388 189 tmp = 0x00;
mgottscho 0:8d34cc2ff388 190 data = tmp & CTRL_REG4_INT_EN_DRDY_MASK; //Clear all other interrupt configurations, because I said so
mgottscho 0:8d34cc2ff388 191 setRegister(CTRL_REG4, data);
mgottscho 0:8d34cc2ff388 192
mgottscho 0:8d34cc2ff388 193 //Clear IPOL bit (2nd LSB), such that active interrupt is LOW, and set PP_OD bit (LSB) such that it is in open drain mode
mgottscho 0:8d34cc2ff388 194 data = getRegister(CTRL_REG3);
mgottscho 0:8d34cc2ff388 195 data = (data & ~CTRL_REG3_IPOL_MASK); // | CTRL_REG3_PP_OD_MASK;
mgottscho 0:8d34cc2ff388 196 setRegister(CTRL_REG3, data);
mgottscho 0:8d34cc2ff388 197
mgottscho 0:8d34cc2ff388 198 //Re-activate sensor
mgottscho 0:8d34cc2ff388 199 if (wasActive)
mgottscho 0:8d34cc2ff388 200 setActive(true);
mgottscho 0:8d34cc2ff388 201 }
mgottscho 0:8d34cc2ff388 202
mgottscho 0:8d34cc2ff388 203 int16_t MMA8451Q::getX(bool sampleNow) {
mgottscho 0:8d34cc2ff388 204 __disable_irq();
mgottscho 0:8d34cc2ff388 205 if (sampleNow) {
mgottscho 0:8d34cc2ff388 206 uint8_t data_msb, data_lsb;
mgottscho 0:8d34cc2ff388 207
mgottscho 0:8d34cc2ff388 208 //Do bitwise ops on unsigned 8-bit parts
mgottscho 0:8d34cc2ff388 209 uint16_t x_tmp = 0;
mgottscho 0:8d34cc2ff388 210 data_msb = getRegister(OUT_X_MSB);
mgottscho 0:8d34cc2ff388 211 if (__14b_data_enabled) {
mgottscho 0:8d34cc2ff388 212 data_lsb = getRegister(OUT_X_LSB);
mgottscho 0:8d34cc2ff388 213 data_lsb &= 0xFC; //ensure 2 LSB are cleared!
mgottscho 0:8d34cc2ff388 214 } else
mgottscho 0:8d34cc2ff388 215 data_lsb = 0;
mgottscho 0:8d34cc2ff388 216 x_tmp = data_msb << 8;
mgottscho 0:8d34cc2ff388 217 x_tmp |= data_lsb;
mgottscho 0:8d34cc2ff388 218
mgottscho 0:8d34cc2ff388 219 //Now, treat the number as signed, then arithmetic right shift by 2
mgottscho 0:8d34cc2ff388 220 __x = x_tmp;
mgottscho 0:8d34cc2ff388 221 __x = __x >> 2;
mgottscho 0:8d34cc2ff388 222 }
mgottscho 0:8d34cc2ff388 223
mgottscho 0:8d34cc2ff388 224 __dataReady = false;
mgottscho 0:8d34cc2ff388 225 __enable_irq();
mgottscho 0:8d34cc2ff388 226
mgottscho 0:8d34cc2ff388 227 return __x;
mgottscho 0:8d34cc2ff388 228 }
mgottscho 0:8d34cc2ff388 229
mgottscho 0:8d34cc2ff388 230 int16_t MMA8451Q::getY(bool sampleNow) {
mgottscho 0:8d34cc2ff388 231 __disable_irq();
mgottscho 0:8d34cc2ff388 232 if (sampleNow) {
mgottscho 0:8d34cc2ff388 233 uint8_t data_msb, data_lsb;
mgottscho 0:8d34cc2ff388 234
mgottscho 0:8d34cc2ff388 235 //Do bitwise ops on unsigned 8-bit parts
mgottscho 0:8d34cc2ff388 236 uint16_t y_tmp = 0;
mgottscho 0:8d34cc2ff388 237 data_msb = getRegister(OUT_Y_MSB);
mgottscho 0:8d34cc2ff388 238 if (__14b_data_enabled) {
mgottscho 0:8d34cc2ff388 239 data_lsb = getRegister(OUT_Y_LSB);
mgottscho 0:8d34cc2ff388 240 data_lsb &= 0xFC; //ensure 2 LSB are cleared!
mgottscho 0:8d34cc2ff388 241 } else
mgottscho 0:8d34cc2ff388 242 data_lsb = 0;
mgottscho 0:8d34cc2ff388 243 y_tmp = data_msb << 8;
mgottscho 0:8d34cc2ff388 244 y_tmp |= data_lsb;
mgottscho 0:8d34cc2ff388 245
mgottscho 0:8d34cc2ff388 246 //Now, treat the number as signed, then arithmetic right shift by 2
mgottscho 0:8d34cc2ff388 247 __y = y_tmp;
mgottscho 0:8d34cc2ff388 248 __y = __y >> 2;
mgottscho 0:8d34cc2ff388 249 }
mgottscho 0:8d34cc2ff388 250
mgottscho 0:8d34cc2ff388 251 __dataReady = false;
mgottscho 0:8d34cc2ff388 252 __enable_irq();
mgottscho 0:8d34cc2ff388 253
mgottscho 0:8d34cc2ff388 254 return __y;
mgottscho 0:8d34cc2ff388 255 }
mgottscho 0:8d34cc2ff388 256
mgottscho 0:8d34cc2ff388 257 int16_t MMA8451Q::getZ(bool sampleNow) {
mgottscho 0:8d34cc2ff388 258 __disable_irq();
mgottscho 0:8d34cc2ff388 259 if (sampleNow) {
mgottscho 0:8d34cc2ff388 260 uint8_t data_msb, data_lsb;
mgottscho 0:8d34cc2ff388 261
mgottscho 0:8d34cc2ff388 262 //Do bitwise ops on unsigned 8-bit parts
mgottscho 0:8d34cc2ff388 263 uint16_t z_tmp = 0;
mgottscho 0:8d34cc2ff388 264 data_msb = getRegister(OUT_Z_MSB);
mgottscho 0:8d34cc2ff388 265 if (__14b_data_enabled) {
mgottscho 0:8d34cc2ff388 266 data_lsb = getRegister(OUT_Z_LSB);
mgottscho 0:8d34cc2ff388 267 data_lsb &= 0xFC; //ensure 2 LSB are cleared!
mgottscho 0:8d34cc2ff388 268 } else
mgottscho 0:8d34cc2ff388 269 data_lsb = 0;
mgottscho 0:8d34cc2ff388 270 z_tmp = data_msb << 8;
mgottscho 0:8d34cc2ff388 271 z_tmp |= data_lsb;
mgottscho 0:8d34cc2ff388 272
mgottscho 0:8d34cc2ff388 273 //Now, treat the number as signed, then arithmetic right shift by 2
mgottscho 0:8d34cc2ff388 274 __z = z_tmp;
mgottscho 0:8d34cc2ff388 275 __z = __z >> 2;
mgottscho 0:8d34cc2ff388 276 }
mgottscho 0:8d34cc2ff388 277
mgottscho 0:8d34cc2ff388 278 __dataReady = false;
mgottscho 0:8d34cc2ff388 279 __enable_irq();
mgottscho 0:8d34cc2ff388 280
mgottscho 0:8d34cc2ff388 281 return __z;
mgottscho 0:8d34cc2ff388 282 }
mgottscho 0:8d34cc2ff388 283
mgottscho 0:8d34cc2ff388 284 float MMA8451Q::getFloatX(bool sampleNow) {
mgottscho 0:8d34cc2ff388 285 return getX(sampleNow) * __div;
mgottscho 0:8d34cc2ff388 286 }
mgottscho 0:8d34cc2ff388 287
mgottscho 0:8d34cc2ff388 288 float MMA8451Q::getFloatY(bool sampleNow) {
mgottscho 0:8d34cc2ff388 289 return getY(sampleNow) * __div;
mgottscho 0:8d34cc2ff388 290 }
mgottscho 0:8d34cc2ff388 291
mgottscho 0:8d34cc2ff388 292 float MMA8451Q::getFloatZ(bool sampleNow) {
mgottscho 0:8d34cc2ff388 293 return getZ(sampleNow) * __div;
mgottscho 0:8d34cc2ff388 294 }
mgottscho 0:8d34cc2ff388 295
mgottscho 0:8d34cc2ff388 296 void MMA8451Q::sleep() {
mgottscho 0:8d34cc2ff388 297
mgottscho 0:8d34cc2ff388 298 }
mgottscho 0:8d34cc2ff388 299
mgottscho 0:8d34cc2ff388 300 void MMA8451Q::wake() {
mgottscho 0:8d34cc2ff388 301
mgottscho 0:8d34cc2ff388 302 }
mgottscho 0:8d34cc2ff388 303
mgottscho 0:8d34cc2ff388 304 void MMA8451Q::__sample_data_ISR() {
mgottscho 0:8d34cc2ff388 305 getX(true);
mgottscho 0:8d34cc2ff388 306 getY(true);
mgottscho 0:8d34cc2ff388 307 getZ(true);
mgottscho 0:8d34cc2ff388 308 __dataReady = true;
mgottscho 0:8d34cc2ff388 309 }