+ uint8_t ret = _ao_bmx160_reg_read(BMX160_DATA_0);
+ return ret;
+}
+
+static uint16_t
+_ao_bmm150_reg_read2(uint8_t lo_addr, uint8_t hi_addr)
+{
+ uint8_t lo = _ao_bmm150_reg_read(lo_addr);
+ uint8_t hi = _ao_bmm150_reg_read(hi_addr);
+
+ return ((uint16_t) hi << 8) | lo;
+}
+
+/*
+ * The compensate functions are taken from the BMM150 sample
+ * driver which has the following copyright:
+ *
+ * Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.
+ *
+ * BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @file bmm150.c
+ * @date 10/01/2020
+ * @version 1.0.3
+ *
+ */
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer X axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_x(int16_t mag_data_x, uint16_t data_rhall)
+{
+ int16_t retval;
+ uint16_t process_comp_x0 = 0;
+ int32_t process_comp_x1;
+ uint16_t process_comp_x2;
+ int32_t process_comp_x3;
+ int32_t process_comp_x4;
+ int32_t process_comp_x5;
+ int32_t process_comp_x6;
+ int32_t process_comp_x7;
+ int32_t process_comp_x8;
+ int32_t process_comp_x9;
+ int32_t process_comp_x10;
+
+ /* Overflow condition check */
+ if (mag_data_x != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL)
+ {
+ if (data_rhall != 0)
+ {
+ /* Availability of valid data*/
+ process_comp_x0 = data_rhall;
+ //printf("using data_rhall %d\n", data_rhall);
+ }
+ else if (ao_bmm150_trim.dig_xyz1 != 0)
+ {
+ process_comp_x0 = ao_bmm150_trim.dig_xyz1;
+ //printf("using trim value %d\n", process_comp_x0);
+ }
+ else
+ {
+ process_comp_x0 = 0;
+ //printf("no valid rhall\n");
+ }
+ if (process_comp_x0 != 0)
+ {
+ /* Processing compensation equations*/
+ process_comp_x1 = ((int32_t)ao_bmm150_trim.dig_xyz1) * 16384;
+ //printf("comp_x1 %d\n", process_comp_x1);
+ process_comp_x2 = ((uint16_t)(process_comp_x1 / process_comp_x0)) - ((uint16_t)0x4000);
+ //printf("comp_x2 %d\n", process_comp_x2);
+ retval = ((int16_t)process_comp_x2);
+ process_comp_x3 = (((int32_t)retval) * ((int32_t)retval));
+ //printf("comp_x3 %d\n", process_comp_x3);
+ process_comp_x4 = (((int32_t)ao_bmm150_trim.dig_xy2) * (process_comp_x3 / 128));
+ //printf("comp_x4 %d\n", process_comp_x4);
+ process_comp_x5 = (int32_t)(((int16_t)ao_bmm150_trim.dig_xy1) * 128);
+ //printf("comp_x5 %d\n", process_comp_x5);
+ process_comp_x6 = ((int32_t)retval) * process_comp_x5;
+ //printf("comp_x6 %d\n", process_comp_x6);
+ process_comp_x7 = (((process_comp_x4 + process_comp_x6) / 512) + ((int32_t)0x100000));
+ //printf("comp_x7 %d\n", process_comp_x7);
+ process_comp_x8 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_x2) + ((int16_t)0xA0)));
+ //printf("comp_x8 %d\n", process_comp_x8);
+ process_comp_x9 = ((process_comp_x7 * process_comp_x8) / 4096);
+ //printf("comp_x9 %d\n", process_comp_x9);
+ process_comp_x10 = ((int32_t)mag_data_x) * process_comp_x9;
+ //printf("comp_x10 %d\n", process_comp_x10);
+ retval = ((int16_t)(process_comp_x10 / 8192));
+ //printf("ret 1 %d\n", retval);
+ retval = (retval + (((int16_t)ao_bmm150_trim.dig_x1) * 8)) / 16;
+ //printf("final %d\n", retval);
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition */
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return retval;
+}
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer Y axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_y(int16_t mag_data_y, uint16_t data_rhall)
+{
+ int16_t retval;
+ uint16_t process_comp_y0 = 0;
+ int32_t process_comp_y1;
+ uint16_t process_comp_y2;
+ int32_t process_comp_y3;
+ int32_t process_comp_y4;
+ int32_t process_comp_y5;
+ int32_t process_comp_y6;
+ int32_t process_comp_y7;
+ int32_t process_comp_y8;
+ int32_t process_comp_y9;
+
+ /* Overflow condition check */
+ if (mag_data_y != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL)
+ {
+ if (data_rhall != 0)
+ {
+ /* Availability of valid data*/
+ process_comp_y0 = data_rhall;
+ }
+ else if (ao_bmm150_trim.dig_xyz1 != 0)
+ {
+ process_comp_y0 = ao_bmm150_trim.dig_xyz1;
+ }
+ else
+ {
+ process_comp_y0 = 0;
+ }
+ if (process_comp_y0 != 0)
+ {
+ /*Processing compensation equations*/
+ process_comp_y1 = (((int32_t)ao_bmm150_trim.dig_xyz1) * 16384) / process_comp_y0;
+ process_comp_y2 = ((uint16_t)process_comp_y1) - ((uint16_t)0x4000);
+ retval = ((int16_t)process_comp_y2);
+ process_comp_y3 = ((int32_t) retval) * ((int32_t)retval);
+ process_comp_y4 = ((int32_t)ao_bmm150_trim.dig_xy2) * (process_comp_y3 / 128);
+ process_comp_y5 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_xy1) * 128));
+ process_comp_y6 = ((process_comp_y4 + (((int32_t)retval) * process_comp_y5)) / 512);
+ process_comp_y7 = ((int32_t)(((int16_t)ao_bmm150_trim.dig_y2) + ((int16_t)0xA0)));
+ process_comp_y8 = (((process_comp_y6 + ((int32_t)0x100000)) * process_comp_y7) / 4096);
+ process_comp_y9 = (((int32_t)mag_data_y) * process_comp_y8);
+ retval = (int16_t)(process_comp_y9 / 8192);
+ retval = (retval + (((int16_t)ao_bmm150_trim.dig_y1) * 8)) / 16;
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition*/
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return retval;
+}
+
+/*!
+ * @brief This internal API is used to obtain the compensated
+ * magnetometer Z axis data(micro-tesla) in int16_t.
+ */
+static int16_t compensate_z(int16_t mag_data_z, uint16_t data_rhall)
+{
+ int32_t retval;
+ int16_t process_comp_z0;
+ int32_t process_comp_z1;
+ int32_t process_comp_z2;
+ int32_t process_comp_z3;
+ int16_t process_comp_z4;
+
+ if (mag_data_z != BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL)
+ {
+ if ((ao_bmm150_trim.dig_z2 != 0) && (ao_bmm150_trim.dig_z1 != 0) && (data_rhall != 0) &&
+ (ao_bmm150_trim.dig_xyz1 != 0))
+ {
+ /*Processing compensation equations*/
+ process_comp_z0 = ((int16_t)data_rhall) - ((int16_t) ao_bmm150_trim.dig_xyz1);
+ process_comp_z1 = (((int32_t)ao_bmm150_trim.dig_z3) * ((int32_t)(process_comp_z0))) / 4;
+ process_comp_z2 = (((int32_t)(mag_data_z - ao_bmm150_trim.dig_z4)) * 32768);
+ process_comp_z3 = ((int32_t)ao_bmm150_trim.dig_z1) * (((int16_t)data_rhall) * 2);
+ process_comp_z4 = (int16_t)((process_comp_z3 + (32768)) / 65536);
+ retval = ((process_comp_z2 - process_comp_z1) / (ao_bmm150_trim.dig_z2 + process_comp_z4));
+
+ /* saturate result to +/- 2 micro-tesla */
+ if (retval > BMM150_POSITIVE_SATURATION_Z)
+ {
+ retval = BMM150_POSITIVE_SATURATION_Z;
+ }
+ else if (retval < BMM150_NEGATIVE_SATURATION_Z)
+ {
+ retval = BMM150_NEGATIVE_SATURATION_Z;
+ }
+
+ /* Conversion of LSB to micro-tesla*/
+ retval = retval / 16;
+ }
+ else
+ {
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+ }
+ else
+ {
+ /* Overflow condition*/
+ retval = BMM150_OVERFLOW_OUTPUT;
+ }
+
+ return (int16_t)retval;