Christian Dupaty 03/2021 Library and demo for BMM150 see datasheet here : https://www.bosch-sensortec.com/products/motion-sensors/magnetometers-bmm150/ Adaptation of BOSCH driver https://github.com/BoschSensortec/BMM150-Sensor-API for ARM MBED and tested on NUCLEO-L073RZ and GEOMAGNETIC CLICK https://www.mikroe.com/geomagnetic-click

Dependents:   BMM150_HelloWorld2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bmm150.cpp Source File

bmm150.cpp

00001 /*
00002 Christian Dupaty 03/2021
00003 Library and demo for BMM150 see datasheet here : https://www.bosch-sensortec.com/products/motion-sensors/magnetometers-bmm150/
00004 Adaptation of BOSCH driver https://github.com/BoschSensortec/BMM150-Sensor-API
00005 for ARM MBED and tested on NUCLEO-L073RZ and GEOMAGNETIC CLICK
00006 https://www.mikroe.com/geomagnetic-click 
00007 */
00008 
00009 #include "mbed.h"
00010 #include "bmm150.h"
00011 
00012 BMM150::BMM150(PinName sda, PinName scl)
00013 {
00014     //I2C *i2c;
00015     i2c = new I2C(sda, scl);
00016     //100KHz, as specified by the datasheet.
00017     i2c ->frequency(100000);        
00018 }       
00019 
00020 int8_t BMM150::initialize(void) 
00021 {
00022   //  i2c.begin();
00023 
00024     /* Power up the sensor from suspend to sleep mode */
00025     set_op_mode(BMM150_SLEEP_MODE);
00026     wait_ms(BMM150_START_UP_TIME);
00027 
00028     /* Check chip ID */
00029     uint8_t id = i2c_read(BMM150_CHIP_ID_ADDR);
00030     if (id != BMM150_CHIP_ID) {
00031         return BMM150_E_ID_NOT_CONFORM;
00032     }
00033 
00034     /* Function to update trim values */
00035     read_trim_registers();
00036 
00037     /* Setting the power mode as normal */
00038     set_op_mode(BMM150_NORMAL_MODE);
00039 
00040     /*  Setting the preset mode as Low power mode
00041         i.e. data rate = 10Hz XY-rep = 1 Z-rep = 2*/
00042     set_presetmode(BMM150_PRESETMODE_LOWPOWER);
00043     // set_presetmode(BMM150_HIGHACCURACY_REPZ);
00044 
00045     return BMM150_OK;
00046 }
00047 
00048 void BMM150::read_mag_data() {
00049     int16_t msb_data;
00050     int8_t reg_data[BMM150_XYZR_DATA_LEN] = {0};
00051 
00052     i2c_read(BMM150_DATA_X_LSB, reg_data, BMM150_XYZR_DATA_LEN);
00053 
00054     /* Mag X axis data */
00055     reg_data[0] = BMM150_GET_BITS(reg_data[0], BMM150_DATA_X);
00056     /* Shift the MSB data to left by 5 bits */
00057     /* Multiply by 32 to get the shift left by 5 value */
00058     msb_data = ((int16_t)((char)reg_data[1])) * 32;
00059     /* Raw mag X axis data */
00060     raw_mag_data.raw_datax = (int16_t)(msb_data | reg_data[0]);
00061     /* Mag Y axis data */
00062     reg_data[2] = BMM150_GET_BITS(reg_data[2], BMM150_DATA_Y);
00063     /* Shift the MSB data to left by 5 bits */
00064     /* Multiply by 32 to get the shift left by 5 value */
00065     msb_data = ((int16_t)((char)reg_data[3])) * 32;
00066     /* Raw mag Y axis data */
00067     raw_mag_data.raw_datay = (int16_t)(msb_data | reg_data[2]);
00068     /* Mag Z axis data */
00069     reg_data[4] = BMM150_GET_BITS(reg_data[4], BMM150_DATA_Z);
00070     /* Shift the MSB data to left by 7 bits */
00071     /* Multiply by 128 to get the shift left by 7 value */
00072     msb_data = ((int16_t)((char)reg_data[5])) * 128;
00073     /* Raw mag Z axis data */
00074     raw_mag_data.raw_dataz = (int16_t)(msb_data | reg_data[4]);
00075     /* Mag R-HALL data */
00076     reg_data[6] = BMM150_GET_BITS(reg_data[6], BMM150_DATA_RHALL);
00077     raw_mag_data.raw_data_r = (uint16_t)(((uint16_t)reg_data[7] << 6) | reg_data[6]);
00078 
00079     /* Compensated Mag X data in int16_t format */
00080     mag_data.x = compensate_x(raw_mag_data.raw_datax, raw_mag_data.raw_data_r);
00081     /* Compensated Mag Y data in int16_t format */
00082     mag_data.y = compensate_y(raw_mag_data.raw_datay, raw_mag_data.raw_data_r);
00083     /* Compensated Mag Z data in int16_t format */
00084     mag_data.z = compensate_z(raw_mag_data.raw_dataz, raw_mag_data.raw_data_r);
00085 }
00086 
00087 /*
00088     @brief This internal API is used to obtain the compensated
00089     magnetometer X axis data(micro-tesla) in int16_t.
00090 */
00091 int16_t BMM150::compensate_x(int16_t mag_data_x, uint16_t data_rhall) 
00092 {
00093     int16_t retval;
00094     uint16_t process_comp_x0 = 0;
00095     int32_t process_comp_x1;
00096     uint16_t process_comp_x2;
00097     int32_t process_comp_x3;
00098     int32_t process_comp_x4;
00099     int32_t process_comp_x5;
00100     int32_t process_comp_x6;
00101     int32_t process_comp_x7;
00102     int32_t process_comp_x8;
00103     int32_t process_comp_x9;
00104     int32_t process_comp_x10;
00105 
00106     /* Overflow condition check */
00107     if (mag_data_x != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
00108         if (data_rhall != 0) {
00109             /* Availability of valid data*/
00110             process_comp_x0 = data_rhall;
00111         } else if (trim_data.dig_xyz1  != 0) {
00112             process_comp_x0 = trim_data.dig_xyz1 ;
00113         } else {
00114             process_comp_x0 = 0;
00115         }
00116         if (process_comp_x0 != 0) {
00117             /* Processing compensation equations*/
00118             process_comp_x1 = ((int32_t)trim_data.dig_xyz1 ) * 16384;
00119             process_comp_x2 = ((uint16_t)(process_comp_x1 / process_comp_x0)) - ((uint16_t)0x4000);
00120             retval = ((int16_t)process_comp_x2);
00121             process_comp_x3 = (((int32_t)retval) * ((int32_t)retval));
00122             process_comp_x4 = (((int32_t)trim_data.dig_xy2 ) * (process_comp_x3 / 128));
00123             process_comp_x5 = (int32_t)(((int16_t)trim_data.dig_xy1 ) * 128);
00124             process_comp_x6 = ((int32_t)retval) * process_comp_x5;
00125             process_comp_x7 = (((process_comp_x4 + process_comp_x6) / 512) + ((int32_t)0x100000));
00126             process_comp_x8 = ((int32_t)(((int16_t)trim_data.dig_x2 ) + ((int16_t)0xA0)));
00127             process_comp_x9 = ((process_comp_x7 * process_comp_x8) / 4096);
00128             process_comp_x10 = ((int32_t)mag_data_x) * process_comp_x9;
00129             retval = ((int16_t)(process_comp_x10 / 8192));
00130             retval = (retval + (((int16_t)trim_data.dig_x1 ) * 8)) / 16;
00131         } else {
00132             retval = BMM150_OVERFLOW_OUTPUT;
00133         }
00134     } else {
00135         /* Overflow condition */
00136         retval = BMM150_OVERFLOW_OUTPUT;
00137     }
00138 
00139     return retval;
00140 }
00141 
00142 /*
00143     @brief This internal API is used to obtain the compensated
00144     magnetometer Y axis data(micro-tesla) in int16_t.
00145 */
00146 int16_t BMM150::compensate_y(int16_t mag_data_y, uint16_t data_rhall) {
00147     int16_t retval;
00148     uint16_t process_comp_y0 = 0;
00149     int32_t process_comp_y1;
00150     uint16_t process_comp_y2;
00151     int32_t process_comp_y3;
00152     int32_t process_comp_y4;
00153     int32_t process_comp_y5;
00154     int32_t process_comp_y6;
00155     int32_t process_comp_y7;
00156     int32_t process_comp_y8;
00157     int32_t process_comp_y9;
00158 
00159     /* Overflow condition check */
00160     if (mag_data_y != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
00161         if (data_rhall != 0) {
00162             /* Availability of valid data*/
00163             process_comp_y0 = data_rhall;
00164         } else if (trim_data.dig_xyz1  != 0) {
00165             process_comp_y0 = trim_data.dig_xyz1 ;
00166         } else {
00167             process_comp_y0 = 0;
00168         }
00169         if (process_comp_y0 != 0) {
00170             /*Processing compensation equations*/
00171             process_comp_y1 = (((int32_t)trim_data.dig_xyz1 ) * 16384) / process_comp_y0;
00172             process_comp_y2 = ((uint16_t)process_comp_y1) - ((uint16_t)0x4000);
00173             retval = ((int16_t)process_comp_y2);
00174             process_comp_y3 = ((int32_t) retval) * ((int32_t)retval);
00175             process_comp_y4 = ((int32_t)trim_data.dig_xy2 ) * (process_comp_y3 / 128);
00176             process_comp_y5 = ((int32_t)(((int16_t)trim_data.dig_xy1 ) * 128));
00177             process_comp_y6 = ((process_comp_y4 + (((int32_t)retval) * process_comp_y5)) / 512);
00178             process_comp_y7 = ((int32_t)(((int16_t)trim_data.dig_y2 ) + ((int16_t)0xA0)));
00179             process_comp_y8 = (((process_comp_y6 + ((int32_t)0x100000)) * process_comp_y7) / 4096);
00180             process_comp_y9 = (((int32_t)mag_data_y) * process_comp_y8);
00181             retval = (int16_t)(process_comp_y9 / 8192);
00182             retval = (retval + (((int16_t)trim_data.dig_y1 ) * 8)) / 16;
00183         } else {
00184             retval = BMM150_OVERFLOW_OUTPUT;
00185         }
00186     } else {
00187         /* Overflow condition*/
00188         retval = BMM150_OVERFLOW_OUTPUT;
00189     }
00190 
00191     return retval;
00192 }
00193 
00194 /*
00195     @brief This internal API is used to obtain the compensated
00196     magnetometer Z axis data(micro-tesla) in int16_t.
00197 */
00198 int16_t BMM150::compensate_z(int16_t mag_data_z, uint16_t data_rhall) {
00199     int32_t retval;
00200     int16_t process_comp_z0;
00201     int32_t process_comp_z1;
00202     int32_t process_comp_z2;
00203     int32_t process_comp_z3;
00204     int16_t process_comp_z4;
00205 
00206     if (mag_data_z != BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL) {
00207         if ((trim_data.dig_z2  != 0) && (trim_data.dig_z1  != 0)
00208                 && (data_rhall != 0) && (trim_data.dig_xyz1  != 0)) {
00209             /*Processing compensation equations*/
00210             process_comp_z0 = ((int16_t)data_rhall) - ((int16_t) trim_data.dig_xyz1 );
00211             process_comp_z1 = (((int32_t)trim_data.dig_z3 ) * ((int32_t)(process_comp_z0))) / 4;
00212             process_comp_z2 = (((int32_t)(mag_data_z - trim_data.dig_z4 )) * 32768);
00213             process_comp_z3 = ((int32_t)trim_data.dig_z1 ) * (((int16_t)data_rhall) * 2);
00214             process_comp_z4 = (int16_t)((process_comp_z3 + (32768)) / 65536);
00215             retval = ((process_comp_z2 - process_comp_z1) / (trim_data.dig_z2  + process_comp_z4));
00216 
00217             /* saturate result to +/- 2 micro-tesla */
00218             if (retval > BMM150_POSITIVE_SATURATION_Z) {
00219                 retval =  BMM150_POSITIVE_SATURATION_Z;
00220             } else {
00221                 if (retval < BMM150_NEGATIVE_SATURATION_Z) {
00222                     retval = BMM150_NEGATIVE_SATURATION_Z;
00223                 }
00224             }
00225             /* Conversion of LSB to micro-tesla*/
00226             retval = retval / 16;
00227         } else {
00228             retval = BMM150_OVERFLOW_OUTPUT;
00229 
00230         }
00231     } else {
00232         /* Overflow condition*/
00233         retval = BMM150_OVERFLOW_OUTPUT;
00234     }
00235 
00236     return (int16_t)retval;
00237 }
00238 
00239 void BMM150::set_presetmode(uint8_t preset_mode) {
00240     switch (preset_mode) {
00241         case BMM150_PRESETMODE_LOWPOWER:
00242             /*  Set the data rate x,y,z repetition
00243                 for Low Power mode */
00244             settings.data_rate  = BMM150_DATA_RATE_10HZ;
00245             settings.xy_rep  = BMM150_LOWPOWER_REPXY;
00246             settings.z_rep  = BMM150_LOWPOWER_REPZ;
00247             set_odr_xyz_rep(settings);
00248             break;
00249         case BMM150_PRESETMODE_REGULAR:
00250             /*  Set the data rate x,y,z repetition
00251                 for Regular mode */
00252             settings.data_rate  = BMM150_DATA_RATE_10HZ;
00253             settings.xy_rep  = BMM150_REGULAR_REPXY;
00254             settings.z_rep  = BMM150_REGULAR_REPZ;
00255             set_odr_xyz_rep(settings);
00256             break;
00257         case BMM150_PRESETMODE_HIGHACCURACY:
00258             /*  Set the data rate x,y,z repetition
00259                 for High Accuracy mode */
00260             settings.data_rate  = BMM150_DATA_RATE_20HZ;
00261             settings.xy_rep  = BMM150_HIGHACCURACY_REPXY;
00262             settings.z_rep  = BMM150_HIGHACCURACY_REPZ;
00263             set_odr_xyz_rep(settings);
00264             break;
00265         case BMM150_PRESETMODE_ENHANCED:
00266             /*  Set the data rate x,y,z repetition
00267                 for Enhanced Accuracy mode */
00268             settings.data_rate  = BMM150_DATA_RATE_10HZ;
00269             settings.xy_rep  = BMM150_ENHANCED_REPXY;
00270             settings.z_rep  = BMM150_ENHANCED_REPZ;
00271             set_odr_xyz_rep(settings);
00272             break;
00273         default:
00274             break;
00275     }
00276 }
00277 
00278 void BMM150::set_odr_xyz_rep(struct bmm150_settings settings) {
00279     /* Set the ODR */
00280     set_odr(settings);
00281     /* Set the XY-repetitions number */
00282     set_xy_rep(settings);
00283     /* Set the Z-repetitions number */
00284     set_z_rep(settings);
00285 }
00286 
00287 void BMM150::set_xy_rep(struct bmm150_settings settings) {
00288     uint8_t rep_xy;
00289     rep_xy = settings.xy_rep ;
00290     i2c_write(BMM150_REP_XY_ADDR, rep_xy);
00291 
00292 }
00293 
00294 void BMM150::set_z_rep(struct bmm150_settings settings) {
00295     uint8_t rep_z;
00296     rep_z = settings.z_rep ;
00297     i2c_write(BMM150_REP_Z_ADDR, rep_z);
00298 }
00299 
00300 
00301 void BMM150::soft_reset() 
00302 {
00303     uint8_t reg_data;
00304 
00305     reg_data = i2c_read(BMM150_POWER_CONTROL_ADDR);
00306     reg_data = reg_data | BMM150_SET_SOFT_RESET;
00307     i2c_write(BMM150_POWER_CONTROL_ADDR, reg_data);
00308     wait_ms(BMM150_SOFT_RESET_wait_ms);
00309 }
00310 
00311 
00312 void BMM150::set_odr(struct bmm150_settings settings) 
00313 {
00314     uint8_t reg_data;
00315 
00316     reg_data = i2c_read(BMM150_OP_MODE_ADDR);
00317     /*Set the ODR value */
00318     reg_data = BMM150_SET_BITS(reg_data, BMM150_ODR, settings.data_rate );
00319     i2c_write(BMM150_OP_MODE_ADDR, reg_data);
00320 }
00321 
00322 void BMM150::i2c_write(short address, short data) 
00323 {
00324     char temp[2];
00325     temp[0]=address;
00326     temp[1]=data;
00327     i2c->write(BMM150_I2C_Address,temp,2);
00328 }
00329 
00330 void BMM150::i2c_write(short address) 
00331 {
00332     char temp[1];
00333     temp[0]=address;
00334     i2c->write(BMM150_I2C_Address,temp,1);
00335 }
00336 
00337 void BMM150::i2c_read(short address, uint8_t* buffer, short length) 
00338 {
00339      i2c_write(address);
00340       i2c->read(BMM150_I2C_Address+1,(char *)buffer,length);
00341 }
00342 
00343 
00344 void BMM150::i2c_read(short address, int8_t* buffer, short length) 
00345 {
00346      i2c_write(address);
00347      i2c->read(BMM150_I2C_Address+1,(char *)buffer,length);
00348 }
00349 
00350 uint8_t BMM150::i2c_read(short address) 
00351 {
00352 char temp[1];
00353     i2c_write(address);
00354     i2c->read(BMM150_I2C_Address+1,temp,1);
00355     return temp[0];
00356 }
00357 
00358 
00359 // char* BMM150::getErrorText(short errorCode);
00360 // {
00361 //     if(ERRORCODE_1_NUM == 1)
00362 //     return ERRORCODE_1;
00363 
00364 //     return "Error not defined.";
00365 // }
00366 
00367 void BMM150::set_op_mode(uint8_t pwr_mode) {
00368     /* Select the power mode to set */
00369     switch (pwr_mode) {
00370         case BMM150_NORMAL_MODE:
00371             /*  If the sensor is in suspend mode
00372                 put the device to sleep mode */
00373             suspend_to_sleep_mode();
00374             /* write the op mode */
00375             write_op_mode(pwr_mode);
00376             break;
00377         case BMM150_FORCED_MODE:
00378             /*  If the sensor is in suspend mode
00379                 put the device to sleep mode */
00380             suspend_to_sleep_mode();
00381             /* write the op mode */
00382             write_op_mode(pwr_mode);
00383             break;
00384         case BMM150_SLEEP_MODE:
00385             /*  If the sensor is in suspend mode
00386                 put the device to sleep mode */
00387             suspend_to_sleep_mode();
00388             /* write the op mode */
00389             write_op_mode(pwr_mode);
00390             break;
00391         case BMM150_SUSPEND_MODE:
00392             /* Set the power control bit to zero */
00393             set_power_control_bit(BMM150_POWER_CNTRL_DISABLE);
00394             break;
00395         default:
00396             break;
00397     }
00398 }
00399 
00400 void BMM150::suspend_to_sleep_mode(void) {
00401     set_power_control_bit(BMM150_POWER_CNTRL_ENABLE);
00402     /* Start-up time wait_ms of 3ms*/
00403     wait_ms(3);
00404 }
00405 
00406 
00407 void BMM150::read_trim_registers() {
00408     uint8_t trim_x1y1[2] = {0};
00409     uint8_t trim_xyz_data[4] = {0};
00410     uint8_t trim_xy1xy2[10] = {0};
00411     uint16_t temp_msb = 0;
00412 
00413     /* Trim register value is read */
00414     i2c_read(BMM150_DIG_X1, trim_x1y1, 2);
00415     i2c_read(BMM150_DIG_Z4_LSB, trim_xyz_data, 4);
00416     i2c_read(BMM150_DIG_Z2_LSB, trim_xy1xy2, 10);
00417     /*  Trim data which is read is updated
00418         in the device structure */
00419     trim_data.dig_x1  = (char)trim_x1y1[0];
00420     trim_data.dig_y1  = (char)trim_x1y1[1];
00421     trim_data.dig_x2  = (char)trim_xyz_data[2];
00422     trim_data.dig_y2  = (char)trim_xyz_data[3];
00423     temp_msb = ((uint16_t)trim_xy1xy2[3]) << 8;
00424     trim_data.dig_z1  = (uint16_t)(temp_msb | trim_xy1xy2[2]);
00425     temp_msb = ((uint16_t)trim_xy1xy2[1]) << 8;
00426     trim_data.dig_z2  = (int16_t)(temp_msb | trim_xy1xy2[0]);
00427     temp_msb = ((uint16_t)trim_xy1xy2[7]) << 8;
00428     trim_data.dig_z3  = (int16_t)(temp_msb | trim_xy1xy2[6]);
00429     temp_msb = ((uint16_t)trim_xyz_data[1]) << 8;
00430     trim_data.dig_z4  = (int16_t)(temp_msb | trim_xyz_data[0]);
00431     trim_data.dig_xy1  = trim_xy1xy2[9];
00432     trim_data.dig_xy2  = (char)trim_xy1xy2[8];
00433     temp_msb = ((uint16_t)(trim_xy1xy2[5] & 0x7F)) << 8;
00434     trim_data.dig_xyz1  = (uint16_t)(temp_msb | trim_xy1xy2[4]);
00435 
00436 }
00437 
00438 void BMM150::write_op_mode(uint8_t op_mode) {
00439     uint8_t reg_data = 0;
00440     reg_data = i2c_read(BMM150_OP_MODE_ADDR);
00441     /* Set the op_mode value in Opmode bits of 0x4C */
00442     reg_data = BMM150_SET_BITS(reg_data, BMM150_OP_MODE, op_mode);
00443     i2c_write(BMM150_OP_MODE_ADDR, reg_data);
00444 }
00445 
00446 void BMM150::set_power_control_bit(uint8_t pwrcntrl_bit) {
00447     uint8_t reg_data = 0;
00448     /* Power control register 0x4B is read */
00449     reg_data = i2c_read(BMM150_POWER_CONTROL_ADDR);
00450     /* Sets the value of power control bit */
00451     reg_data = BMM150_SET_BITS_POS_0(reg_data, BMM150_PWR_CNTRL, pwrcntrl_bit);
00452     i2c_write(BMM150_POWER_CONTROL_ADDR, reg_data);
00453 }
00454 
00455 
00456 // /*!
00457 //  * @brief This API is used to perform the complete self test
00458 //  * (both normal and advanced) for the BMM150 sensor
00459 //  */
00460 // char BMM150::perform_self_test(uint8_t self_test_mode)
00461 // {
00462 //  char rslt;
00463 //  char self_test_rslt = 0;
00464 
00465 //  switch (self_test_mode) {
00466 //  case BMM150_NORMAL_SELF_TEST:
00467 //      /* Set the sensor in sleep mode */
00468 //      settings.pwr_mode = BMM150_SLEEP_MODE;
00469 //      set_op_mode(BMM150_SLEEP_MODE);
00470 //      /* Perform the normal self test */
00471 //      rslt = perform_normal_self_test();
00472 //      break;
00473 
00474 //  case BMM150_ADVANCED_SELF_TEST:
00475 //      /* Perform the advanced self test */
00476 //      rslt = perform_adv_self_test();
00477 //      /* Check to ensure bus error does not occur */
00478 //      if (rslt >=  BMM150_OK) {
00479 //          /* Store the status of self test result */
00480 //          self_test_rslt = rslt;
00481 //          /* Perform soft reset */
00482 //          soft_reset();
00483 //      }
00484 //      rslt = self_test_rslt;
00485 //      break;
00486 //  default:
00487 //      rslt = BMM150_E_INVALID_CONFIG;
00488 //      break;
00489 //  }
00490 
00491 //  return rslt;
00492 // }
00493 
00494 // /*
00495 //  * @brief This internal API is used to perform the normal self test
00496 //  * of the sensor and return the self test result as return value
00497 //  */
00498 // char BMM150::perform_normal_self_test()
00499 // {
00500 //  char rslt;
00501 //  uint8_t self_test_bit;
00502 
00503 //  /* Triggers the start of normal self test */
00504 //  enable_normal_self_test(&self_test_bit);
00505 //      /* Check for self test completion status */
00506 //      if (self_test_bit == 0) {
00507 //          /* Validates the self test results for all 3 axes */
00508 //          rslt = validate_normal_self_test();
00509 //      }
00510 
00511 //  return rslt;
00512 // }
00513 
00514 // /*!
00515 //  * @brief This internal API is used to enable the normal self test by setting
00516 //  * the Self Test bit (bit0) of the 0x4C register,
00517 //  * which triggers the start of self test
00518 //  */
00519 // void BMM150::enable_normal_self_test(uint8_t *self_test_enable)
00520 // {
00521 //  uint8_t reg_data;
00522 //  uint8_t self_test_val;
00523 
00524 //  /* Read the data from register 0x4C */
00525 //  reg_data = i2c->read(BMM150_OP_MODE_ADDR);
00526 //  /* Set the Self Test bit(bit0) of the 0x4C register */
00527 //  self_test_val = 1;
00528 //  reg_data = BMM150_SET_BITS_POS_0(reg_data, BMM150_SELF_TEST, self_test_val);
00529 //  /* Write the data to 0x4C register to trigger self test */
00530 //  i2c_write(BMM150_OP_MODE_ADDR, reg_data);
00531 //  wait_ms(BMM150_NORMAL_SELF_TEST_wait_ms);
00532 //  /* Read the data from register 0x4C */
00533 //  reg_data = i2c->read(BMM150_OP_MODE_ADDR);
00534 //  /* Self Test bit(bit0) is stored in self_test_enable,
00535 //  It will be reset to zero after the self test is over */
00536 //  *self_test_enable = BMM150_GET_BITS_POS_0(reg_data, BMM150_SELF_TEST);
00537 // }
00538 
00539 // /*!
00540 //  * @brief This internal API is used to validate the results of normal self test
00541 //  * by using the self test status available in the bit0 of registers 0x42,0x44
00542 //  * and 0x46.
00543 //  */
00544 // char BMM150::validate_normal_self_test()
00545 // {
00546 //  char rslt;
00547 //  uint8_t status;
00548 //  uint8_t self_test_rslt[5];
00549 
00550 //  /* Read the data from register 0x42 to 0x46 */
00551 //  i2c->read(BMM150_DATA_X_LSB, self_test_rslt, BMM150_SELF_TEST_LEN);
00552 //  /* Parse and get the self test status bits */
00553 //  /* X-Self-Test (bit0) of 0x42 register is stored*/
00554 //  self_test_rslt[0] = BMM150_GET_BITS_POS_0(self_test_rslt[0], BMM150_SELF_TEST);
00555 //  /* Y-Self-Test (bit0) of 0x44 register is stored */
00556 //  self_test_rslt[2] = BMM150_GET_BITS_POS_0(self_test_rslt[2], BMM150_SELF_TEST);
00557 //  /* Z-Self-Test (bit0) of 0x46 register is stored */
00558 //  self_test_rslt[4] = BMM150_GET_BITS_POS_0(self_test_rslt[4], BMM150_SELF_TEST);
00559 //  /* Combine the self test status and store it in the first
00560 //  3 bits of the status variable for processing*/
00561 //  status = (uint8_t)((self_test_rslt[4] << 2) | (self_test_rslt[2] << 1) | self_test_rslt[0]);
00562 //  /* Validate status and store Self test result in "rslt" */
00563 //  if (status == BMM150_SELF_TEST_STATUS_SUCCESS) {
00564 //      /* Self test is success when all status bits are set */
00565 //      rslt = BMM150_OK;
00566 //  } else {
00567 //      if (status == BMM150_SELF_TEST_STATUS_XYZ_FAIL) {
00568 //          /* Self test - all axis fail condition */
00569 //          rslt = BMM150_W_NORMAL_SELF_TEST_XYZ_FAIL;
00570 //      } else {
00571 //          /* Self test - some axis fail condition */
00572 //          rslt = (char)status;
00573 //      }
00574 //  }
00575 
00576 //  return rslt;
00577 // }
00578 
00579 // /*!
00580 //  * @brief This internal API is used to perform advanced self test for Z axis
00581 //  */
00582 // char BMM150::perform_adv_self_test()
00583 // {
00584 //  uint8_t self_test_current;
00585 //  int16_t positive_data_z;
00586 //  int16_t negative_data_z;
00587 //  char rslt;
00588 
00589 //  /* Set the desired power mode ,axes control and repetition settings */
00590 //  adv_self_test_settings();
00591 //  /* Measure the Z axes data with positive self-test current */
00592 //  self_test_current = BMM150_ENABLE_POSITIVE_CURRENT;
00593 //  adv_self_test_measurement(self_test_current, &positive_data_z);
00594 //  /* Measure the Z axes data with
00595 //  negative self-test current */
00596 //  self_test_current = BMM150_ENABLE_NEGATIVE_CURRENT;
00597 //  adv_self_test_measurement(self_test_current, &negative_data_z);
00598 //  /* Disable self-test current */
00599 //  self_test_current = BMM150_DISABLE_SELF_TEST_CURRENT;
00600 //  set_adv_self_test_current(self_test_current);
00601 //  /* Validate the advanced self test */
00602 //  rslt = validate_adv_self_test(positive_data_z, negative_data_z);
00603 
00604 //  return rslt;
00605 // }
00606 
00607 // /*!
00608 //  * @brief This internal API is used to set the desired power mode ,
00609 //  * axes control and repetition settings for advanced self test
00610 //  */
00611 // void BMM150::adv_self_test_settings()
00612 // {
00613 //  /* Set the power mode as sleep mode */
00614 //  settings.pwr_mode = BMM150_SLEEP_MODE;
00615 //  set_op_mode(BMM150_SLEEP_MODE);
00616 //  /* Disable XY-axis measurement */
00617 //  settings.xyz_axes_control = BMM150_DISABLE_XY_AXIS;
00618 //  set_control_measurement_xyz(settings);
00619 //  /* Repetition value is set as 0x04 */
00620 //  settings.z_rep = BMM150_SELF_TEST_REP_Z;
00621 //  set_z_rep(settings);
00622 // }
00623 
00624 // /*!
00625 //  * @brief This internal API is used to set the positive or negative value of
00626 //  * self-test current and obtain the corresponding magnetometer z axis data
00627 //  */
00628 // void BMM150::adv_self_test_measurement(uint8_t self_test_current, int16_t *data_z)
00629 // {
00630 //  /* Set the advanced self test current as positive or
00631 //  negative based on the value of parameter "self_test_current" */
00632 //  set_adv_self_test_current(self_test_current);
00633 //  /* Set the device in forced mode*/
00634 //  settings.pwr_mode = BMM150_FORCED_MODE;
00635 //  set_op_mode(BMM150_FORCED_MODE);
00636 //  /* wait_ms to ensure measurement is complete */
00637 //  wait_ms(4);
00638 //  /* Read Mag data and store the value of Z axis data */
00639 //  read_mag_data();
00640 //  /* Mag Z axis data is stored */
00641 //  *data_z = mag_data.z;
00642 // }
00643 
00644 // /*!
00645 //  * @brief This internal API is used to get the difference between the
00646 //  * Z axis mag data obtained by positive and negative self-test current
00647 //  * and validate whether the advanced self test is done successfully or not.
00648 //  */
00649 // char BMM150::validate_adv_self_test(int16_t positive_data_z, int16_t negative_data_z)
00650 // {
00651 //  int32_t adv_self_test_rslt;
00652 //  char rslt;
00653 
00654 //  /* Advanced self test difference between the Z axis mag data
00655 //     obtained by the positive and negative self-test current */
00656 //  adv_self_test_rslt = positive_data_z - negative_data_z;
00657 //  /* Advanced self test validation */
00658 //  /*Value of adv_self_test_rslt should be in between 180-240 micro-tesla*/
00659 //  if ((adv_self_test_rslt > 180) && (adv_self_test_rslt < 240)) {
00660 //      /* Advanced self test success */
00661 //      rslt = BMM150_OK;
00662 //  } else {
00663 //      /* Advanced self test fail */
00664 //      rslt = BMM150_W_ADV_SELF_TEST_FAIL;
00665 //  }
00666 
00667 //  return rslt;
00668 // }
00669 
00670 // /*
00671 //  * @brief This internal API is used to set the self test current value in
00672 //  * the Adv. ST bits (bit6 and bit7) of 0x4C register
00673 //  */
00674 // void BMM150::set_adv_self_test_current(uint8_t self_test_current)
00675 // {
00676 //  uint8_t reg_data;
00677 
00678 //  /* Read the 0x4C register */
00679 //  reg_data = i2c->read(BMM150_OP_MODE_ADDR);
00680 //  /* Set the self test current value in the Adv. ST bits
00681 //  (bit6 and bit7) of 0x4c register */
00682 //  reg_data = BMM150_SET_BITS(reg_data, BMM150_ADV_SELF_TEST, self_test_current);
00683 //  i2c_write(BMM150_OP_MODE_ADDR, reg_data);
00684 
00685 // }
00686 
00687 // /*
00688 //  * @brief This internal API is used to enable or disable the magnetic
00689 //  * measurement of x,y,z axes based on the value of xyz_axes_control.
00690 //  */
00691 // void BMM150::set_control_measurement_xyz(struct bmm150_settings settings)
00692 // {
00693 //  uint8_t reg_data;
00694 
00695 //  reg_data = i2c->read(BMM150_AXES_ENABLE_ADDR);
00696 //  /* Set the axes to be enabled/disabled*/
00697 //  reg_data = BMM150_SET_BITS(reg_data, BMM150_CONTROL_MEASURE, settings.xyz_axes_control);
00698 //  i2c_write(BMM150_AXES_ENABLE_ADDR, reg_data);
00699 // }