A compilation of some hardware sensors and their shared programming interfaces.
Embed:
(wiki syntax)
Show/hide line numbers
MMA8451Q.cpp
00001 /* MMA8451Q.cpp 00002 * Tested with mbed board: FRDM-KL46Z 00003 * Author: Mark Gottscho 00004 * mgottscho@ucla.edu 00005 */ 00006 00007 #include "mbed.h" 00008 #include "I2CSensor.h" 00009 #include "PeriodicSensor.h" 00010 #include "SleepableSensor.h" 00011 #include "MMA8451Q.h" 00012 00013 using namespace std; 00014 00015 //////////////////// PUBLIC METHODS //////////////////// 00016 00017 MMA8451Q::MMA8451Q (PinName sda, PinName scl, int i2c_addr) : 00018 I2CSensor(sda, scl, i2c_addr), //parent constructor 00019 PeriodicSensor(0.05), //default max sampling rate of 20Hz 00020 SleepableSensor(), 00021 __x(0), 00022 __y(0), 00023 __z(0), 00024 __active(false), 00025 __14b_data_enabled(true), 00026 __output_data_rate(MMA8451Q::smpl_rate_t(0)), 00027 __scale(MMA8451Q::scale_t(0)), 00028 __div(G2_DIV) 00029 { } 00030 00031 MMA8451Q::~MMA8451Q() {} 00032 00033 void MMA8451Q::selfInit() { 00034 __i2c.frequency(400000); 00035 reset(); 00036 setOutputDataRate (HZ800); 00037 setScale (G2); 00038 set14bData (true); 00039 //enableDataReadyInterrupt(true, true); //INT1 00040 } 00041 00042 void MMA8451Q::reset() { 00043 uint8_t data = CTRL_REG2_RST_MASK; 00044 setRegister(CTRL_REG2, data); 00045 wait(0.1); 00046 } 00047 00048 uint8_t MMA8451Q::whoAmI() { 00049 return getRegister(WHO_AM_I); 00050 } 00051 00052 bool MMA8451Q::isActive () { 00053 return __active; 00054 } 00055 00056 void MMA8451Q::setActive (bool activate) { 00057 uint8_t data; 00058 data = getRegister(CTRL_REG1); 00059 if (activate) 00060 data |= CTRL_REG1_ACTIVE_MASK; //Set bit 00061 else 00062 data &= ~CTRL_REG1_ACTIVE_MASK; //Clear bit 00063 setRegister(CTRL_REG1, data); 00064 __active = activate; 00065 } 00066 00067 uint8_t MMA8451Q::getSystemMode () { 00068 return getRegister(SYSMOD); 00069 } 00070 00071 bool MMA8451Q::is14bDataEnabled () { 00072 return __14b_data_enabled; 00073 } 00074 00075 void MMA8451Q::set14bData (bool enable) { 00076 bool wasActive = isActive (); 00077 if (wasActive) 00078 setActive (false); //deactivate before updating control bits 00079 00080 uint8_t data; 00081 data = getRegister(CTRL_REG1); 00082 data = (data & ~CTRL_REG1_F_READ_MASK) | (CTRL_REG1_F_READ_MASK & enable); //Set 2nd LSB to enable 00083 setRegister(CTRL_REG1, data); 00084 __14b_data_enabled = enable; 00085 00086 if (wasActive) 00087 setActive (true); //restore activity 00088 } 00089 00090 MMA8451Q::smpl_rate_t MMA8451Q::getOutputDataRate () { 00091 return __output_data_rate; 00092 } 00093 00094 void MMA8451Q::setOutputDataRate (MMA8451Q::smpl_rate_t rate) { 00095 bool wasActive = __active; 00096 if (wasActive) 00097 setActive (false); //must disable to update register 00098 00099 uint8_t data, dr; 00100 data = getRegister(CTRL_REG1); 00101 switch (rate) { 00102 case HZ800: 00103 dr = 0; 00104 break; 00105 case HZ400: 00106 dr = 1; 00107 break; 00108 case HZ200: 00109 dr = 2; 00110 break; 00111 case HZ100: 00112 dr = 3; 00113 break; 00114 case HZ50: 00115 dr = 4; 00116 break; 00117 case HZ12_5: 00118 dr = 5; 00119 break; 00120 case HZ6_25: 00121 dr = 6; 00122 break; 00123 case HZ1_56: 00124 dr = 7; 00125 break; 00126 default: 00127 dr = 0; //800HZ 00128 break; 00129 } 00130 data = (data & ~CTRL_REG1_DR_MASK) | (dr << 3); 00131 setRegister(CTRL_REG1, data); 00132 00133 if (wasActive) 00134 setActive (true); //Restore active state 00135 00136 __output_data_rate = rate; 00137 } 00138 00139 MMA8451Q::scale_t MMA8451Q::getScale () { 00140 return __scale; 00141 } 00142 00143 void MMA8451Q::setScale (MMA8451Q::scale_t scale) { 00144 bool wasActive = __active; 00145 if (wasActive) 00146 setActive (false); //deactivate before updating control bits 00147 00148 uint8_t data = getRegister(XYZ_DATA_CFG); 00149 data = (data & ~XYZ_DATA_CFG_FS_MASK) | scale; 00150 setRegister(XYZ_DATA_CFG, data); 00151 00152 if (wasActive) 00153 setActive (true); //restore activity 00154 00155 __scale = scale; 00156 switch (scale) { 00157 default: 00158 case G2: 00159 __div = G2_DIV; 00160 break; 00161 case G4: 00162 __div = G4_DIV; 00163 break; 00164 case G8: 00165 __div = G8_DIV; 00166 break; 00167 } 00168 } 00169 00170 void MMA8451Q::enableDataReadyInterrupt(bool enable, bool pinSelect) { 00171 //Deactivate sensor 00172 bool wasActive = __active; 00173 if (wasActive) 00174 setActive (false); 00175 00176 //Configure interrupt 00177 uint8_t tmp; 00178 if (pinSelect) 00179 tmp = 0xFF; 00180 else 00181 tmp = 0x00; 00182 uint8_t data = tmp & CTRL_REG5_INT_CFG_DRDY_MASK; //Clear all other interrupt configurations, because I said so 00183 setRegister(CTRL_REG5, data); 00184 00185 //Enable interrupt 00186 if (enable) 00187 tmp = 0xFF; 00188 else 00189 tmp = 0x00; 00190 data = tmp & CTRL_REG4_INT_EN_DRDY_MASK; //Clear all other interrupt configurations, because I said so 00191 setRegister(CTRL_REG4, data); 00192 00193 //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 00194 data = getRegister(CTRL_REG3); 00195 data = (data & ~CTRL_REG3_IPOL_MASK); // | CTRL_REG3_PP_OD_MASK; 00196 setRegister(CTRL_REG3, data); 00197 00198 //Re-activate sensor 00199 if (wasActive) 00200 setActive (true); 00201 } 00202 00203 int16_t MMA8451Q::getX (bool sampleNow) { 00204 __disable_irq(); 00205 if (sampleNow) { 00206 uint8_t data_msb, data_lsb; 00207 00208 //Do bitwise ops on unsigned 8-bit parts 00209 uint16_t x_tmp = 0; 00210 data_msb = getRegister(OUT_X_MSB); 00211 if (__14b_data_enabled) { 00212 data_lsb = getRegister(OUT_X_LSB); 00213 data_lsb &= 0xFC; //ensure 2 LSB are cleared! 00214 } else 00215 data_lsb = 0; 00216 x_tmp = data_msb << 8; 00217 x_tmp |= data_lsb; 00218 00219 //Now, treat the number as signed, then arithmetic right shift by 2 00220 __x = x_tmp; 00221 __x = __x >> 2; 00222 } 00223 00224 __dataReady = false; 00225 __enable_irq(); 00226 00227 return __x; 00228 } 00229 00230 int16_t MMA8451Q::getY (bool sampleNow) { 00231 __disable_irq(); 00232 if (sampleNow) { 00233 uint8_t data_msb, data_lsb; 00234 00235 //Do bitwise ops on unsigned 8-bit parts 00236 uint16_t y_tmp = 0; 00237 data_msb = getRegister(OUT_Y_MSB); 00238 if (__14b_data_enabled) { 00239 data_lsb = getRegister(OUT_Y_LSB); 00240 data_lsb &= 0xFC; //ensure 2 LSB are cleared! 00241 } else 00242 data_lsb = 0; 00243 y_tmp = data_msb << 8; 00244 y_tmp |= data_lsb; 00245 00246 //Now, treat the number as signed, then arithmetic right shift by 2 00247 __y = y_tmp; 00248 __y = __y >> 2; 00249 } 00250 00251 __dataReady = false; 00252 __enable_irq(); 00253 00254 return __y; 00255 } 00256 00257 int16_t MMA8451Q::getZ (bool sampleNow) { 00258 __disable_irq(); 00259 if (sampleNow) { 00260 uint8_t data_msb, data_lsb; 00261 00262 //Do bitwise ops on unsigned 8-bit parts 00263 uint16_t z_tmp = 0; 00264 data_msb = getRegister(OUT_Z_MSB); 00265 if (__14b_data_enabled) { 00266 data_lsb = getRegister(OUT_Z_LSB); 00267 data_lsb &= 0xFC; //ensure 2 LSB are cleared! 00268 } else 00269 data_lsb = 0; 00270 z_tmp = data_msb << 8; 00271 z_tmp |= data_lsb; 00272 00273 //Now, treat the number as signed, then arithmetic right shift by 2 00274 __z = z_tmp; 00275 __z = __z >> 2; 00276 } 00277 00278 __dataReady = false; 00279 __enable_irq(); 00280 00281 return __z; 00282 } 00283 00284 float MMA8451Q::getFloatX (bool sampleNow) { 00285 return getX (sampleNow) * __div; 00286 } 00287 00288 float MMA8451Q::getFloatY (bool sampleNow) { 00289 return getY (sampleNow) * __div; 00290 } 00291 00292 float MMA8451Q::getFloatZ (bool sampleNow) { 00293 return getZ (sampleNow) * __div; 00294 } 00295 00296 void MMA8451Q::sleep() { 00297 00298 } 00299 00300 void MMA8451Q::wake() { 00301 00302 } 00303 00304 void MMA8451Q::__sample_data_ISR() { 00305 getX (true); 00306 getY (true); 00307 getZ (true); 00308 __dataReady = true; 00309 }
Generated on Wed Jul 13 2022 19:24:41 by 1.7.2