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

Committer:
cdupaty
Date:
Thu Mar 25 13:08:05 2021 +0000
Revision:
1:9651fd7ee8f6
Parent:
0:ef20a9039c0c
New I2C functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cdupaty 0:ef20a9039c0c 1 /*
cdupaty 0:ef20a9039c0c 2 Christian Dupaty 03/2021
cdupaty 0:ef20a9039c0c 3 Library and demo for BMM150 see datasheet here : https://www.bosch-sensortec.com/products/motion-sensors/magnetometers-bmm150/
cdupaty 0:ef20a9039c0c 4 Adaptation of BOSCH driver https://github.com/BoschSensortec/BMM150-Sensor-API
cdupaty 0:ef20a9039c0c 5 for ARM MBED and tested on NUCLEO-L073RZ and GEOMAGNETIC CLICK
cdupaty 0:ef20a9039c0c 6 https://www.mikroe.com/geomagnetic-click
cdupaty 0:ef20a9039c0c 7 */
cdupaty 0:ef20a9039c0c 8
cdupaty 0:ef20a9039c0c 9 #include "mbed.h"
cdupaty 0:ef20a9039c0c 10 #include "bmm150.h"
cdupaty 0:ef20a9039c0c 11
cdupaty 0:ef20a9039c0c 12 BMM150::BMM150(PinName sda, PinName scl)
cdupaty 0:ef20a9039c0c 13 {
cdupaty 0:ef20a9039c0c 14 //I2C *i2c;
cdupaty 0:ef20a9039c0c 15 i2c = new I2C(sda, scl);
cdupaty 0:ef20a9039c0c 16 //100KHz, as specified by the datasheet.
cdupaty 0:ef20a9039c0c 17 i2c ->frequency(100000);
cdupaty 0:ef20a9039c0c 18 }
cdupaty 0:ef20a9039c0c 19
cdupaty 0:ef20a9039c0c 20 int8_t BMM150::initialize(void)
cdupaty 0:ef20a9039c0c 21 {
cdupaty 0:ef20a9039c0c 22 // i2c.begin();
cdupaty 0:ef20a9039c0c 23
cdupaty 0:ef20a9039c0c 24 /* Power up the sensor from suspend to sleep mode */
cdupaty 0:ef20a9039c0c 25 set_op_mode(BMM150_SLEEP_MODE);
cdupaty 0:ef20a9039c0c 26 wait_ms(BMM150_START_UP_TIME);
cdupaty 0:ef20a9039c0c 27
cdupaty 0:ef20a9039c0c 28 /* Check chip ID */
cdupaty 0:ef20a9039c0c 29 uint8_t id = i2c_read(BMM150_CHIP_ID_ADDR);
cdupaty 0:ef20a9039c0c 30 if (id != BMM150_CHIP_ID) {
cdupaty 0:ef20a9039c0c 31 return BMM150_E_ID_NOT_CONFORM;
cdupaty 0:ef20a9039c0c 32 }
cdupaty 0:ef20a9039c0c 33
cdupaty 0:ef20a9039c0c 34 /* Function to update trim values */
cdupaty 0:ef20a9039c0c 35 read_trim_registers();
cdupaty 0:ef20a9039c0c 36
cdupaty 0:ef20a9039c0c 37 /* Setting the power mode as normal */
cdupaty 0:ef20a9039c0c 38 set_op_mode(BMM150_NORMAL_MODE);
cdupaty 0:ef20a9039c0c 39
cdupaty 0:ef20a9039c0c 40 /* Setting the preset mode as Low power mode
cdupaty 0:ef20a9039c0c 41 i.e. data rate = 10Hz XY-rep = 1 Z-rep = 2*/
cdupaty 0:ef20a9039c0c 42 set_presetmode(BMM150_PRESETMODE_LOWPOWER);
cdupaty 0:ef20a9039c0c 43 // set_presetmode(BMM150_HIGHACCURACY_REPZ);
cdupaty 0:ef20a9039c0c 44
cdupaty 0:ef20a9039c0c 45 return BMM150_OK;
cdupaty 0:ef20a9039c0c 46 }
cdupaty 0:ef20a9039c0c 47
cdupaty 0:ef20a9039c0c 48 void BMM150::read_mag_data() {
cdupaty 0:ef20a9039c0c 49 int16_t msb_data;
cdupaty 0:ef20a9039c0c 50 int8_t reg_data[BMM150_XYZR_DATA_LEN] = {0};
cdupaty 0:ef20a9039c0c 51
cdupaty 0:ef20a9039c0c 52 i2c_read(BMM150_DATA_X_LSB, reg_data, BMM150_XYZR_DATA_LEN);
cdupaty 0:ef20a9039c0c 53
cdupaty 0:ef20a9039c0c 54 /* Mag X axis data */
cdupaty 0:ef20a9039c0c 55 reg_data[0] = BMM150_GET_BITS(reg_data[0], BMM150_DATA_X);
cdupaty 0:ef20a9039c0c 56 /* Shift the MSB data to left by 5 bits */
cdupaty 0:ef20a9039c0c 57 /* Multiply by 32 to get the shift left by 5 value */
cdupaty 0:ef20a9039c0c 58 msb_data = ((int16_t)((char)reg_data[1])) * 32;
cdupaty 0:ef20a9039c0c 59 /* Raw mag X axis data */
cdupaty 0:ef20a9039c0c 60 raw_mag_data.raw_datax = (int16_t)(msb_data | reg_data[0]);
cdupaty 0:ef20a9039c0c 61 /* Mag Y axis data */
cdupaty 0:ef20a9039c0c 62 reg_data[2] = BMM150_GET_BITS(reg_data[2], BMM150_DATA_Y);
cdupaty 0:ef20a9039c0c 63 /* Shift the MSB data to left by 5 bits */
cdupaty 0:ef20a9039c0c 64 /* Multiply by 32 to get the shift left by 5 value */
cdupaty 0:ef20a9039c0c 65 msb_data = ((int16_t)((char)reg_data[3])) * 32;
cdupaty 0:ef20a9039c0c 66 /* Raw mag Y axis data */
cdupaty 0:ef20a9039c0c 67 raw_mag_data.raw_datay = (int16_t)(msb_data | reg_data[2]);
cdupaty 0:ef20a9039c0c 68 /* Mag Z axis data */
cdupaty 0:ef20a9039c0c 69 reg_data[4] = BMM150_GET_BITS(reg_data[4], BMM150_DATA_Z);
cdupaty 0:ef20a9039c0c 70 /* Shift the MSB data to left by 7 bits */
cdupaty 0:ef20a9039c0c 71 /* Multiply by 128 to get the shift left by 7 value */
cdupaty 0:ef20a9039c0c 72 msb_data = ((int16_t)((char)reg_data[5])) * 128;
cdupaty 0:ef20a9039c0c 73 /* Raw mag Z axis data */
cdupaty 0:ef20a9039c0c 74 raw_mag_data.raw_dataz = (int16_t)(msb_data | reg_data[4]);
cdupaty 0:ef20a9039c0c 75 /* Mag R-HALL data */
cdupaty 0:ef20a9039c0c 76 reg_data[6] = BMM150_GET_BITS(reg_data[6], BMM150_DATA_RHALL);
cdupaty 0:ef20a9039c0c 77 raw_mag_data.raw_data_r = (uint16_t)(((uint16_t)reg_data[7] << 6) | reg_data[6]);
cdupaty 0:ef20a9039c0c 78
cdupaty 0:ef20a9039c0c 79 /* Compensated Mag X data in int16_t format */
cdupaty 0:ef20a9039c0c 80 mag_data.x = compensate_x(raw_mag_data.raw_datax, raw_mag_data.raw_data_r);
cdupaty 0:ef20a9039c0c 81 /* Compensated Mag Y data in int16_t format */
cdupaty 0:ef20a9039c0c 82 mag_data.y = compensate_y(raw_mag_data.raw_datay, raw_mag_data.raw_data_r);
cdupaty 0:ef20a9039c0c 83 /* Compensated Mag Z data in int16_t format */
cdupaty 0:ef20a9039c0c 84 mag_data.z = compensate_z(raw_mag_data.raw_dataz, raw_mag_data.raw_data_r);
cdupaty 0:ef20a9039c0c 85 }
cdupaty 0:ef20a9039c0c 86
cdupaty 0:ef20a9039c0c 87 /*
cdupaty 0:ef20a9039c0c 88 @brief This internal API is used to obtain the compensated
cdupaty 0:ef20a9039c0c 89 magnetometer X axis data(micro-tesla) in int16_t.
cdupaty 0:ef20a9039c0c 90 */
cdupaty 0:ef20a9039c0c 91 int16_t BMM150::compensate_x(int16_t mag_data_x, uint16_t data_rhall)
cdupaty 0:ef20a9039c0c 92 {
cdupaty 0:ef20a9039c0c 93 int16_t retval;
cdupaty 0:ef20a9039c0c 94 uint16_t process_comp_x0 = 0;
cdupaty 0:ef20a9039c0c 95 int32_t process_comp_x1;
cdupaty 0:ef20a9039c0c 96 uint16_t process_comp_x2;
cdupaty 0:ef20a9039c0c 97 int32_t process_comp_x3;
cdupaty 0:ef20a9039c0c 98 int32_t process_comp_x4;
cdupaty 0:ef20a9039c0c 99 int32_t process_comp_x5;
cdupaty 0:ef20a9039c0c 100 int32_t process_comp_x6;
cdupaty 0:ef20a9039c0c 101 int32_t process_comp_x7;
cdupaty 0:ef20a9039c0c 102 int32_t process_comp_x8;
cdupaty 0:ef20a9039c0c 103 int32_t process_comp_x9;
cdupaty 0:ef20a9039c0c 104 int32_t process_comp_x10;
cdupaty 0:ef20a9039c0c 105
cdupaty 0:ef20a9039c0c 106 /* Overflow condition check */
cdupaty 0:ef20a9039c0c 107 if (mag_data_x != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
cdupaty 0:ef20a9039c0c 108 if (data_rhall != 0) {
cdupaty 0:ef20a9039c0c 109 /* Availability of valid data*/
cdupaty 0:ef20a9039c0c 110 process_comp_x0 = data_rhall;
cdupaty 0:ef20a9039c0c 111 } else if (trim_data.dig_xyz1 != 0) {
cdupaty 0:ef20a9039c0c 112 process_comp_x0 = trim_data.dig_xyz1;
cdupaty 0:ef20a9039c0c 113 } else {
cdupaty 0:ef20a9039c0c 114 process_comp_x0 = 0;
cdupaty 0:ef20a9039c0c 115 }
cdupaty 0:ef20a9039c0c 116 if (process_comp_x0 != 0) {
cdupaty 0:ef20a9039c0c 117 /* Processing compensation equations*/
cdupaty 0:ef20a9039c0c 118 process_comp_x1 = ((int32_t)trim_data.dig_xyz1) * 16384;
cdupaty 0:ef20a9039c0c 119 process_comp_x2 = ((uint16_t)(process_comp_x1 / process_comp_x0)) - ((uint16_t)0x4000);
cdupaty 0:ef20a9039c0c 120 retval = ((int16_t)process_comp_x2);
cdupaty 0:ef20a9039c0c 121 process_comp_x3 = (((int32_t)retval) * ((int32_t)retval));
cdupaty 0:ef20a9039c0c 122 process_comp_x4 = (((int32_t)trim_data.dig_xy2) * (process_comp_x3 / 128));
cdupaty 0:ef20a9039c0c 123 process_comp_x5 = (int32_t)(((int16_t)trim_data.dig_xy1) * 128);
cdupaty 0:ef20a9039c0c 124 process_comp_x6 = ((int32_t)retval) * process_comp_x5;
cdupaty 0:ef20a9039c0c 125 process_comp_x7 = (((process_comp_x4 + process_comp_x6) / 512) + ((int32_t)0x100000));
cdupaty 0:ef20a9039c0c 126 process_comp_x8 = ((int32_t)(((int16_t)trim_data.dig_x2) + ((int16_t)0xA0)));
cdupaty 0:ef20a9039c0c 127 process_comp_x9 = ((process_comp_x7 * process_comp_x8) / 4096);
cdupaty 0:ef20a9039c0c 128 process_comp_x10 = ((int32_t)mag_data_x) * process_comp_x9;
cdupaty 0:ef20a9039c0c 129 retval = ((int16_t)(process_comp_x10 / 8192));
cdupaty 0:ef20a9039c0c 130 retval = (retval + (((int16_t)trim_data.dig_x1) * 8)) / 16;
cdupaty 0:ef20a9039c0c 131 } else {
cdupaty 0:ef20a9039c0c 132 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 133 }
cdupaty 0:ef20a9039c0c 134 } else {
cdupaty 0:ef20a9039c0c 135 /* Overflow condition */
cdupaty 0:ef20a9039c0c 136 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 137 }
cdupaty 0:ef20a9039c0c 138
cdupaty 0:ef20a9039c0c 139 return retval;
cdupaty 0:ef20a9039c0c 140 }
cdupaty 0:ef20a9039c0c 141
cdupaty 0:ef20a9039c0c 142 /*
cdupaty 0:ef20a9039c0c 143 @brief This internal API is used to obtain the compensated
cdupaty 0:ef20a9039c0c 144 magnetometer Y axis data(micro-tesla) in int16_t.
cdupaty 0:ef20a9039c0c 145 */
cdupaty 0:ef20a9039c0c 146 int16_t BMM150::compensate_y(int16_t mag_data_y, uint16_t data_rhall) {
cdupaty 0:ef20a9039c0c 147 int16_t retval;
cdupaty 0:ef20a9039c0c 148 uint16_t process_comp_y0 = 0;
cdupaty 0:ef20a9039c0c 149 int32_t process_comp_y1;
cdupaty 0:ef20a9039c0c 150 uint16_t process_comp_y2;
cdupaty 0:ef20a9039c0c 151 int32_t process_comp_y3;
cdupaty 0:ef20a9039c0c 152 int32_t process_comp_y4;
cdupaty 0:ef20a9039c0c 153 int32_t process_comp_y5;
cdupaty 0:ef20a9039c0c 154 int32_t process_comp_y6;
cdupaty 0:ef20a9039c0c 155 int32_t process_comp_y7;
cdupaty 0:ef20a9039c0c 156 int32_t process_comp_y8;
cdupaty 0:ef20a9039c0c 157 int32_t process_comp_y9;
cdupaty 0:ef20a9039c0c 158
cdupaty 0:ef20a9039c0c 159 /* Overflow condition check */
cdupaty 0:ef20a9039c0c 160 if (mag_data_y != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
cdupaty 0:ef20a9039c0c 161 if (data_rhall != 0) {
cdupaty 0:ef20a9039c0c 162 /* Availability of valid data*/
cdupaty 0:ef20a9039c0c 163 process_comp_y0 = data_rhall;
cdupaty 0:ef20a9039c0c 164 } else if (trim_data.dig_xyz1 != 0) {
cdupaty 0:ef20a9039c0c 165 process_comp_y0 = trim_data.dig_xyz1;
cdupaty 0:ef20a9039c0c 166 } else {
cdupaty 0:ef20a9039c0c 167 process_comp_y0 = 0;
cdupaty 0:ef20a9039c0c 168 }
cdupaty 0:ef20a9039c0c 169 if (process_comp_y0 != 0) {
cdupaty 0:ef20a9039c0c 170 /*Processing compensation equations*/
cdupaty 0:ef20a9039c0c 171 process_comp_y1 = (((int32_t)trim_data.dig_xyz1) * 16384) / process_comp_y0;
cdupaty 0:ef20a9039c0c 172 process_comp_y2 = ((uint16_t)process_comp_y1) - ((uint16_t)0x4000);
cdupaty 0:ef20a9039c0c 173 retval = ((int16_t)process_comp_y2);
cdupaty 0:ef20a9039c0c 174 process_comp_y3 = ((int32_t) retval) * ((int32_t)retval);
cdupaty 0:ef20a9039c0c 175 process_comp_y4 = ((int32_t)trim_data.dig_xy2) * (process_comp_y3 / 128);
cdupaty 0:ef20a9039c0c 176 process_comp_y5 = ((int32_t)(((int16_t)trim_data.dig_xy1) * 128));
cdupaty 0:ef20a9039c0c 177 process_comp_y6 = ((process_comp_y4 + (((int32_t)retval) * process_comp_y5)) / 512);
cdupaty 0:ef20a9039c0c 178 process_comp_y7 = ((int32_t)(((int16_t)trim_data.dig_y2) + ((int16_t)0xA0)));
cdupaty 0:ef20a9039c0c 179 process_comp_y8 = (((process_comp_y6 + ((int32_t)0x100000)) * process_comp_y7) / 4096);
cdupaty 0:ef20a9039c0c 180 process_comp_y9 = (((int32_t)mag_data_y) * process_comp_y8);
cdupaty 0:ef20a9039c0c 181 retval = (int16_t)(process_comp_y9 / 8192);
cdupaty 0:ef20a9039c0c 182 retval = (retval + (((int16_t)trim_data.dig_y1) * 8)) / 16;
cdupaty 0:ef20a9039c0c 183 } else {
cdupaty 0:ef20a9039c0c 184 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 185 }
cdupaty 0:ef20a9039c0c 186 } else {
cdupaty 0:ef20a9039c0c 187 /* Overflow condition*/
cdupaty 0:ef20a9039c0c 188 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 189 }
cdupaty 0:ef20a9039c0c 190
cdupaty 0:ef20a9039c0c 191 return retval;
cdupaty 0:ef20a9039c0c 192 }
cdupaty 0:ef20a9039c0c 193
cdupaty 0:ef20a9039c0c 194 /*
cdupaty 0:ef20a9039c0c 195 @brief This internal API is used to obtain the compensated
cdupaty 0:ef20a9039c0c 196 magnetometer Z axis data(micro-tesla) in int16_t.
cdupaty 0:ef20a9039c0c 197 */
cdupaty 0:ef20a9039c0c 198 int16_t BMM150::compensate_z(int16_t mag_data_z, uint16_t data_rhall) {
cdupaty 0:ef20a9039c0c 199 int32_t retval;
cdupaty 0:ef20a9039c0c 200 int16_t process_comp_z0;
cdupaty 0:ef20a9039c0c 201 int32_t process_comp_z1;
cdupaty 0:ef20a9039c0c 202 int32_t process_comp_z2;
cdupaty 0:ef20a9039c0c 203 int32_t process_comp_z3;
cdupaty 0:ef20a9039c0c 204 int16_t process_comp_z4;
cdupaty 0:ef20a9039c0c 205
cdupaty 0:ef20a9039c0c 206 if (mag_data_z != BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL) {
cdupaty 0:ef20a9039c0c 207 if ((trim_data.dig_z2 != 0) && (trim_data.dig_z1 != 0)
cdupaty 0:ef20a9039c0c 208 && (data_rhall != 0) && (trim_data.dig_xyz1 != 0)) {
cdupaty 0:ef20a9039c0c 209 /*Processing compensation equations*/
cdupaty 0:ef20a9039c0c 210 process_comp_z0 = ((int16_t)data_rhall) - ((int16_t) trim_data.dig_xyz1);
cdupaty 0:ef20a9039c0c 211 process_comp_z1 = (((int32_t)trim_data.dig_z3) * ((int32_t)(process_comp_z0))) / 4;
cdupaty 0:ef20a9039c0c 212 process_comp_z2 = (((int32_t)(mag_data_z - trim_data.dig_z4)) * 32768);
cdupaty 0:ef20a9039c0c 213 process_comp_z3 = ((int32_t)trim_data.dig_z1) * (((int16_t)data_rhall) * 2);
cdupaty 0:ef20a9039c0c 214 process_comp_z4 = (int16_t)((process_comp_z3 + (32768)) / 65536);
cdupaty 0:ef20a9039c0c 215 retval = ((process_comp_z2 - process_comp_z1) / (trim_data.dig_z2 + process_comp_z4));
cdupaty 0:ef20a9039c0c 216
cdupaty 0:ef20a9039c0c 217 /* saturate result to +/- 2 micro-tesla */
cdupaty 0:ef20a9039c0c 218 if (retval > BMM150_POSITIVE_SATURATION_Z) {
cdupaty 0:ef20a9039c0c 219 retval = BMM150_POSITIVE_SATURATION_Z;
cdupaty 0:ef20a9039c0c 220 } else {
cdupaty 0:ef20a9039c0c 221 if (retval < BMM150_NEGATIVE_SATURATION_Z) {
cdupaty 0:ef20a9039c0c 222 retval = BMM150_NEGATIVE_SATURATION_Z;
cdupaty 0:ef20a9039c0c 223 }
cdupaty 0:ef20a9039c0c 224 }
cdupaty 0:ef20a9039c0c 225 /* Conversion of LSB to micro-tesla*/
cdupaty 0:ef20a9039c0c 226 retval = retval / 16;
cdupaty 0:ef20a9039c0c 227 } else {
cdupaty 0:ef20a9039c0c 228 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 229
cdupaty 0:ef20a9039c0c 230 }
cdupaty 0:ef20a9039c0c 231 } else {
cdupaty 0:ef20a9039c0c 232 /* Overflow condition*/
cdupaty 0:ef20a9039c0c 233 retval = BMM150_OVERFLOW_OUTPUT;
cdupaty 0:ef20a9039c0c 234 }
cdupaty 0:ef20a9039c0c 235
cdupaty 0:ef20a9039c0c 236 return (int16_t)retval;
cdupaty 0:ef20a9039c0c 237 }
cdupaty 0:ef20a9039c0c 238
cdupaty 0:ef20a9039c0c 239 void BMM150::set_presetmode(uint8_t preset_mode) {
cdupaty 0:ef20a9039c0c 240 switch (preset_mode) {
cdupaty 0:ef20a9039c0c 241 case BMM150_PRESETMODE_LOWPOWER:
cdupaty 0:ef20a9039c0c 242 /* Set the data rate x,y,z repetition
cdupaty 0:ef20a9039c0c 243 for Low Power mode */
cdupaty 0:ef20a9039c0c 244 settings.data_rate = BMM150_DATA_RATE_10HZ;
cdupaty 0:ef20a9039c0c 245 settings.xy_rep = BMM150_LOWPOWER_REPXY;
cdupaty 0:ef20a9039c0c 246 settings.z_rep = BMM150_LOWPOWER_REPZ;
cdupaty 0:ef20a9039c0c 247 set_odr_xyz_rep(settings);
cdupaty 0:ef20a9039c0c 248 break;
cdupaty 0:ef20a9039c0c 249 case BMM150_PRESETMODE_REGULAR:
cdupaty 0:ef20a9039c0c 250 /* Set the data rate x,y,z repetition
cdupaty 0:ef20a9039c0c 251 for Regular mode */
cdupaty 0:ef20a9039c0c 252 settings.data_rate = BMM150_DATA_RATE_10HZ;
cdupaty 0:ef20a9039c0c 253 settings.xy_rep = BMM150_REGULAR_REPXY;
cdupaty 0:ef20a9039c0c 254 settings.z_rep = BMM150_REGULAR_REPZ;
cdupaty 0:ef20a9039c0c 255 set_odr_xyz_rep(settings);
cdupaty 0:ef20a9039c0c 256 break;
cdupaty 0:ef20a9039c0c 257 case BMM150_PRESETMODE_HIGHACCURACY:
cdupaty 0:ef20a9039c0c 258 /* Set the data rate x,y,z repetition
cdupaty 0:ef20a9039c0c 259 for High Accuracy mode */
cdupaty 0:ef20a9039c0c 260 settings.data_rate = BMM150_DATA_RATE_20HZ;
cdupaty 0:ef20a9039c0c 261 settings.xy_rep = BMM150_HIGHACCURACY_REPXY;
cdupaty 0:ef20a9039c0c 262 settings.z_rep = BMM150_HIGHACCURACY_REPZ;
cdupaty 0:ef20a9039c0c 263 set_odr_xyz_rep(settings);
cdupaty 0:ef20a9039c0c 264 break;
cdupaty 0:ef20a9039c0c 265 case BMM150_PRESETMODE_ENHANCED:
cdupaty 0:ef20a9039c0c 266 /* Set the data rate x,y,z repetition
cdupaty 0:ef20a9039c0c 267 for Enhanced Accuracy mode */
cdupaty 0:ef20a9039c0c 268 settings.data_rate = BMM150_DATA_RATE_10HZ;
cdupaty 0:ef20a9039c0c 269 settings.xy_rep = BMM150_ENHANCED_REPXY;
cdupaty 0:ef20a9039c0c 270 settings.z_rep = BMM150_ENHANCED_REPZ;
cdupaty 0:ef20a9039c0c 271 set_odr_xyz_rep(settings);
cdupaty 0:ef20a9039c0c 272 break;
cdupaty 0:ef20a9039c0c 273 default:
cdupaty 0:ef20a9039c0c 274 break;
cdupaty 0:ef20a9039c0c 275 }
cdupaty 0:ef20a9039c0c 276 }
cdupaty 0:ef20a9039c0c 277
cdupaty 0:ef20a9039c0c 278 void BMM150::set_odr_xyz_rep(struct bmm150_settings settings) {
cdupaty 0:ef20a9039c0c 279 /* Set the ODR */
cdupaty 0:ef20a9039c0c 280 set_odr(settings);
cdupaty 0:ef20a9039c0c 281 /* Set the XY-repetitions number */
cdupaty 0:ef20a9039c0c 282 set_xy_rep(settings);
cdupaty 0:ef20a9039c0c 283 /* Set the Z-repetitions number */
cdupaty 0:ef20a9039c0c 284 set_z_rep(settings);
cdupaty 0:ef20a9039c0c 285 }
cdupaty 0:ef20a9039c0c 286
cdupaty 0:ef20a9039c0c 287 void BMM150::set_xy_rep(struct bmm150_settings settings) {
cdupaty 0:ef20a9039c0c 288 uint8_t rep_xy;
cdupaty 0:ef20a9039c0c 289 rep_xy = settings.xy_rep;
cdupaty 0:ef20a9039c0c 290 i2c_write(BMM150_REP_XY_ADDR, rep_xy);
cdupaty 0:ef20a9039c0c 291
cdupaty 0:ef20a9039c0c 292 }
cdupaty 0:ef20a9039c0c 293
cdupaty 0:ef20a9039c0c 294 void BMM150::set_z_rep(struct bmm150_settings settings) {
cdupaty 0:ef20a9039c0c 295 uint8_t rep_z;
cdupaty 0:ef20a9039c0c 296 rep_z = settings.z_rep;
cdupaty 0:ef20a9039c0c 297 i2c_write(BMM150_REP_Z_ADDR, rep_z);
cdupaty 0:ef20a9039c0c 298 }
cdupaty 0:ef20a9039c0c 299
cdupaty 0:ef20a9039c0c 300
cdupaty 0:ef20a9039c0c 301 void BMM150::soft_reset()
cdupaty 0:ef20a9039c0c 302 {
cdupaty 0:ef20a9039c0c 303 uint8_t reg_data;
cdupaty 0:ef20a9039c0c 304
cdupaty 0:ef20a9039c0c 305 reg_data = i2c_read(BMM150_POWER_CONTROL_ADDR);
cdupaty 0:ef20a9039c0c 306 reg_data = reg_data | BMM150_SET_SOFT_RESET;
cdupaty 0:ef20a9039c0c 307 i2c_write(BMM150_POWER_CONTROL_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 308 wait_ms(BMM150_SOFT_RESET_wait_ms);
cdupaty 0:ef20a9039c0c 309 }
cdupaty 0:ef20a9039c0c 310
cdupaty 0:ef20a9039c0c 311
cdupaty 0:ef20a9039c0c 312 void BMM150::set_odr(struct bmm150_settings settings)
cdupaty 0:ef20a9039c0c 313 {
cdupaty 0:ef20a9039c0c 314 uint8_t reg_data;
cdupaty 0:ef20a9039c0c 315
cdupaty 0:ef20a9039c0c 316 reg_data = i2c_read(BMM150_OP_MODE_ADDR);
cdupaty 0:ef20a9039c0c 317 /*Set the ODR value */
cdupaty 0:ef20a9039c0c 318 reg_data = BMM150_SET_BITS(reg_data, BMM150_ODR, settings.data_rate);
cdupaty 0:ef20a9039c0c 319 i2c_write(BMM150_OP_MODE_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 320 }
cdupaty 0:ef20a9039c0c 321
cdupaty 0:ef20a9039c0c 322 void BMM150::i2c_write(short address, short data)
cdupaty 0:ef20a9039c0c 323 {
cdupaty 1:9651fd7ee8f6 324 char temp[2];
cdupaty 1:9651fd7ee8f6 325 temp[0]=address;
cdupaty 1:9651fd7ee8f6 326 temp[1]=data;
cdupaty 1:9651fd7ee8f6 327 i2c->write(BMM150_I2C_Address,temp,2);
cdupaty 1:9651fd7ee8f6 328 }
cdupaty 1:9651fd7ee8f6 329
cdupaty 1:9651fd7ee8f6 330 void BMM150::i2c_write(short address)
cdupaty 1:9651fd7ee8f6 331 {
cdupaty 1:9651fd7ee8f6 332 char temp[1];
cdupaty 1:9651fd7ee8f6 333 temp[0]=address;
cdupaty 1:9651fd7ee8f6 334 i2c->write(BMM150_I2C_Address,temp,1);
cdupaty 0:ef20a9039c0c 335 }
cdupaty 0:ef20a9039c0c 336
cdupaty 0:ef20a9039c0c 337 void BMM150::i2c_read(short address, uint8_t* buffer, short length)
cdupaty 1:9651fd7ee8f6 338 {
cdupaty 1:9651fd7ee8f6 339 i2c_write(address);
cdupaty 1:9651fd7ee8f6 340 i2c->read(BMM150_I2C_Address+1,(char *)buffer,length);
cdupaty 0:ef20a9039c0c 341 }
cdupaty 0:ef20a9039c0c 342
cdupaty 0:ef20a9039c0c 343
cdupaty 0:ef20a9039c0c 344 void BMM150::i2c_read(short address, int8_t* buffer, short length)
cdupaty 0:ef20a9039c0c 345 {
cdupaty 1:9651fd7ee8f6 346 i2c_write(address);
cdupaty 1:9651fd7ee8f6 347 i2c->read(BMM150_I2C_Address+1,(char *)buffer,length);
cdupaty 0:ef20a9039c0c 348 }
cdupaty 0:ef20a9039c0c 349
cdupaty 0:ef20a9039c0c 350 uint8_t BMM150::i2c_read(short address)
cdupaty 0:ef20a9039c0c 351 {
cdupaty 1:9651fd7ee8f6 352 char temp[1];
cdupaty 1:9651fd7ee8f6 353 i2c_write(address);
cdupaty 1:9651fd7ee8f6 354 i2c->read(BMM150_I2C_Address+1,temp,1);
cdupaty 1:9651fd7ee8f6 355 return temp[0];
cdupaty 0:ef20a9039c0c 356 }
cdupaty 0:ef20a9039c0c 357
cdupaty 0:ef20a9039c0c 358
cdupaty 0:ef20a9039c0c 359 // char* BMM150::getErrorText(short errorCode);
cdupaty 0:ef20a9039c0c 360 // {
cdupaty 0:ef20a9039c0c 361 // if(ERRORCODE_1_NUM == 1)
cdupaty 0:ef20a9039c0c 362 // return ERRORCODE_1;
cdupaty 0:ef20a9039c0c 363
cdupaty 0:ef20a9039c0c 364 // return "Error not defined.";
cdupaty 0:ef20a9039c0c 365 // }
cdupaty 0:ef20a9039c0c 366
cdupaty 0:ef20a9039c0c 367 void BMM150::set_op_mode(uint8_t pwr_mode) {
cdupaty 0:ef20a9039c0c 368 /* Select the power mode to set */
cdupaty 0:ef20a9039c0c 369 switch (pwr_mode) {
cdupaty 0:ef20a9039c0c 370 case BMM150_NORMAL_MODE:
cdupaty 0:ef20a9039c0c 371 /* If the sensor is in suspend mode
cdupaty 0:ef20a9039c0c 372 put the device to sleep mode */
cdupaty 0:ef20a9039c0c 373 suspend_to_sleep_mode();
cdupaty 0:ef20a9039c0c 374 /* write the op mode */
cdupaty 0:ef20a9039c0c 375 write_op_mode(pwr_mode);
cdupaty 0:ef20a9039c0c 376 break;
cdupaty 0:ef20a9039c0c 377 case BMM150_FORCED_MODE:
cdupaty 0:ef20a9039c0c 378 /* If the sensor is in suspend mode
cdupaty 0:ef20a9039c0c 379 put the device to sleep mode */
cdupaty 0:ef20a9039c0c 380 suspend_to_sleep_mode();
cdupaty 0:ef20a9039c0c 381 /* write the op mode */
cdupaty 0:ef20a9039c0c 382 write_op_mode(pwr_mode);
cdupaty 0:ef20a9039c0c 383 break;
cdupaty 0:ef20a9039c0c 384 case BMM150_SLEEP_MODE:
cdupaty 0:ef20a9039c0c 385 /* If the sensor is in suspend mode
cdupaty 0:ef20a9039c0c 386 put the device to sleep mode */
cdupaty 0:ef20a9039c0c 387 suspend_to_sleep_mode();
cdupaty 0:ef20a9039c0c 388 /* write the op mode */
cdupaty 0:ef20a9039c0c 389 write_op_mode(pwr_mode);
cdupaty 0:ef20a9039c0c 390 break;
cdupaty 0:ef20a9039c0c 391 case BMM150_SUSPEND_MODE:
cdupaty 0:ef20a9039c0c 392 /* Set the power control bit to zero */
cdupaty 0:ef20a9039c0c 393 set_power_control_bit(BMM150_POWER_CNTRL_DISABLE);
cdupaty 0:ef20a9039c0c 394 break;
cdupaty 0:ef20a9039c0c 395 default:
cdupaty 0:ef20a9039c0c 396 break;
cdupaty 0:ef20a9039c0c 397 }
cdupaty 0:ef20a9039c0c 398 }
cdupaty 0:ef20a9039c0c 399
cdupaty 0:ef20a9039c0c 400 void BMM150::suspend_to_sleep_mode(void) {
cdupaty 0:ef20a9039c0c 401 set_power_control_bit(BMM150_POWER_CNTRL_ENABLE);
cdupaty 0:ef20a9039c0c 402 /* Start-up time wait_ms of 3ms*/
cdupaty 0:ef20a9039c0c 403 wait_ms(3);
cdupaty 0:ef20a9039c0c 404 }
cdupaty 0:ef20a9039c0c 405
cdupaty 0:ef20a9039c0c 406
cdupaty 0:ef20a9039c0c 407 void BMM150::read_trim_registers() {
cdupaty 0:ef20a9039c0c 408 uint8_t trim_x1y1[2] = {0};
cdupaty 0:ef20a9039c0c 409 uint8_t trim_xyz_data[4] = {0};
cdupaty 0:ef20a9039c0c 410 uint8_t trim_xy1xy2[10] = {0};
cdupaty 0:ef20a9039c0c 411 uint16_t temp_msb = 0;
cdupaty 0:ef20a9039c0c 412
cdupaty 0:ef20a9039c0c 413 /* Trim register value is read */
cdupaty 0:ef20a9039c0c 414 i2c_read(BMM150_DIG_X1, trim_x1y1, 2);
cdupaty 0:ef20a9039c0c 415 i2c_read(BMM150_DIG_Z4_LSB, trim_xyz_data, 4);
cdupaty 0:ef20a9039c0c 416 i2c_read(BMM150_DIG_Z2_LSB, trim_xy1xy2, 10);
cdupaty 0:ef20a9039c0c 417 /* Trim data which is read is updated
cdupaty 0:ef20a9039c0c 418 in the device structure */
cdupaty 0:ef20a9039c0c 419 trim_data.dig_x1 = (char)trim_x1y1[0];
cdupaty 0:ef20a9039c0c 420 trim_data.dig_y1 = (char)trim_x1y1[1];
cdupaty 0:ef20a9039c0c 421 trim_data.dig_x2 = (char)trim_xyz_data[2];
cdupaty 0:ef20a9039c0c 422 trim_data.dig_y2 = (char)trim_xyz_data[3];
cdupaty 0:ef20a9039c0c 423 temp_msb = ((uint16_t)trim_xy1xy2[3]) << 8;
cdupaty 0:ef20a9039c0c 424 trim_data.dig_z1 = (uint16_t)(temp_msb | trim_xy1xy2[2]);
cdupaty 0:ef20a9039c0c 425 temp_msb = ((uint16_t)trim_xy1xy2[1]) << 8;
cdupaty 0:ef20a9039c0c 426 trim_data.dig_z2 = (int16_t)(temp_msb | trim_xy1xy2[0]);
cdupaty 0:ef20a9039c0c 427 temp_msb = ((uint16_t)trim_xy1xy2[7]) << 8;
cdupaty 0:ef20a9039c0c 428 trim_data.dig_z3 = (int16_t)(temp_msb | trim_xy1xy2[6]);
cdupaty 0:ef20a9039c0c 429 temp_msb = ((uint16_t)trim_xyz_data[1]) << 8;
cdupaty 0:ef20a9039c0c 430 trim_data.dig_z4 = (int16_t)(temp_msb | trim_xyz_data[0]);
cdupaty 0:ef20a9039c0c 431 trim_data.dig_xy1 = trim_xy1xy2[9];
cdupaty 0:ef20a9039c0c 432 trim_data.dig_xy2 = (char)trim_xy1xy2[8];
cdupaty 0:ef20a9039c0c 433 temp_msb = ((uint16_t)(trim_xy1xy2[5] & 0x7F)) << 8;
cdupaty 0:ef20a9039c0c 434 trim_data.dig_xyz1 = (uint16_t)(temp_msb | trim_xy1xy2[4]);
cdupaty 0:ef20a9039c0c 435
cdupaty 0:ef20a9039c0c 436 }
cdupaty 0:ef20a9039c0c 437
cdupaty 0:ef20a9039c0c 438 void BMM150::write_op_mode(uint8_t op_mode) {
cdupaty 0:ef20a9039c0c 439 uint8_t reg_data = 0;
cdupaty 0:ef20a9039c0c 440 reg_data = i2c_read(BMM150_OP_MODE_ADDR);
cdupaty 0:ef20a9039c0c 441 /* Set the op_mode value in Opmode bits of 0x4C */
cdupaty 0:ef20a9039c0c 442 reg_data = BMM150_SET_BITS(reg_data, BMM150_OP_MODE, op_mode);
cdupaty 0:ef20a9039c0c 443 i2c_write(BMM150_OP_MODE_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 444 }
cdupaty 0:ef20a9039c0c 445
cdupaty 0:ef20a9039c0c 446 void BMM150::set_power_control_bit(uint8_t pwrcntrl_bit) {
cdupaty 0:ef20a9039c0c 447 uint8_t reg_data = 0;
cdupaty 0:ef20a9039c0c 448 /* Power control register 0x4B is read */
cdupaty 0:ef20a9039c0c 449 reg_data = i2c_read(BMM150_POWER_CONTROL_ADDR);
cdupaty 0:ef20a9039c0c 450 /* Sets the value of power control bit */
cdupaty 0:ef20a9039c0c 451 reg_data = BMM150_SET_BITS_POS_0(reg_data, BMM150_PWR_CNTRL, pwrcntrl_bit);
cdupaty 0:ef20a9039c0c 452 i2c_write(BMM150_POWER_CONTROL_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 453 }
cdupaty 0:ef20a9039c0c 454
cdupaty 0:ef20a9039c0c 455
cdupaty 0:ef20a9039c0c 456 // /*!
cdupaty 0:ef20a9039c0c 457 // * @brief This API is used to perform the complete self test
cdupaty 0:ef20a9039c0c 458 // * (both normal and advanced) for the BMM150 sensor
cdupaty 0:ef20a9039c0c 459 // */
cdupaty 0:ef20a9039c0c 460 // char BMM150::perform_self_test(uint8_t self_test_mode)
cdupaty 0:ef20a9039c0c 461 // {
cdupaty 0:ef20a9039c0c 462 // char rslt;
cdupaty 0:ef20a9039c0c 463 // char self_test_rslt = 0;
cdupaty 0:ef20a9039c0c 464
cdupaty 0:ef20a9039c0c 465 // switch (self_test_mode) {
cdupaty 0:ef20a9039c0c 466 // case BMM150_NORMAL_SELF_TEST:
cdupaty 0:ef20a9039c0c 467 // /* Set the sensor in sleep mode */
cdupaty 0:ef20a9039c0c 468 // settings.pwr_mode = BMM150_SLEEP_MODE;
cdupaty 0:ef20a9039c0c 469 // set_op_mode(BMM150_SLEEP_MODE);
cdupaty 0:ef20a9039c0c 470 // /* Perform the normal self test */
cdupaty 0:ef20a9039c0c 471 // rslt = perform_normal_self_test();
cdupaty 0:ef20a9039c0c 472 // break;
cdupaty 0:ef20a9039c0c 473
cdupaty 0:ef20a9039c0c 474 // case BMM150_ADVANCED_SELF_TEST:
cdupaty 0:ef20a9039c0c 475 // /* Perform the advanced self test */
cdupaty 0:ef20a9039c0c 476 // rslt = perform_adv_self_test();
cdupaty 0:ef20a9039c0c 477 // /* Check to ensure bus error does not occur */
cdupaty 0:ef20a9039c0c 478 // if (rslt >= BMM150_OK) {
cdupaty 0:ef20a9039c0c 479 // /* Store the status of self test result */
cdupaty 0:ef20a9039c0c 480 // self_test_rslt = rslt;
cdupaty 0:ef20a9039c0c 481 // /* Perform soft reset */
cdupaty 0:ef20a9039c0c 482 // soft_reset();
cdupaty 0:ef20a9039c0c 483 // }
cdupaty 0:ef20a9039c0c 484 // rslt = self_test_rslt;
cdupaty 0:ef20a9039c0c 485 // break;
cdupaty 0:ef20a9039c0c 486 // default:
cdupaty 0:ef20a9039c0c 487 // rslt = BMM150_E_INVALID_CONFIG;
cdupaty 0:ef20a9039c0c 488 // break;
cdupaty 0:ef20a9039c0c 489 // }
cdupaty 0:ef20a9039c0c 490
cdupaty 0:ef20a9039c0c 491 // return rslt;
cdupaty 0:ef20a9039c0c 492 // }
cdupaty 0:ef20a9039c0c 493
cdupaty 0:ef20a9039c0c 494 // /*
cdupaty 0:ef20a9039c0c 495 // * @brief This internal API is used to perform the normal self test
cdupaty 0:ef20a9039c0c 496 // * of the sensor and return the self test result as return value
cdupaty 0:ef20a9039c0c 497 // */
cdupaty 0:ef20a9039c0c 498 // char BMM150::perform_normal_self_test()
cdupaty 0:ef20a9039c0c 499 // {
cdupaty 0:ef20a9039c0c 500 // char rslt;
cdupaty 0:ef20a9039c0c 501 // uint8_t self_test_bit;
cdupaty 0:ef20a9039c0c 502
cdupaty 0:ef20a9039c0c 503 // /* Triggers the start of normal self test */
cdupaty 0:ef20a9039c0c 504 // enable_normal_self_test(&self_test_bit);
cdupaty 0:ef20a9039c0c 505 // /* Check for self test completion status */
cdupaty 0:ef20a9039c0c 506 // if (self_test_bit == 0) {
cdupaty 0:ef20a9039c0c 507 // /* Validates the self test results for all 3 axes */
cdupaty 0:ef20a9039c0c 508 // rslt = validate_normal_self_test();
cdupaty 0:ef20a9039c0c 509 // }
cdupaty 0:ef20a9039c0c 510
cdupaty 0:ef20a9039c0c 511 // return rslt;
cdupaty 0:ef20a9039c0c 512 // }
cdupaty 0:ef20a9039c0c 513
cdupaty 0:ef20a9039c0c 514 // /*!
cdupaty 0:ef20a9039c0c 515 // * @brief This internal API is used to enable the normal self test by setting
cdupaty 0:ef20a9039c0c 516 // * the Self Test bit (bit0) of the 0x4C register,
cdupaty 0:ef20a9039c0c 517 // * which triggers the start of self test
cdupaty 0:ef20a9039c0c 518 // */
cdupaty 0:ef20a9039c0c 519 // void BMM150::enable_normal_self_test(uint8_t *self_test_enable)
cdupaty 0:ef20a9039c0c 520 // {
cdupaty 0:ef20a9039c0c 521 // uint8_t reg_data;
cdupaty 0:ef20a9039c0c 522 // uint8_t self_test_val;
cdupaty 0:ef20a9039c0c 523
cdupaty 0:ef20a9039c0c 524 // /* Read the data from register 0x4C */
cdupaty 0:ef20a9039c0c 525 // reg_data = i2c->read(BMM150_OP_MODE_ADDR);
cdupaty 0:ef20a9039c0c 526 // /* Set the Self Test bit(bit0) of the 0x4C register */
cdupaty 0:ef20a9039c0c 527 // self_test_val = 1;
cdupaty 0:ef20a9039c0c 528 // reg_data = BMM150_SET_BITS_POS_0(reg_data, BMM150_SELF_TEST, self_test_val);
cdupaty 0:ef20a9039c0c 529 // /* Write the data to 0x4C register to trigger self test */
cdupaty 0:ef20a9039c0c 530 // i2c_write(BMM150_OP_MODE_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 531 // wait_ms(BMM150_NORMAL_SELF_TEST_wait_ms);
cdupaty 0:ef20a9039c0c 532 // /* Read the data from register 0x4C */
cdupaty 0:ef20a9039c0c 533 // reg_data = i2c->read(BMM150_OP_MODE_ADDR);
cdupaty 0:ef20a9039c0c 534 // /* Self Test bit(bit0) is stored in self_test_enable,
cdupaty 0:ef20a9039c0c 535 // It will be reset to zero after the self test is over */
cdupaty 0:ef20a9039c0c 536 // *self_test_enable = BMM150_GET_BITS_POS_0(reg_data, BMM150_SELF_TEST);
cdupaty 0:ef20a9039c0c 537 // }
cdupaty 0:ef20a9039c0c 538
cdupaty 0:ef20a9039c0c 539 // /*!
cdupaty 0:ef20a9039c0c 540 // * @brief This internal API is used to validate the results of normal self test
cdupaty 0:ef20a9039c0c 541 // * by using the self test status available in the bit0 of registers 0x42,0x44
cdupaty 0:ef20a9039c0c 542 // * and 0x46.
cdupaty 0:ef20a9039c0c 543 // */
cdupaty 0:ef20a9039c0c 544 // char BMM150::validate_normal_self_test()
cdupaty 0:ef20a9039c0c 545 // {
cdupaty 0:ef20a9039c0c 546 // char rslt;
cdupaty 0:ef20a9039c0c 547 // uint8_t status;
cdupaty 0:ef20a9039c0c 548 // uint8_t self_test_rslt[5];
cdupaty 0:ef20a9039c0c 549
cdupaty 0:ef20a9039c0c 550 // /* Read the data from register 0x42 to 0x46 */
cdupaty 0:ef20a9039c0c 551 // i2c->read(BMM150_DATA_X_LSB, self_test_rslt, BMM150_SELF_TEST_LEN);
cdupaty 0:ef20a9039c0c 552 // /* Parse and get the self test status bits */
cdupaty 0:ef20a9039c0c 553 // /* X-Self-Test (bit0) of 0x42 register is stored*/
cdupaty 0:ef20a9039c0c 554 // self_test_rslt[0] = BMM150_GET_BITS_POS_0(self_test_rslt[0], BMM150_SELF_TEST);
cdupaty 0:ef20a9039c0c 555 // /* Y-Self-Test (bit0) of 0x44 register is stored */
cdupaty 0:ef20a9039c0c 556 // self_test_rslt[2] = BMM150_GET_BITS_POS_0(self_test_rslt[2], BMM150_SELF_TEST);
cdupaty 0:ef20a9039c0c 557 // /* Z-Self-Test (bit0) of 0x46 register is stored */
cdupaty 0:ef20a9039c0c 558 // self_test_rslt[4] = BMM150_GET_BITS_POS_0(self_test_rslt[4], BMM150_SELF_TEST);
cdupaty 0:ef20a9039c0c 559 // /* Combine the self test status and store it in the first
cdupaty 0:ef20a9039c0c 560 // 3 bits of the status variable for processing*/
cdupaty 0:ef20a9039c0c 561 // status = (uint8_t)((self_test_rslt[4] << 2) | (self_test_rslt[2] << 1) | self_test_rslt[0]);
cdupaty 0:ef20a9039c0c 562 // /* Validate status and store Self test result in "rslt" */
cdupaty 0:ef20a9039c0c 563 // if (status == BMM150_SELF_TEST_STATUS_SUCCESS) {
cdupaty 0:ef20a9039c0c 564 // /* Self test is success when all status bits are set */
cdupaty 0:ef20a9039c0c 565 // rslt = BMM150_OK;
cdupaty 0:ef20a9039c0c 566 // } else {
cdupaty 0:ef20a9039c0c 567 // if (status == BMM150_SELF_TEST_STATUS_XYZ_FAIL) {
cdupaty 0:ef20a9039c0c 568 // /* Self test - all axis fail condition */
cdupaty 0:ef20a9039c0c 569 // rslt = BMM150_W_NORMAL_SELF_TEST_XYZ_FAIL;
cdupaty 0:ef20a9039c0c 570 // } else {
cdupaty 0:ef20a9039c0c 571 // /* Self test - some axis fail condition */
cdupaty 0:ef20a9039c0c 572 // rslt = (char)status;
cdupaty 0:ef20a9039c0c 573 // }
cdupaty 0:ef20a9039c0c 574 // }
cdupaty 0:ef20a9039c0c 575
cdupaty 0:ef20a9039c0c 576 // return rslt;
cdupaty 0:ef20a9039c0c 577 // }
cdupaty 0:ef20a9039c0c 578
cdupaty 0:ef20a9039c0c 579 // /*!
cdupaty 0:ef20a9039c0c 580 // * @brief This internal API is used to perform advanced self test for Z axis
cdupaty 0:ef20a9039c0c 581 // */
cdupaty 0:ef20a9039c0c 582 // char BMM150::perform_adv_self_test()
cdupaty 0:ef20a9039c0c 583 // {
cdupaty 0:ef20a9039c0c 584 // uint8_t self_test_current;
cdupaty 0:ef20a9039c0c 585 // int16_t positive_data_z;
cdupaty 0:ef20a9039c0c 586 // int16_t negative_data_z;
cdupaty 0:ef20a9039c0c 587 // char rslt;
cdupaty 0:ef20a9039c0c 588
cdupaty 0:ef20a9039c0c 589 // /* Set the desired power mode ,axes control and repetition settings */
cdupaty 0:ef20a9039c0c 590 // adv_self_test_settings();
cdupaty 0:ef20a9039c0c 591 // /* Measure the Z axes data with positive self-test current */
cdupaty 0:ef20a9039c0c 592 // self_test_current = BMM150_ENABLE_POSITIVE_CURRENT;
cdupaty 0:ef20a9039c0c 593 // adv_self_test_measurement(self_test_current, &positive_data_z);
cdupaty 0:ef20a9039c0c 594 // /* Measure the Z axes data with
cdupaty 0:ef20a9039c0c 595 // negative self-test current */
cdupaty 0:ef20a9039c0c 596 // self_test_current = BMM150_ENABLE_NEGATIVE_CURRENT;
cdupaty 0:ef20a9039c0c 597 // adv_self_test_measurement(self_test_current, &negative_data_z);
cdupaty 0:ef20a9039c0c 598 // /* Disable self-test current */
cdupaty 0:ef20a9039c0c 599 // self_test_current = BMM150_DISABLE_SELF_TEST_CURRENT;
cdupaty 0:ef20a9039c0c 600 // set_adv_self_test_current(self_test_current);
cdupaty 0:ef20a9039c0c 601 // /* Validate the advanced self test */
cdupaty 0:ef20a9039c0c 602 // rslt = validate_adv_self_test(positive_data_z, negative_data_z);
cdupaty 0:ef20a9039c0c 603
cdupaty 0:ef20a9039c0c 604 // return rslt;
cdupaty 0:ef20a9039c0c 605 // }
cdupaty 0:ef20a9039c0c 606
cdupaty 0:ef20a9039c0c 607 // /*!
cdupaty 0:ef20a9039c0c 608 // * @brief This internal API is used to set the desired power mode ,
cdupaty 0:ef20a9039c0c 609 // * axes control and repetition settings for advanced self test
cdupaty 0:ef20a9039c0c 610 // */
cdupaty 0:ef20a9039c0c 611 // void BMM150::adv_self_test_settings()
cdupaty 0:ef20a9039c0c 612 // {
cdupaty 0:ef20a9039c0c 613 // /* Set the power mode as sleep mode */
cdupaty 0:ef20a9039c0c 614 // settings.pwr_mode = BMM150_SLEEP_MODE;
cdupaty 0:ef20a9039c0c 615 // set_op_mode(BMM150_SLEEP_MODE);
cdupaty 0:ef20a9039c0c 616 // /* Disable XY-axis measurement */
cdupaty 0:ef20a9039c0c 617 // settings.xyz_axes_control = BMM150_DISABLE_XY_AXIS;
cdupaty 0:ef20a9039c0c 618 // set_control_measurement_xyz(settings);
cdupaty 0:ef20a9039c0c 619 // /* Repetition value is set as 0x04 */
cdupaty 0:ef20a9039c0c 620 // settings.z_rep = BMM150_SELF_TEST_REP_Z;
cdupaty 0:ef20a9039c0c 621 // set_z_rep(settings);
cdupaty 0:ef20a9039c0c 622 // }
cdupaty 0:ef20a9039c0c 623
cdupaty 0:ef20a9039c0c 624 // /*!
cdupaty 0:ef20a9039c0c 625 // * @brief This internal API is used to set the positive or negative value of
cdupaty 0:ef20a9039c0c 626 // * self-test current and obtain the corresponding magnetometer z axis data
cdupaty 0:ef20a9039c0c 627 // */
cdupaty 0:ef20a9039c0c 628 // void BMM150::adv_self_test_measurement(uint8_t self_test_current, int16_t *data_z)
cdupaty 0:ef20a9039c0c 629 // {
cdupaty 0:ef20a9039c0c 630 // /* Set the advanced self test current as positive or
cdupaty 0:ef20a9039c0c 631 // negative based on the value of parameter "self_test_current" */
cdupaty 0:ef20a9039c0c 632 // set_adv_self_test_current(self_test_current);
cdupaty 0:ef20a9039c0c 633 // /* Set the device in forced mode*/
cdupaty 0:ef20a9039c0c 634 // settings.pwr_mode = BMM150_FORCED_MODE;
cdupaty 0:ef20a9039c0c 635 // set_op_mode(BMM150_FORCED_MODE);
cdupaty 0:ef20a9039c0c 636 // /* wait_ms to ensure measurement is complete */
cdupaty 0:ef20a9039c0c 637 // wait_ms(4);
cdupaty 0:ef20a9039c0c 638 // /* Read Mag data and store the value of Z axis data */
cdupaty 0:ef20a9039c0c 639 // read_mag_data();
cdupaty 0:ef20a9039c0c 640 // /* Mag Z axis data is stored */
cdupaty 0:ef20a9039c0c 641 // *data_z = mag_data.z;
cdupaty 0:ef20a9039c0c 642 // }
cdupaty 0:ef20a9039c0c 643
cdupaty 0:ef20a9039c0c 644 // /*!
cdupaty 0:ef20a9039c0c 645 // * @brief This internal API is used to get the difference between the
cdupaty 0:ef20a9039c0c 646 // * Z axis mag data obtained by positive and negative self-test current
cdupaty 0:ef20a9039c0c 647 // * and validate whether the advanced self test is done successfully or not.
cdupaty 0:ef20a9039c0c 648 // */
cdupaty 0:ef20a9039c0c 649 // char BMM150::validate_adv_self_test(int16_t positive_data_z, int16_t negative_data_z)
cdupaty 0:ef20a9039c0c 650 // {
cdupaty 0:ef20a9039c0c 651 // int32_t adv_self_test_rslt;
cdupaty 0:ef20a9039c0c 652 // char rslt;
cdupaty 0:ef20a9039c0c 653
cdupaty 0:ef20a9039c0c 654 // /* Advanced self test difference between the Z axis mag data
cdupaty 0:ef20a9039c0c 655 // obtained by the positive and negative self-test current */
cdupaty 0:ef20a9039c0c 656 // adv_self_test_rslt = positive_data_z - negative_data_z;
cdupaty 0:ef20a9039c0c 657 // /* Advanced self test validation */
cdupaty 0:ef20a9039c0c 658 // /*Value of adv_self_test_rslt should be in between 180-240 micro-tesla*/
cdupaty 0:ef20a9039c0c 659 // if ((adv_self_test_rslt > 180) && (adv_self_test_rslt < 240)) {
cdupaty 0:ef20a9039c0c 660 // /* Advanced self test success */
cdupaty 0:ef20a9039c0c 661 // rslt = BMM150_OK;
cdupaty 0:ef20a9039c0c 662 // } else {
cdupaty 0:ef20a9039c0c 663 // /* Advanced self test fail */
cdupaty 0:ef20a9039c0c 664 // rslt = BMM150_W_ADV_SELF_TEST_FAIL;
cdupaty 0:ef20a9039c0c 665 // }
cdupaty 0:ef20a9039c0c 666
cdupaty 0:ef20a9039c0c 667 // return rslt;
cdupaty 0:ef20a9039c0c 668 // }
cdupaty 0:ef20a9039c0c 669
cdupaty 0:ef20a9039c0c 670 // /*
cdupaty 0:ef20a9039c0c 671 // * @brief This internal API is used to set the self test current value in
cdupaty 0:ef20a9039c0c 672 // * the Adv. ST bits (bit6 and bit7) of 0x4C register
cdupaty 0:ef20a9039c0c 673 // */
cdupaty 0:ef20a9039c0c 674 // void BMM150::set_adv_self_test_current(uint8_t self_test_current)
cdupaty 0:ef20a9039c0c 675 // {
cdupaty 0:ef20a9039c0c 676 // uint8_t reg_data;
cdupaty 0:ef20a9039c0c 677
cdupaty 0:ef20a9039c0c 678 // /* Read the 0x4C register */
cdupaty 0:ef20a9039c0c 679 // reg_data = i2c->read(BMM150_OP_MODE_ADDR);
cdupaty 0:ef20a9039c0c 680 // /* Set the self test current value in the Adv. ST bits
cdupaty 0:ef20a9039c0c 681 // (bit6 and bit7) of 0x4c register */
cdupaty 0:ef20a9039c0c 682 // reg_data = BMM150_SET_BITS(reg_data, BMM150_ADV_SELF_TEST, self_test_current);
cdupaty 0:ef20a9039c0c 683 // i2c_write(BMM150_OP_MODE_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 684
cdupaty 0:ef20a9039c0c 685 // }
cdupaty 0:ef20a9039c0c 686
cdupaty 0:ef20a9039c0c 687 // /*
cdupaty 0:ef20a9039c0c 688 // * @brief This internal API is used to enable or disable the magnetic
cdupaty 0:ef20a9039c0c 689 // * measurement of x,y,z axes based on the value of xyz_axes_control.
cdupaty 0:ef20a9039c0c 690 // */
cdupaty 0:ef20a9039c0c 691 // void BMM150::set_control_measurement_xyz(struct bmm150_settings settings)
cdupaty 0:ef20a9039c0c 692 // {
cdupaty 0:ef20a9039c0c 693 // uint8_t reg_data;
cdupaty 0:ef20a9039c0c 694
cdupaty 0:ef20a9039c0c 695 // reg_data = i2c->read(BMM150_AXES_ENABLE_ADDR);
cdupaty 0:ef20a9039c0c 696 // /* Set the axes to be enabled/disabled*/
cdupaty 0:ef20a9039c0c 697 // reg_data = BMM150_SET_BITS(reg_data, BMM150_CONTROL_MEASURE, settings.xyz_axes_control);
cdupaty 0:ef20a9039c0c 698 // i2c_write(BMM150_AXES_ENABLE_ADDR, reg_data);
cdupaty 0:ef20a9039c0c 699 // }