A compilation of some hardware sensors and their shared programming interfaces.
Embed:
(wiki syntax)
Show/hide line numbers
MAG3110.cpp
00001 /* MAG3110.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 "MAG3110.h" 00011 00012 using namespace std; 00013 00014 MAG3110::MAG3110 (PinName sda, PinName scl, int i2c_addr) : 00015 I2CSensor(sda, scl, i2c_addr), 00016 PeriodicSensor(0.05), //default max sampling rate of 20Hz 00017 __x(0), 00018 __y(0), 00019 __z(0), 00020 __active(false), 00021 __adc_rate(adc_smpl_rate_t(0)), 00022 __ratio(oversmpl_ratio_t(0)), 00023 __rate(smpl_rate_t(0)) 00024 { 00025 } 00026 00027 MAG3110::~MAG3110() {} 00028 00029 void MAG3110::selfInit() { 00030 __i2c.frequency(400000); 00031 setOutputSamplingParameters (HZ80, O16, NULL); 00032 00033 //Enable auto magnetic sensor reset before each sample, as recommended in the datasheet 00034 uint8_t data = getRegister(CTRL_REG2); 00035 data |= CTRL_REG2_AUTO_MRST_EN_MASK; //Set the AUTO_MRST_EN bit 00036 setRegister(CTRL_REG2, data); 00037 } 00038 00039 uint8_t MAG3110::whoAmI() { 00040 return getRegister(WHO_AM_I); 00041 } 00042 00043 uint8_t MAG3110::getDataRegisterStatus () { 00044 return getRegister(DR_STATUS); 00045 } 00046 00047 uint8_t MAG3110::getSystemMode () { 00048 return getRegister(SYSMOD); 00049 } 00050 00051 bool MAG3110::isActive () { 00052 return (bool) (getRegister(CTRL_REG1) & 0x01); 00053 } 00054 00055 void MAG3110::setActive (bool activate) { 00056 uint8_t data; 00057 data = getRegister(CTRL_REG1); 00058 if (activate) 00059 data |= CTRL_REG1_AC_MASK; //Set bit 00060 else 00061 data &= ~CTRL_REG1_AC_MASK; //Clear bit 00062 setRegister(CTRL_REG1, data); 00063 __active = activate; 00064 } 00065 00066 00067 void MAG3110::getOutputSamplingParameters (smpl_rate_t *rate, oversmpl_ratio_t *ratio, adc_smpl_rate_t *adc_rate) { 00068 if (rate != NULL) 00069 *rate = __rate; 00070 if (ratio != NULL) 00071 *ratio = __ratio; 00072 if (ratio != NULL) 00073 *adc_rate = __adc_rate; 00074 } 00075 00076 00077 bool MAG3110::setOutputSamplingParameters (smpl_rate_t rate, oversmpl_ratio_t ratio, adc_smpl_rate_t *adc_rate) { 00078 uint8_t dr; 00079 uint8_t os; 00080 adc_smpl_rate_t tmp_adc_rate; 00081 00082 switch (rate) { 00083 default: 00084 case HZ80: 00085 switch (ratio) { 00086 case O16: 00087 tmp_adc_rate = AHZ1280; 00088 dr = 0; 00089 os = 0; 00090 break; 00091 //Other rate-ratio combinations are illegal 00092 default: 00093 return false; 00094 } 00095 break; 00096 00097 case HZ40: 00098 switch (ratio) { 00099 case O16: 00100 tmp_adc_rate = AHZ640; 00101 dr = 1; 00102 os = 0; 00103 break; 00104 case O32: 00105 tmp_adc_rate = AHZ1280; 00106 dr = 0; 00107 os = 1; 00108 break; 00109 //Other rate-ratio combinations are illegal 00110 default: 00111 return false; 00112 } 00113 break; 00114 00115 case HZ20: 00116 switch (ratio) { 00117 case O16: 00118 tmp_adc_rate = AHZ320; 00119 dr = 2; 00120 os = 0; 00121 break; 00122 case O32: 00123 tmp_adc_rate = AHZ640; 00124 dr = 1; 00125 os = 1; 00126 break; 00127 case O64: 00128 tmp_adc_rate = AHZ1280; 00129 dr = 0; 00130 os = 2; 00131 break; 00132 //Other rate-ratio combinations are illegal 00133 default: 00134 return false; 00135 } 00136 break; 00137 00138 case HZ10: 00139 switch (ratio) { 00140 case O16: 00141 tmp_adc_rate = AHZ160; 00142 dr = 3; 00143 os = 0; 00144 break; 00145 case O32: 00146 tmp_adc_rate = AHZ320; 00147 dr = 2; 00148 os = 1; 00149 break; 00150 case O64: 00151 tmp_adc_rate = AHZ640; 00152 dr = 1; 00153 os = 2; 00154 break; 00155 case O128: 00156 tmp_adc_rate = AHZ1280; 00157 dr = 0; 00158 os = 3; 00159 break; 00160 //This should be impossible 00161 default: 00162 return false; 00163 } 00164 break; 00165 00166 case HZ5: 00167 switch (ratio) { 00168 case O16: 00169 tmp_adc_rate = AHZ80; 00170 dr = 4; 00171 os = 0; 00172 break; 00173 case O32: 00174 tmp_adc_rate = AHZ160; 00175 dr = 3; 00176 os = 1; 00177 break; 00178 case O64: 00179 tmp_adc_rate = AHZ320; 00180 dr = 2; 00181 os = 2; 00182 break; 00183 case O128: 00184 tmp_adc_rate = AHZ640; 00185 dr = 1; 00186 os = 3; 00187 break; 00188 //This should be impossible 00189 default: 00190 return false; 00191 } 00192 break; 00193 00194 case HZ2_5: 00195 switch (ratio) { 00196 case O16: 00197 tmp_adc_rate = AHZ80; 00198 dr = 5; 00199 os = 0; 00200 break; 00201 case O32: 00202 tmp_adc_rate = AHZ80; 00203 dr = 4; 00204 os = 1; 00205 break; 00206 case O64: 00207 tmp_adc_rate = AHZ160; 00208 dr = 3; 00209 os = 2; 00210 break; 00211 case O128: 00212 tmp_adc_rate = AHZ320; 00213 dr = 2; 00214 os = 3; 00215 break; 00216 //This should be impossible 00217 default: 00218 return false; 00219 } 00220 break; 00221 00222 case HZ1_25: 00223 switch (ratio) { 00224 case O16: 00225 tmp_adc_rate = AHZ80; 00226 dr = 6; 00227 os = 0; 00228 break; 00229 case O32: 00230 tmp_adc_rate = AHZ80; 00231 dr = 5; 00232 os = 1; 00233 break; 00234 case O64: 00235 tmp_adc_rate = AHZ80; 00236 dr = 4; 00237 os = 2; 00238 break; 00239 case O128: 00240 tmp_adc_rate = AHZ160; 00241 dr = 3; 00242 os = 3; 00243 break; 00244 //This should be impossible 00245 default: 00246 return false; 00247 } 00248 break; 00249 00250 case HZ0_63: 00251 switch (ratio) { 00252 case O16: 00253 tmp_adc_rate = AHZ80; 00254 dr = 7; 00255 os = 0; 00256 break; 00257 case O32: 00258 tmp_adc_rate = AHZ80; 00259 dr = 6; 00260 os = 1; 00261 break; 00262 case O64: 00263 tmp_adc_rate = AHZ80; 00264 dr = 5; 00265 os = 2; 00266 break; 00267 case O128: 00268 tmp_adc_rate = AHZ80; 00269 dr = 4; 00270 os = 3; 00271 break; 00272 //This should be impossible 00273 default: 00274 return false; 00275 } 00276 break; 00277 00278 case HZ0_31: 00279 switch (ratio) { 00280 case O32: 00281 tmp_adc_rate = AHZ80; 00282 dr = 7; 00283 os = 1; 00284 break; 00285 case O64: 00286 tmp_adc_rate = AHZ80; 00287 dr = 6; 00288 os = 2; 00289 break; 00290 case O128: 00291 tmp_adc_rate = AHZ80; 00292 dr = 5; 00293 os = 3; 00294 break; 00295 default: 00296 return false; 00297 } 00298 break; 00299 00300 case HZ0_16: 00301 switch (ratio) { 00302 case O64: 00303 tmp_adc_rate = AHZ80; 00304 dr = 7; 00305 os = 2; 00306 break; 00307 case O128: 00308 tmp_adc_rate = AHZ80; 00309 dr = 6; 00310 os = 3; 00311 break; 00312 default: 00313 return false; 00314 } 00315 break; 00316 00317 case HZ0_08: 00318 switch (ratio) { 00319 case O128: 00320 tmp_adc_rate = AHZ80; 00321 dr = 7; 00322 os = 3; 00323 break; 00324 default: 00325 return false; 00326 } 00327 break; 00328 } 00329 00330 //Deactivate to update register 00331 bool wasActive = __active; 00332 setActive (false); 00333 00334 //Update value for the caller 00335 if (adc_rate != NULL) 00336 *adc_rate = tmp_adc_rate; 00337 00338 //Update CTRL_REG1 DR and OS fields 00339 uint8_t data = getRegister(CTRL_REG1); 00340 uint8_t dr_os = (dr << 5) | (os << 3); //Set DR in 3 MSB, OS in next 2 bits. 3 LSB are 0 00341 data = (data & ~(CTRL_REG1_DR_MASK | CTRL_REG1_OS_MASK)) | ((CTRL_REG1_DR_MASK | CTRL_REG1_OS_MASK) & dr_os); //Update 5 MSB 00342 setRegister(CTRL_REG1, data); 00343 00344 //Update cached values 00345 __adc_rate = tmp_adc_rate; 00346 __ratio = ratio; 00347 __rate = rate; 00348 00349 if (wasActive) 00350 setActive (true); 00351 00352 return true; 00353 } 00354 00355 00356 00357 int16_t MAG3110::getX (bool sampleNow) { 00358 __disable_irq(); 00359 if (sampleNow) { 00360 uint8_t data_msb, data_lsb; 00361 data_msb = getRegister(OUT_X_MSB); 00362 data_lsb = getRegister(OUT_X_LSB); 00363 __x = data_msb << 8; 00364 __x |= data_lsb; 00365 } 00366 00367 __dataReady = false; 00368 __enable_irq(); 00369 00370 return __x; 00371 } 00372 00373 int16_t MAG3110::getY (bool sampleNow) { 00374 __disable_irq(); 00375 if (sampleNow) { 00376 uint8_t data_msb, data_lsb; 00377 data_msb = getRegister(OUT_Y_MSB); 00378 data_lsb = getRegister(OUT_Y_LSB); 00379 __y = data_msb << 8; 00380 __y |= data_lsb; 00381 } 00382 00383 __dataReady = false; 00384 __enable_irq(); 00385 00386 return __y; 00387 } 00388 00389 int16_t MAG3110::getZ (bool sampleNow) { 00390 __disable_irq(); 00391 if (sampleNow) { 00392 uint8_t data_msb, data_lsb; 00393 data_msb = getRegister(OUT_Z_MSB); 00394 data_lsb = getRegister(OUT_Z_LSB); 00395 __z = data_msb << 8; 00396 __z |= data_lsb; 00397 } 00398 00399 __dataReady = false; 00400 __enable_irq(); 00401 00402 return __z; 00403 } 00404 00405 float MAG3110::getFloatX (bool sampleNow) { 00406 return getX (sampleNow) * DATA_CONVERSION; 00407 } 00408 00409 float MAG3110::getFloatY (bool sampleNow) { 00410 return getY (sampleNow) * DATA_CONVERSION; 00411 } 00412 00413 float MAG3110::getFloatZ (bool sampleNow) { 00414 return getZ (sampleNow) * DATA_CONVERSION; 00415 } 00416 00417 int8_t MAG3110::getDieTemp() { 00418 return (int8_t) getRegister(DIE_TEMP); 00419 } 00420 00421 float MAG3110::getFloatDieTemp () { 00422 return getDieTemp() * TEMP_DIV; 00423 } 00424 00425 void MAG3110::__sample_data_ISR() { 00426 getX (true); 00427 getY (true); 00428 getZ (true); 00429 __dataReady = true; 00430 }
Generated on Wed Jul 13 2022 19:24:41 by 1.7.2